我的知识库 / Kubernetes / Informer
Informer是client-go中实现的一个工具包,目前已经被kubernetes中各个组件所使用,例如controller-manager。Informer本质是一个api资源的缓存。
主要功能:
将etcd数据同步至本地缓存,客户端通过本地缓存读取和监听资源
注册资源Add,Update,Delete的触发事件
目的:
本地缓存,避免组件直接与api-server交互,减缓对api-server及etcd的访问压力。
Reflector
Delta FIFO Queue
Indexer(local strorage)
下面结合流程示意图简单介绍这些组件的角色。
这张示意图展示了client-go类库中各个组件的工作机制,以及它们与咱们将要编写的自定义控制器的交互点(黄颜色标注的块是需要自行开发的部分)。
Reflector:
负责监听(Watch)特定Kubernetes资源对象,监听的资源对象可以是内置的资源例如Pod,Ingress等,也可以是定制的CR对象。
Reflettor与ApiServer建立连接,第一次使用List&Watch
机制从ApiServer中List特定资源的所有实例,这些实例附带的ResourceVersion字段可以用来区分实例是否更新。后续在使用List&Watch
机制从ApiServer中Watch特定资源的新增,更新,删除等变化(增量Delta)。
将监听到的资源的新增,更新,删除顺序写入到DeltaFIFO队列中。
DeltaFIFO:
一个增量的先进先出的队列,存储监听到的资源,以及资源事件类型,例如Added,Updated,Deleted,Replaced,Sync。
Informer:
Indexer:
一个自带索引功能的本地存储,用于存储资源对象。Informer从DeltaFIFO中Pop出资源,存储到Indexer。Indexer中资源与k8s etcd数据保持一致。本地读取时直接查询本地存储,从而减少k8s apiserver和etcd的压力。
自定义控制器
clientset, err := kubernetes.NewForConfig(config)
stopCh := make(chan struct{})
defer close(stopch)
sharedInformers := informers.NewSharedInformerFactory(clientset, time.Minute)
informer := sharedInformer.Core().V1().Pods().Informer()
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{} {
// ...
},
UpdateFunc: func(obj interface{} {
// ...
},
DeleteFunc : func(obj interface{} {
// ...
})
informer.Run(stopCh)
})
上面这个示例,当触发了 Add,Update 或者 Delete 事件,就通知 Client-go,告知 Kubernetes 资源事件发生变更并且需要进行相应的处理。
每个内置的k8s资源对实现了对应的Informer机制,均包含Lister和Informer方法,例如:
type PodInformer interface {
Lister() cache.SharedIndexInformer
Informer() v1.PodLister
}
每实例化一个Informer对象,都需要维护一个对应的Reflector。当同一对象Informer实例被实例化多次时,运行过多的ListAndWatch,这其中包括的