如何用Prometheus检测K8s容器CPU使用率与请求、限制的关系?
搞定Prometheus CPU使用率与请求/限制的关联检测
嘿,我来帮你解决这个CPU指标关联的问题!你已经搞定了内存的检测,CPU其实思路类似,只是需要先把container_cpu_usage_seconds_total这个累计指标转换成和请求/限制单位一致的实时使用率,这样就能直接对比了。
核心原理:让CPU指标单位对齐
container_cpu_usage_seconds_total是累计的CPU使用秒数,而kube_pod_container_resource_requests_cpu_cores的单位是核数(cores),直接对比肯定不对。我们需要用irate或rate函数把累计值转换成每秒CPU使用率(cores)——这个值和请求/限制的单位完全一致,就可以直接做除法对比了。
举个例子:如果irate结果是1.2,就代表容器当前用了1.2核CPU,和请求的1核、限制的2核完全可比。
具体查询语句
1. 容器实时CPU使用率(转换后)
用irate适合捕捉突发峰值(告警常用),rate适合长期平均趋势:
sum by(container_name, pod_name) ( irate(container_cpu_usage_seconds_total{ namespace=~"myNamespace", pod_name=~"myPodName", container_name=~"myContainerName", container_name!="pause" # 排除kubelet的pause沙箱容器 }[1m]) )
2. CPU请求值(对齐标签)
注意K8s资源指标的标签是container,而容器指标是container_name,用label_replace统一标签名,确保后续运算能匹配:
sum by(container_name, pod_name) ( label_replace( kube_pod_container_resource_requests_cpu_cores{ namespace=~"myNamespace", pod=~"myPodName", container=~"myContainerName" }, "container_name", "$1", "container", "(.*)" # 把container标签转成container_name ) )
3. CPU限制值(同样对齐标签)
sum by(container_name, pod_name) ( label_replace( kube_pod_container_resource_limits_cpu_cores{ namespace=~"myNamespace", pod=~"myPodName", container=~"myContainerName" }, "container_name", "$1", "container", "(.*)" ) )
告警规则示例
把上面的查询组合起来,就能实现你要的三种检测:
检测CPU使用率超过请求值(比如超过120%,可调整阈值)
sum by(container_name, pod_name) ( irate(container_cpu_usage_seconds_total{ namespace=~"myNamespace", pod_name=~"myPodName", container_name=~"myContainerName", container_name!="pause" }[1m]) ) / sum by(container_name, pod_name) ( label_replace( kube_pod_container_resource_requests_cpu_cores{ namespace=~"myNamespace", pod=~"myPodName", container=~"myContainerName" }, "container_name", "$1", "container", "(.*)" ) ) > 1.2
检测CPU使用率低于请求值(比如低于50%,可能资源浪费)
把上面的> 1.2改成< 0.5即可。
检测CPU使用率接近限制值(比如达到90%)
sum by(container_name, pod_name) ( irate(container_cpu_usage_seconds_total{ namespace=~"myNamespace", pod_name=~"myPodName", container_name=~"myContainerName", container_name!="pause" }[1m]) ) / sum by(container_name, pod_name) ( label_replace( kube_pod_container_resource_limits_cpu_cores{ namespace=~"myNamespace", pod=~"myPodName", container=~"myContainerName" }, "container_name", "$1", "container", "(.*)" ) ) > 0.9
几个注意点
- 标签对齐是关键:如果你的环境中两个指标的标签名本来就一致(比如都是container_name),可以去掉
label_replace,直接用相同的标签sum by。 - irate vs rate:告警优先用
irate,因为它对短时间的CPU峰值更敏感;如果是做趋势面板,rate更稳定。 - 排除无关容器:一定要加上
container_name!="pause",不然会把K8s的沙箱容器CPU算进去,干扰结果。
内容的提问来源于stack exchange,提问作者scoulomb
相关产品推荐
相关产品推荐

