源码分析系列文章已经开源到github,地址如下:
- github:
https://github.com/farmer-hutao/k8s-source-code-analysis - gitbook:
https://farmer-hutao.github.io/k8s-source-code-analysis
—————————————————
1. 概述
本节标题写的是 Informer,不过我们的内容不局限于狭义的 Informer 部分,只是 Informer 最有代表性,其他的 Reflector 等也不好独立开来讲。
Informer 在很多组件的源码中可以看到,尤其是 kube-controller-manager (写这篇文章时我已经基本写完 kube-scheduler 的源码分析,着手写 kube-controller-manager 了,鉴于 controlelr 和 client-go 关联比较大,跳过来先讲讲典型的控制器工作流程中涉及到的 client-go 部分).
Informer 是 client-go 中一个比较核心的工具,通过 Informer(实际我们用到的都不是单纯的 informer,而是组合了各种工具的 sharedInformerFactory) 我们可以轻松 List/Get 某个资源对象,可以监听资源对象的各种事件(比如创建和删除)然后触发回调函数,让我们能够在各种事件发生的时候能够作出相应的逻辑处理。举个例字,当 pod 数量变化的时候 deployment 是不是需要判断自己名下的 pod 数量是否还和预期的一样?如果少了是不是要考虑创建?
2. 架构概览
自定义控制器的工作流程基本如下图所示,我们今天要分析图中上半部分的逻辑。
我们开发自定义控制器的时候用到的“机制”主要定义在 client-go 的 tool/cache下:
我们根据图中的9个步骤来跟源码
3. reflector – List & Watch API Server
Reflector 会监视特定的资源,将变化写入给定的存储中,也就是 Delta FIFO queue.
3.1. Reflector 对象
Reflector 的中文含义是反射器,我们先看一下类型定义:
tools/cache/reflector.go:47
type Reflector struct { name string metrics *reflectorMetrics expectedType reflect.Type store Store listerWatcher ListerWatcher period time.Duration resyncPeriod time.Duration ShouldResync func() bool clock clock.Clock lastSyncResourceVersion string lastSyncResourceVersionMutex sync.RWMutex }
reflector.go中主要就 Reflector 这个 struct 和相关的一些函数:
3.2. ListAndWatch
ListAndWatch 首先 list 所有 items,获取当前的资源版本信息,然后使用这个版本信息来 watch(也就是从这个版本开始的所有资源变化会被关注)。我们看一下这里的 ListAndWatch 方法主要逻辑:
tools/cache/reflector.go:168
func (r *Reflector) ListAndWatch(stopCh