不推荐单独依赖 client-go 做生产级监控,它适合控制器逻辑或轻量状态轮询,而非替代 Prometheus;应结合 SharedInformer 实现稳定事件监听、超时控制和 CRD 状态补充,定位为精准干预而非持续观测。
直接用 client-go 做集群状态监控是可行的,但**不推荐单独依赖它做生产级监控**——它适合控制器逻辑或轻量状态轮询,不适合替代 Prometheus 这类专为指标采集设计的系统。
这是最典型的“监控”动作:不查日志、不拉指标,而是监听资源生命周期事件。关键在于避免自己实现重连和事件去重。
clientset.CoreV1().Pods("default").Watch(ctx, metav1.ListOptions{Watch: true}) 返回 watch.Interface,调用 ResultChan() 获取 watch.Event
Event.Type 是 Added/Modified/Deleted,Event.Object 是 *corev1.Pod,需类型断言ctx.Done() 导致 goroutine 泄漏;Watch 连接断开后没重试,直接静默退出cache.NewSharedInformer 封装,它自动重连、本地缓存、支持 AddEventHandler 注册回调单纯查 Node.Status.Conditions 里 Type=="Ready" 的 Status=="True" 不够——很多故障下节点仍显示 Ready,但实际无法调度 Pod。
Node.Status.Allocatable 是否非空,以及 Node.Spec.Unschedulable == false
Node.Status.NodeInfo.KubeletVersion 和 Node.Status.Images 判断 kubelet 是否活跃(比如 5 分钟内没上报镜像列表,大概率失联)List() 后遍历判断,却没设 context.WithTimeout,API Server 响应慢时整个监控流程卡住ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second),用完记得 cancel()
Prometheus 擅长指标,但对 CRD 资源的语义状态(比如 MyDatabase.Spec.Replicas == MyDatabase.Status.ReadyReplicas)抓取困难,这时 client-go 是唯一选择。
Status.Phase == "Failed",立刻发告警或触发修复逻辑scheme,否则 clientset.RESTClient() 解析失败,报错 "no kind is registered for the type"
myv1.AddToScheme(scheme.Scheme),再传给 dynamic.NewForConfig 或自定义 clientset它本质是 Kubernetes 客户端 SDK,不是监控采集器。硬用它做全量指标采集,会踩一堆隐性坑:
429 Too Many Requests)真正该做的,是让 client-go 做“精准干预”(比如发现 Deployment 失败立即 Patch 回滚),把“持续观测”交给 Prometheus + Grafana ——两者定位不同,混用反而增加运维复杂度。