如何用 Prometheus 计算 K8s 容器的 CPU 使用率?
K8s 容器 CPU 使用率通过 cAdvisor 暴露的 container_cpu_usage_seconds_total 指标计算:rate 后按 namespace、pod/container 分组得到平均使用核数。本文给出完整 PromQL、request/limit 利用率算法与常见坑。
核心公式:sum(rate(container_cpu_usage_seconds_total{container!="", container!="POD", pod!=""}[5m])) by (namespace, pod)——对 CPU 累计秒数取速率,结果就是每个 Pod 在该窗口内平均使用的 CPU 核数。
指标从哪来?
kubelet 内置 cAdvisor,自动采集每个容器的 container_cpu_usage_seconds_total(CPU 累计使用秒数)。Prometheus 抓取 kubelet 的 /metrics/cadvisor 端点即可获得。
常用 PromQL
# 每个 Pod 的 CPU 使用核数
sum(rate(container_cpu_usage_seconds_total{container!="", container!="POD", pod!=""}[5m])) by (namespace, pod)
# 换算成占 request 的百分比
sum(rate(container_cpu_usage_seconds_total{container!="", container!="POD", pod!=""}[5m])) by (namespace, pod)
/ (sum(kube_pod_container_resource_requests{resource="cpu", unit="core"}) by (namespace, pod) > 0) * 100
# 占 limit 的百分比(仅在分母涵盖同一组限额容器时有意义)
sum(rate(container_cpu_usage_seconds_total{container!="", container!="POD", pod!=""}[5m])) by (namespace, pod)
/ (sum(kube_pod_container_resource_limits{resource="cpu", unit="core"}) by (namespace, pod) > 0) * 100
request 为 0 或缺失时不计算百分比;部分容器未设 limit 时,分母不能代表整个 Pod 的总容量。init container、Pod 级资源等有效资源规则需另行核对。
注意三个坑
- 过滤空标签:根据实际标签排除容器外的聚合与沙箱序列,不能认为 image 为空一定是沙箱。多集群应限定 cluster,重复抓取需先去重,不能直接相加;
- 使用率 vs 核数:rate 结果是核数(0.5 = 半核),要百分比必须除以 request 或 limit;
- CPU 限流:达到 limit 会被 throttle,关注
container_cpu_cfs_throttled_seconds_total的速率及 throttled periods;五分钟均值低于 limit 也可能发生短时限流,不能保证它一定提前预警。
常见问题(FAQ)
Q:为什么我的查询结果为空? 检查是否抓到了 cadvisor 端点(应进一步限定实际 /metrics/cadvisor 对应的 job/endpoint 标签,其他 kubelet 端点 up 不代表该端点成功),老版本 K8s 的指标名前缀可能不同。
Q:rate 窗口选多大? CPU 波动快,建议 5m;告警场景可以 [5m] 趋势 + 持续时长双条件。