如何用PromQL结合两个指标计算Kubernetes Pod内存使用率?
解决Prometheus中跨标签计算Pod内存使用率的问题
这个问题我之前也碰到过,核心就是得先把两个指标的标签对齐——毕竟它们的Pod标识标签名不一样(一个是pod_name,一个是pod),之后才能顺利做除法计算使用率。下面给你两种实用的实现方法:
方法一:用label_replace统一标签名
最直观的方式是通过label_replace函数把其中一个指标的标签重命名,让两个指标拥有相同的分组标签。比如把kube_pod_container_resource_limits_memory_bytes的pod标签改成pod_name,这样就能和container_memory_usage_bytes的标签完美匹配:
# 计算百分比形式的Pod内存使用率 (sum(container_memory_usage_bytes) by (pod_name) / sum(label_replace(kube_pod_container_resource_limits_memory_bytes, "pod_name", "$1", "pod", "(.*)")) by (pod_name)) * 100
函数简单解释:
label_replace(metric, new_label, replacement, old_label, regex)的作用就是:
- 针对
kube_pod_container_resource_limits_memory_bytes这个指标 - 用正则
(.*)匹配原标签pod的全部内容 - 创建一个新标签
pod_name,值和原pod标签完全一致
这样两个指标就都能通过pod_name分组,顺利完成除法运算。
方法二:用group_left做标签关联
如果不想修改标签名,也可以用group_left(或group_right)来实现跨标签的匹配关联——前提是两个标签的取值完全一致(比如pod_name和pod的值都是Pod的名称):
(sum(container_memory_usage_bytes) by (pod_name) / sum(kube_pod_container_resource_limits_memory_bytes) by (pod)) on(pod) group_left(pod_name) * 100
这里on(pod)指定关联逻辑是“当左边指标的pod_name值等于右边指标的pod值时进行匹配”,group_left(pod_name)表示保留左边指标的pod_name标签作为结果的分组标签。
额外优化:处理无内存限制的Pod
如果有些Pod没有配置内存限制,kube_pod_container_resource_limits_memory_bytes指标会不存在,这时候除法会出现NaN。你可以通过过滤或者默认值处理来优化:
# 只显示有内存限制的Pod使用率 (sum(container_memory_usage_bytes) by (pod_name) / sum(label_replace(kube_pod_container_resource_limits_memory_bytes, "pod_name", "$1", "pod", "(.*)")) by (pod_name)) * 100 and sum(label_replace(kube_pod_container_resource_limits_memory_bytes, "pod_name", "$1", "pod", "(.*)")) by (pod_name) > 0
或者用clamp_min避免除以0的情况:
(sum(container_memory_usage_bytes) by (pod_name) / clamp_min(sum(label_replace(kube_pod_container_resource_limits_memory_bytes, "pod_name", "$1", "pod", "(.*)")) by (pod_name), 1)) * 100
内容的提问来源于stack exchange,提问作者zhashuyu
相关产品推荐
相关产品推荐

