本篇文章由 AI 辅助完成
Informer 就是一个带“自动更新”功能的本地缓存(Local Cache)。
直观理解:订阅模式 vs. 轮询模式 想象你要==监控集群里的 Pod 状态==:
笨办法(直接调用 Client): 你每隔 5 秒问一次 API Server:“现在的 Pod 列表是什么?”
后果:集群里有 1 万个 Pod,你每秒问一次,API Server 的 QPS 瞬间爆炸,你会被限流(Rate Limit)。 术语:这叫 Polling(轮询),效率低,延迟高。 聪明办法(使用 Informer): 你告诉 API Server:“我要订阅 Pod 的变化”。
过程: 先全量拿一次列表(List),存到你本地内存里。 建立长连接(Watch),只要有变化,API Server 主动推给你。 你更新本地内存,并触发你的回调函数(Callback)。 后果:大部分查询直接读本地内存,零网络开销。只有变化时才通信。 术语:这叫 Watch 机制 + Client-side Caching。 代码极简版 核心就三步:创建 -> 注册回调 -> 启动。
package main import ( "context" "time" corev1 "k8s.io/api/core/v1" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" ) func main() { // 假设 clientset 已经初始化好 var clientset *kubernetes.Clientset // 1. 创建 Informer:监听所有 Namespace 的 Pod // 参数 30*time.Minute 是 Resync 周期,意思是即使没变化,每隔这么久也重新同步一次(防丢失) factory := informers.NewSharedInformerFactory(clientset, 30*time.Minute) podInformer := factory.Core().V1().Pods().Informer() // 2. 注册回调:告诉 Informer 有事了叫我 podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { pod := obj.(*corev1.Pod) klog.Infof("捕获新增 Pod: %s", pod.Name) // 这里写你的业务逻辑,比如加入工作队列 }, UpdateFunc: func(oldObj, newObj interface{}) { // 只有真正变化了才处理,避免噪音 oldPod := oldObj.(*corev1.Pod) newPod := newObj.(*corev1.Pod) if oldPod.ResourceVersion == newPod.ResourceVersion { return } klog.Infof("捕获更新 Pod: %s", newPod.Name) }, DeleteFunc: func(obj interface{}) { klog.Infof("捕获删除 Pod") }, }) // 3. 启动 ctx, cancel := context.WithCancel(context.Background()) defer cancel() // 异步启动 Informer go factory.Start(ctx.Done()) // 等待缓存同步完成(这步很重要,否则查不到数据) factory.WaitForCacheSync(ctx.Done()) klog.Info("Informer 已就绪,正在监听...") // 阻塞主线程 <-ctx.Done() } 为什么要用 Informer? 如果你只是写个脚本一次性查个数据,用 clientset.CoreV1().Pods().Get() 没问题。
...