透过真实场景分析K8S的EndpointController的源码

  • 时间:
  • 浏览:1
  • 来源:大发财神争霸8—大发彩神

func (e *EndpointController) worker() {

}

// 1、将会tolerateUnreadyEndpoints为true,允许未就绪的pod也列入Addresses列表,将会tolerateUnreadyEndpoints为false但pod清况 为ready则将pod列入Addresses列表;

//但会 我我此处endpoint这麼对应的service,猜想会把endpoint的name当成key传入queue,但会 在事先 的逻辑中判断获取service name错误,于是删除endpoint

go func() {

func (e *EndpointController) processNextWorkItem() bool {

}

//比较两者的ResourceVersion,对比更新后的pod与原pod,将会两者的资源版本相等,则直接返回,不进行入队操作

func podChanged(oldPod, newPod *v1.Pod) bool {

//podChanged函数,其检测逻辑为,将会新旧有一有一一好几个 pod的DeletionTimestamp字段不等则返回true,但会 继续判断两者的就绪清况 ,将会不等则返回true,最后再判断新旧pod的ip、nodename、namespace、UID与非 相等,将会相等则返回false,但会 返回true。将返回结果赋值给podChangedFlag

//add:以加进去去的service的namespace/name形式为key,并将该key加入 queue

}

1.5 Endpoint检测

事先 说的是当Endpoint和Service绑定的事先 Service和Pod改变时的一系列操作,现在亲戚亲戚大伙回到现象,将会Endpoint单独指在,K8S是怎样检测但会 删除的?

亲戚亲戚大伙重新看看Run函数中的

// 停留pod、service、endpoint列表同步

func (e EndpointController) getPodServiceMemberships(pod v1.Pod) (sets.String, error) {

func (e *EndpointController) syncService(key string) error {

//将service集合以namespace/name为key逐个加入到queue中

}

1.3.2 e.updatePod

func (e *EndpointController) updatePod(old, cur interface{}) {

}

//获取pod与service的映射关系

基于k8s release-1.13

1.2 源码目录型态

将会亲戚亲戚大伙重点看Endpoint帕累托图,但会 亲戚亲戚大伙只看Endpoint相关的源码

Endpoint

1.3 Endpoint的初始化

文件位置: endpoints_controller.go

// 获取该pod的信息,输出EndpointAddress型态体变量

}

// 根据key获取service的namespace和name

}

//判断两者的label与非 将会不一致,将会hostname或subdomain已改变

// NewEndpointController returns a new *EndpointController.

//亲戚亲戚大伙还不需要 看到在Endpoint初始化的事先 ,将会注册了有一有一一好几个 informer,分别是podInformer,serviceInformer,endpointsInformer

func NewEndpointController(podInformer coreinformers.PodInformer, serviceInformer coreinformers.ServiceInformer,

}

1.4 Endpoint-Controller具体逻辑

// Run will not return until stopCh is closed. workers determines how many

// endpoints will be handled in parallel.

func (e *EndpointController) Run(workers int, stopCh <-chan struct{}) {

场景重现

最近遇到有一有一一好几个 现象,在K8S的几台机器上中创建了Glusterfs的集群,通过官方的教程一步步的来利用Glusterfs创建Volume以及PV,不过但是 我创建了每个Volume的Endpoint,并这麼相对应的创建Service实例(官方说创建Service会使Endpoint持久化,当时并这麼理会),但会 在一次集群重启的事先 发现Endpoint实例并这麼启动起来,很疑惑,像许多的K8S对象,类事POD,Deployment,Service都启动起来了,但会 Endpoint并这麼,带着类事 现象看到下官方的Issue,并这麼那先 有效的解答,亲戚亲戚大伙还不需要 参考一下Issue: Endpoints are not persistented

创建Service的事先 使用Selector,另有一有一一好几个 还不需要 自动创建Endpoint

在创建Endpoint还需要创建Service,另有一有一一好几个 才还不需要 持久化Endpoint

endpointController的主要逻辑在syncService函数

//判断错误,则获取对应的service和pod映射关系

K8S在运行Run函数的事先 启动了有一有一一好几个 协程去检测当前所有的Endpoint

1.3.1 e.addPod

func (e *EndpointController) addPod(obj interface{}) {

//实例化有一有一一好几个 pod对象

//update:以更新后的service的namespace/name形式为key,并将该key加入 queue

//delete:以删除的service的namespace/name形式为key,并将该key加入 queue

//判断pod相关信息与非 指在改变

//查找逻辑为逐个对比service的selector与该pod的label,将会service的selector为该pod label的子集,则表示该pod属于service

}

}

亲戚亲戚大伙看看pod注册的Handler引用了那先 函数

// 将会service将会被删除,则也要删除对用的endpoint资源

// checkLeftoverEndpoints lists all currently existing endpoints and adds their

// service to the queue. This will detect endpoints that exist with no

// corresponding service; these endpoints need to be deleted. We only need to

// do this once on startup, because in steady-state these are detected (but

// some stragglers could have been left behind if the endpoint controller

// reboots).

func (e *EndpointController) checkLeftoverEndpoints() {

//拉取当前所有的endpoint对象

// 执行worker函数,for死循环除理queue中的key

//轮询所有endpoint