Prometheus 怎么把 CPU 秒数(cpu_seconds_total)换算成使用率百分比?
Prometheus 计数器换算 CPU 使用率:rate() 求每秒增量即核数,×100 得百分比;node_cpu_seconds_total 与容器 container_cpu_usage_seconds_total 的完整 PromQL 示例与 FAQ。
核心思路:CPU 秒数是累计计数器**(counter),用 rate() 求每秒增量——结果直接就是"占用了几个核",乘 100 就是百分比。** 每秒消耗 1 秒 CPU = 占满 1 个核。
主机 CPU(node_exporter)
# 整机 CPU 使用率(%):100 减去空闲占比
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# 只看用户态(user)使用率
avg by (instance) (rate(node_cpu_seconds_total{mode="user"}[5m])) * 100
拆解 rate(node_cpu_seconds_total{mode="idle"}[5m]):
node_cpu_seconds_total按mode(idle/user/system/iowait…)分标签累计 CPU 时间;rate(...[5m])计算 5 分钟窗口内每秒增量 → 每个CPU序列的空闲时间占比;avg by (instance)把各核合并;1 - idle 是非空闲时间占比,包含 iowait/steal 等,不等于纯执行时间。
容器 CPU(cAdvisor/kubelet)
# 每个容器的 CPU 使用核数
rate(container_cpu_usage_seconds_total{container!=""}[5m])
# 换算成占其 limit 的百分比(K8s 场景更实用)
100 *
sum without (cpu) (rate(container_cpu_usage_seconds_total{container!=""}[5m]))
/ on (namespace, pod, container) group_left
(
(container_spec_cpu_quota{container!=""} > 0)
/ container_spec_cpu_period{container!=""}
)
要点:quota 和 period 都是微秒,quota/period 才得到CPU核数;周期不能固定假设100000。仅正配额有此百分比意义。使用前需核对 cpu 标签是总量、逐核还是缺省,不能同时累加总量和逐核;重复抓取及多集群同名容器也需去重/增加匹配标签,保证右侧每个容器唯一。
换算直觉检查
rate(...) 结果是 0.5 意味着:平均每秒钟消耗了 0.5 秒的 CPU——即半个核,50% 的单核使用率。双核机器上 0.5 核 = 整机的 25%,这就是"要不要除以核数"取决于你问的是"几核"还是"整机的百分之几"。
常见问题(FAQ)
Q:rate 和 irate 选哪个?
A:看趋势用 rate[5m](平滑);抓瞬时尖刺用 irate(只看最后两个点)。告警条件一般用 rate,避免毛刺误报。
Q:为什么算出来超过 100%?
A:多核叠加——进程用了 2 核,rate 结果就是 2,×100 是 200%。要归一化到整机百分比就除以核数(或直接用 1 - idle 的算法,天然在 0-100 内)。
Q:计数器重启清零会影响结果吗?
A:rate() 会处理可见的 counter reset,但采样缺口、短生命周期和外推仍会影响估计,不能保证完全无影响——这正是必须用它而不是手动算差值的原因。