informer是client-go中封装list-watch机制的核心组件,通过本地缓存、事件分发和资源版本管理实现高效资源监听,为operator和控制器提供变化感知能力。

直接学 client-go 的 Informer 机制,比读 Kubernetes 源码更高效、更贴近实战。 它是理解“Kubernetes 如何感知变化”最短路径,也是所有 Operator、控制器、备份工具的底层心跳。
为什么从 Informer 入手而不是 API Server 或 etcd
Informer 封装了 List-Watch 的完整生命周期:先全量拉取(List),再长连接监听(Watch),本地缓存资源状态,并触发事件回调。你不需要碰 etcd 底层存储,也不用处理 HTTP 流式响应的边界问题——client-go 已经帮你兜底。
常见错误现象包括:
-
Informer启动后没收到任何AddEvent,其实是没调用informer.Run(stopCh) - 本地缓存查不到刚创建的 Pod,因为
informer.HasSynced()还没返回true,就提前查了 cache - 多个 goroutine 并发读写 informer 的
Indexer,导致 panic,正确做法是只读不写,或加锁
如何快速验证一个 Informer 是否正常工作
用最小可运行代码测试,重点看三件事:是否连上、是否同步完成、是否收到事件。
关键步骤:
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
- 用
clientcmd.BuildConfigFromFlags("", kubeconfigPath)或rest.InClusterConfig()获取 config - 构造
cache.NewSharedIndexInformer,传入cache.ListWatch{ListFunc: ..., WatchFunc: ...},或直接用cache.NewSharedInformer简化版 - 注册
AddFunc/UpdateFunc/DeleteFunc回调,里面至少打一行日志 - 启动前确保
cache.WaitForCacheSync(stopCh, informer.HasSynced)返回true - 用
kubectl create pod手动触发事件,观察日志输出
Informer 和 controller-runtime 的 Reconciler 是什么关系
controller-runtime 的 Reconciler 是对 Informer 之上的一层封装:它把事件驱动转为“对象变更 → 触发一次 Reconcile → 查当前状态 → 对比期望状态 → 补齐差异”的声明式循环。
性能与兼容性影响:
- 原生 Informer 更轻量,适合只监听不修改的场景(如备份工具轮询资源)
-
controller-runtime自动管理 Informer 生命周期、重试队列、限速器,但引入额外调度开销 - Kubernetes 1.22+ 的
DynamicClient配合 Informer 可以动态监听任意 CRD,无需重新编译 - 如果你要写 Operator,直接用
controller-runtime;如果只是做集群巡检或快照导出,裸用 Informer 更可控
最容易被忽略的初始化细节
不是认证方式,也不是 namespace 过滤,而是 ResyncPeriod 参数——它控制 Informer 主动刷新本地缓存的频率,默认是 0(不主动刷新)。在长时间运行的备份服务中,若不设值(比如设为 5 * time.Minute),可能因网络抖动或 Watch 断连导致缓存 stale,漏掉资源变更。
另一个坑是 ResourceVersion 处理:Informer 的 Watch 从 resourceVersion="0" 开始,但 List 必须用 resourceVersion=""(空字符串),否则会报错 Invalid value: "0": a resource version may only be used with list or watch。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










