metrics-server是kubernetes集群提供cpu/内存实时指标的核心组件,支撑kubectl top、hpa等原生能力;它通过/apis/metrics.k8s.io/v1beta1暴露节点和pod指标,仅保留2分钟窗口数据,不存储历史,需配合prometheus实现长期监控与告警。

直接调用 metrics-server 的 /nodes/{name}/metrics 接口最轻量
集群里跑着 metrics-server 是前提,没它就什么都别试——kubectl top node 都会报 error: Metrics not available for nodes。先确认它在运行:kubectl get pods -n kube-system | grep metrics-server。如果没起来,Go 程序再怎么写也拿不到数据。
接口路径是 /apis/metrics.k8s.io/v1beta1/nodes/{node-name},返回结构里 usage.cpu 和 usage.memory 是关键字段,但注意:
-
usage.cpu是字符串,如"234m",得手动转成毫核整数(234)或纳秒(234 * 1e6) -
usage.memory是字符串,如"1.2Gi",需解析单位(Ki/Mi/Gi)再换算为字节 - 该 API 默认只保留 2 分钟窗口数据,查太老的时间点会返回空数组,不是你的 Go 代码漏了逻辑
用 client-go 调 metrics.k8s.io/v1beta1 客户端而非 corev1
别误用 clientset.CoreV1().Nodes(),那个拿不到指标,它只管资源定义。必须用 metrics-client:
import (
metricsv1beta1 "k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1"
)
<p>// 构建 metrics client
metricsClient, err := metricsv1beta1.NewForConfig(config)
if err != nil {
log.Fatal(err)
}</p><p>// 获取单个节点指标
metrics, err := metricsClient.NodeMetricses().Get(context.TODO(), nodeName, metav1.GetOptions{})
</p>
关键点:
- 导入路径是
k8s.io/metrics/pkg/client/clientset/versioned/typed/metrics/v1beta1,不是k8s.io/client-go主包 - 需要额外引入
k8s.io/metrics模块,go get k8s.io/metrics@v0.30.0(版本要跟集群匹配) - 集群内运行时用
rest.InClusterConfig(),别手写 token 或 host
查不到数据?先排除 metrics-server 自身问题
常见失败不是 Go 写错了,而是 metrics-server 卡在中间环节:
- Pod 处于
CrashLoopBackOff:检查日志kubectl logs -n kube-system deploy/metrics-server,常见原因是证书不信任(加--kubelet-insecure-tls启动参数临时绕过) - API Server 拒绝聚合层请求:确认
aggregation-layer已启用,kubectl get apiservice v1beta1.metrics.k8s.io状态必须是True - Node 不上报:
kubelet必须开启--enable-debugging-handlers=true(默认开启),且防火墙没拦10250端口 - 权限不足:ServiceAccount 缺少
system:auth-delegatorClusterRoleBinding,会导致 403
想长期监控?别只靠 metrics-server 实时抓取
metrics-server 是瞬时采样,不存历史,也不做聚合。真要分析 CPU 负载趋势或做告警,得走 Prometheus:
- 用
node_load1、node_load5、node_load15查系统平均负载 - 用
100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)算 CPU 使用率 - Go 程序里调 Prometheus API 时,
time参数必须是 Unix 秒级时间戳,传字符串会静默失败 - 分母别硬编码核数,用
count by(instance) (node_cpu_seconds_total{mode="user"})动态取当前节点总核数
metrics-server 和 Prometheus 是互补关系,不是二选一。前者适合快速看一眼,后者才支撑真实运维闭环。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











