直接结论:用 kube-apiserver 的 /readyz(优先)和 /livez 端点做健康检查,Go 中通过 HTTP GET 请求实现,需正确配置 ServiceAccount 认证或 kubeconfig、加载 CA 证书、设置超时并复用 http.Client,禁用 InsecureSkipVerify,避免高频轮询。

怎么用Go调用Kubernetes API做集群健康检查
直接结论:别自己轮询所有组件状态,用 kube-apiserver 提供的 /healthz、/livez、/readyz 端点最轻量且可靠。Go 里只需发 HTTP GET 请求,但必须处理好认证和 TLS 验证。
常见错误是硬编码 http://localhost:8080/healthz —— 这在 Pod 外根本连不上,而且跳过证书校验(InsecureSkipVerify: true)在生产环境等于裸奔。
- 从 Pod 内部检查:用 ServiceAccount 自动挂载的
/var/run/secrets/kubernetes.io/serviceaccount/token和ca.crt - 从集群外检查:需配置 kubeconfig,用
rest.InClusterConfig()(Pod 内)或clientcmd.BuildConfigFromFlags()(本地)生成rest.Config - 务必复用
http.Client并设置超时(建议Timeout: 5 * time.Second),避免连接堆积
为什么 /readyz 比 /healthz 更值得监控
/healthz 已被弃用(1.20+ 版本返回 404 或重定向),实际应优先用 /readyz(判断是否可接收流量)和 /livez(判断进程是否存活)。三者返回状态码都是 200 才算通过,但检查项不同:
-
/livez只检查 etcd 连通性和 apiserver 进程,不依赖其他组件 -
/readyz额外检查 controller-manager、scheduler 是否就绪(通过 leader election lock),更贴近真实可用性 - 加
?verbose参数(如/readyz?verbose)可看到每个子检查项(etcd、informer-sync等)的具体状态和耗时
示例请求逻辑:
立即学习“go语言免费学习笔记(深入)”;
resp, err := client.Get("https://<code>api-server-ip</code>:6443/readyz?verbose")
if err != nil || resp.StatusCode != 200 {
// 触发告警
}
如何避免自检程序本身成为集群负担
高频轮询 /readyz 会增加 apiserver 压力,尤其当集群规模大、启用了大量 check 插件(如 ssh、etcd)时。关键控制点:
- 默认间隔至少设为 15 秒以上,不要用 1s 或 5s ——
kubelet自身也只每 10 秒查一次/healthz - 禁用非必要检查项:在 apiserver 启动参数中加
--healthz-port=0关闭旧端点,用--livez-grace-period和--readyz-grace-period控制容忍延迟 - 如果只是验证“集群能否响应”,用
HEAD /readyz替代GET,减少响应体传输开销
遇到 x509: certificate signed by unknown authority 怎么办
这是最常卡住的点:Go 默认校验服务器证书,而 k8s apiserver 的证书通常是私有 CA 签发的。解决方式取决于运行位置:
- Pod 内:读取挂载的
/var/run/secrets/kubernetes.io/serviceaccount/ca.crt,用它构建tls.Config.RootCAs - 本地调试:把
kubeconfig里的certificate-authority-database64 解码后写入临时文件,再加载 - 绝对不要全局设
InsecureSkipVerify: true—— 即便测试环境,也应限定到目标域名(用tls.Config.VerifyPeerCertificate做白名单校验)
真正容易被忽略的是:某些托管集群(如 EKS、AKS)的 endpoint 域名会动态变更,CA 证书也可能定期轮换,硬编码证书路径或跳过校验会导致某天突然全部失效。


















