Kubernetes Informer 详解
目录
Informer 是 Client-go 中的一个核心工具包。Informer 内部实现极其复杂,但也是一个设计精良、安全可靠的组件。
Informer 简介
基础功能
Informer 是 Client-go 中的一个核心工具包。在 Kubernetes 源码中,如果 Kubernetes 的某个组件,需要 List/Get Kubernetes 中的 Object,在绝大多 数情况下,会直接使用 Informer 实例中的 Lister()方法(该方法包含 了 Get 和 List 方法),而很少直接请求 Kubernetes API。Informer 最基本 的功能就是 List/Get Kubernetes 中的 Object。 如下图所示,仅需要十行左右的代码就能实现对 Pod 的 List 和 Get。
高级功能
Client-go 的首要目标是满足 Kubernetes 的自身需求。Informer 作为其中的核心工具包,面对 Kubernetes 极为复杂业务逻辑,如果仅实现 List/Get 功能,根本无法满足 Kubernetes 自身需求。因此,Informer 被设计为一个灵活而复杂的工具包,除 List/Get Object 外,Informer 还可以监听事件并触发回调函数等,以实现更加复杂的业务逻辑。
Informer 设计思路
关键点
为了让 Client-go 更快地返回 List/Get 请求的结果、减少对 Kubenetes API 的直接调用,Informer 被设计实现为一个依赖 Kubernetes List/Watch API 、可监听事件并触发回调函数的二级缓存工具包。
更快地返回 List/Get 请求
减少对 Kubenetes API 的直接调用: 使用 Informer 实例的 Lister() 方法, List/Get Kubernetes 中的 Object 时,Informer 不会去请求 Kubernetes API,而是直接查找缓存在本地内存中的数据(这份数据由 Informer 自己维护)。通过这种方式,Informer 既可以更快地返回结果,又能减少对 Kubernetes API 的直接调用。
依赖 Kubernetes List/Watch API
Informer 只调用 Kubernetes List 和 Watch 两种 API:
- 初始化时先调用 List API 获得 resource 的全部 Object,缓存在内存
- 然后调用 Watch API 维护这份缓存
- 之后不再调用 Kubernetes API
用 List/Watch 维护缓存、保持一致性是典型做法。特殊的是,Informer 只在初始化时调用一次 List API,之后完全依赖 Watch API,没有 resync 机制。
Google Kubernetes 开发人员解释:现有的 List/Watch 机制完全能保证不漏掉任何事件,因此无需额外的 relist/resync。这说明 Kubernetes 完全信任 etcd。
可监听事件并触发回调函数
Informer 通过 Watch API 监听某 resource 下的所有事件,可添加自定义回调函数。回调函数需实现三个方法:
OnAdd(obj interface{})- 创建事件OnUpdate(oldObj, newObj interface{})- 更新事件OnDelete(obj interface{})- 删除事件
Controller 的设计实现中会经常用到这个功能。
二级缓存
二级缓存(DeltaFIFO 和 LocalStore):
- DeltaFIFO:存储 Watch API 返回的各种事件
- LocalStore:仅被 Lister 的 List/Get 方法访问
虽然 Informer 和 Kubernetes 之间没有 resync 机制,但 Informer 内部这两级缓存之间存在 resync 机制。
Informer 详细解析
内部主要组件
Informer 包含六个主要组件:
- Controller:Informer 内部的 Controller(非 Kubernetes Controller)
- Reflector:通过 Watch API 监听 resource 下的所有事件
- DeltaFIFO:存储 Watch 事件的缓存队列
- LocalStore:提供本地内存缓存(Lister 调用)
- Lister:提供 List/Get 方法访问本地缓存
- Processor:记录回调函数实例,负责触发这些函数
工作流程详解
以 Pod 为例:
- 初始化:Reflector 调用 List API 获得所有 Pod,放入 Store
- 查询:调用 Lister 的 List/Get 方法时,直接从 Store 查询
- 监听:Informer 初始化完成后,Reflector 开始 Watch Pod 事件
- 事件捕获:Pod 被删除时,Reflector 监听到删除事件,发送到 DeltaFIFO
- 缓存更新:DeltaFIFO 存储事件,同时操作 Store 删除 pod_1
- 事件处理:DeltaFIFO Pop 事件到 Controller
- 触发回调:Controller 触发 Processor 的回调函数
- 缓存同步:LocalStore 周期性把所有 Pod 信息重新放到 DeltaFIFO(resync 机制)