深入剖析Kubernetes-编写自定义控制器

如下图所示是一个控制器的工作原理图:
深入剖析Kubernetes-编写自定义控制器
控制器的工作原理大致如下:

获取关心的对象

这个控制器要做的第一件事,是从Kubemetes的APIServer里获取它所关心的对象,也就是我定义的Network 对象。
这个操作,依靠的是一个叫作Informer(可以翻译为∶通知器)的代码库完成的。Informer与API对象是——对应的。

Informer通过与APIServer建立连接,使用ListAndWatch机制增量的方式获取API Server中所有关心的对象,并把增量的对象放入Delta FIFO Queue中。

而另一方面,Informe 会不断地从这个Delta FIFO Queue里读取(Pop)增量。每拿到一个增量,Informer就会判断这个增量里的事件类型,然后创建或者更新本地对象的缓存。这个缓存,在 Kubernetes 里一般被叫作 Store。

而iInformer的第二个职责,则是根据这些事件的类型,触发事先注册好的ResourceEventHandler。这些 Handler,需要在创建控制器的时候注册给它对应的Informer。通常为Informer注册了三个 Handler(AddFunc、UpdateFunc和DeleteFunc),分别对应API对象的"添加""更新"和"删除"事件。而具体的处理操作,都是将该事件对应的 API对象加入到工作队列中。需要注意的是,实际入队的并不是API对象本身,而是它们的 Key,即∶该API对象的/. 而我们后面即将编写的控制循环,则会不断地从这个工作队列里拿到这些Key,然后开始执行真正的控制逻辑。

所谓Informer,其实就是一个带有本地缓存和索引机制的、可以注册 EventHandler的client。它是自定义控制器跟 APIServer进行数据同步的重要组件。
更具体地说,Informer通过一种叫作 ListAndWatch的方法,把 APIServer中的API对象缓存在了本地,并负责更新和维护这个缓存。

根据对象的目标状态和当前状态执行相应的操作

每一个Controller在启动的时候会启动一个或多个协程无线循环的处理我们的业务逻辑,即根据对象的目标状态和当前状态执行相应的操作。对象的目标状态是从Informer的本地缓存即Store中获取,对象当前状态则是通过APIServer的实时API接口获取。Informer根据目标状态和当前状态的差异,就可以完成一次调协过程,最终达到目标状态与当前状态的一致,这也就是声明式API的本质