kubernetes并没有使用传统的消息队列来传递消息,而是使用了informer机制来实现各模块间的消息传递,如下图所示,每个gvr都实现了一套自己的informer。
Informer 内部主要组件 :
- Controller 并不是 Kubernetes Controller,这两个 Controller 并没有任何联系;
- Reflector 的主要作用是通过 Kubernetes Watch API 监听某种 resource 下的所有事件;
- DeltaFIFO 记录各种事件的队列,存储Watch API返回的各种事件
- LocalStore(indexer)只会被Lister的Lister/Get方法访问。
- Lister 主要是被调用 List/Get 方法;
- Processor 中记录了所有的回调函数实例(即 ResourceEventHandler 实例),并负责触发这些函数。
informer主要功能有两个:
- Reflector 通过ListWatcher 同步apiserver 数据(只启动时搞一次),并watch apiserver ,将event 加入到队列中
- 从 Queue中获取event,更新存储,并触发Processor 业务层注册的 ResourceEventHandler
二级缓存:
- 这两级缓存分别是 DeltaFIFO 和 LocalStore(indexer)。这两级缓存的用途各不相同。DeltaFIFO 用来存储 Watch API 返回的各种事件 ,LocalStore 只会被 Lister 的 List/Get 方法访问 。(LocalStore中的数据informer启动时会同步一次)
- Informer 和 Kubernetes 之间没有 resync 机制,但 Informer 内部的这两级缓存之间存在 resync 机制。(两级缓存之间为什么需要有resync,能带来什么收益?sts后面还是把二级缓存resync去掉了)http://likakuli.com/post/2019/03/26/statefulset/
sharedInformer:
- 可以使同一gvr的informer使用同一informer实例,节约资源
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer { f.lock.Lock() defer f.lock.Unlock() informerType := reflect.TypeOf(obj) informer, exists := f.informers[informerType] if exists { return informer } resyncPeriod, exists := f.customResync[informerType] if !exists { resyncPeriod = f.defaultResync } informer = newFunc(f.client, resyncPeriod) f.informers[informerType] = informer return informer }
参考: