如果为List请求,则调用 GetEndpoints 获取拓扑修改后的 endpoints 列表,并返回
func (sc *storageCache) GetEndpoints() []*v1.Endpoints { sc.mu.RLock() defer sc.mu.RUnlock() epList := make([]*v1.Endpoints, 0, len(sc.endpointsMap)) for _, v := range sc.endpointsMap { epList = append(epList, v.modified) } return epList }如果为 Watch 请求,则不断从 storageCache.endpointsWatchCh 管道中接受 watch event,并返回
interceptServiceRequest 逻辑与 interceptEndpointsRequest 一致,这里不再赘述。
总结SuperEdge service group 利用 application-grid-wrapper 实现拓扑感知,完成了同一个 nodeunit 内服务的闭环访问
service group 实现的拓扑感知和 Kubernetes 社区原生实现对比,有如下区别:
service group 拓扑 key 可以自定义,也即为 gridUniqKey,使用起来更加灵活;而社区实现目前只有三种选择:"kubernetes.io/hostname","topology.kubernetes.io/zone"以及"topology.kubernetes.io/region"
service group 只能填写一个拓扑 key,也即只能访问本拓扑域内有效的 endpoint,无法访问其它拓扑域的 endpoint;而社区可以通过 topologyKey 列表以及"*"实现其它备选拓扑域 endpoint 的访问
ServiceGrid Controller 负责根据 ServiceGrid 产生对应的 service(包含由serviceGrid.Spec.GridUniqKey构成的 topologyKeys annotations),逻辑和 DeploymentGrid Controller 整体一致,如下:
创建并维护 service group 需要的若干 CRDs (包括:ServiceGrid)
监听 ServiceGrid event,并填充 ServiceGrid 到工作队列中;循环从队列中取出ServiceGrid进行解析,创建并且维护对应的 service
监听 service event,并将相关的 ServiceGrid 塞到工作队列中进行上述处理,协助上述逻辑达到整体 reconcile 逻辑
为了实现Kubernetes零侵入,需要在 kube-proxy 与 apiserver 通信之间添加一层 wrapper,调用链路如下:kube-proxy -> application-grid-wrapper -> lite-apiserver -> kube-apiserver
application-grid-wrapper 是一个 http server,接受来自 kube-proxy 的请求,同时维护一个资源缓存,处理函数由外到内依次如下:
debug:接受 debug 请求,返回 wrapper pprof 运行信息
logger:打印请求日志
node:接受kube-proxy node GET (/api/v1/nodes/{node}) 请求,并返回 node 信息
event:接受 kube-proxy events POST (/events) 请求,并将请求转发给 lite-apiserver
service:接受 kube-proxy service List&Watch (/api/v1/services) 请求,并根据 storageCache 内容返回 (GetServices)。
endpoint:接受 kube-proxy endpoint List&Watch(/api/v1/endpoints) 请求,并根据storageCache 内容返回 (GetEndpoints)。
wrapper 为了实现拓扑感知,维护了一个资源cache,包括:node,service,endpoint,同时注册了相关 event 处理函数。核心拓扑算法逻辑为:调用 filterConcernedAddresses 过滤 endpoint.Subsets Addresses 以及 NotReadyAddresses,只保留同一个 service topologyKeys 中的 endpoint。另外,如果 wrapper 所在边缘节点没有 service topologyKeys 标签,则也无法访问该 service。
wrapper 接受来自 kube-proxy 对 endpoints 以及 service 的 List&Watch 请求,以 endpoints 为例:如果为List请求,则调用 GetEndpoints 获取拓扑修改后的 endpoints 列表,并返回;如果为 Watch 请求,则不断从 storageCache.endpointsWatchCh 管道中接受 watch event,并返回。service逻辑与 endpoints 一致。
展望目前 SuperEdge service group 实现的拓扑算法功能更加灵活方便,如何处理与 Kubernetes 社区 service topology awareness 之间的关系值得探索,建议将 SuperEdge 拓扑算法推到社区
Refsduyanghao kubernetes-reading-notes