如何用PromQL计算CPU使用率的MIN/MAX/AVG?查询异常排查
PromQL查询返回空结果及平均值偏差问题
我编写了测试脚本,使用rate()获取千分比CPU使用率(例:50m=50/1000 CPU核利用率),并通过两个查询对比结果:
window_sec=120 curl -s -G "http://master.com:30355/api/v1/query_range" \ --data-urlencode "query=rate(container_cpu_usage_seconds_total{namespace='arka-ingress', \ pod='pod', container=''}[${window_sec}s]) * 1000" \ --data-urlencode "start=$(($(date +%s)-window_sec))" \ --data-urlencode "end=$(date +%s)" \ --data-urlencode "step=15s" | jq curl -s -G "http://master.com:30355/api/v1/query" \ --data-urlencode "query=avg(rate(container_cpu_usage_seconds_total{namespace='arka-ingress', \ pod='pod', container=''}[${window_sec}s])) * 1000" | jq
查询输出如下:
{"status": "success", "data": {"resultType": "matrix", "result": [{"metric": {"beta_kubernetes_io_arch": "amd64", "beta_kubernetes_io_os": "linux", "cpu": "total", "feature_node_kubernetes_io_network_sriov_capable": "true", "id": "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod0c5de2b8_2dea_4dd6_9a5c_bef29bc01c35.slice", "instance": "master.com", "job": "kubernetes-nodes-cadvisor", "kubernetes_io_arch": "amd64", "kubernetes_io_hostname": "master.com", "kubernetes_io_os": "linux", "namespace": "ingress", "node_openshift_io_os_id": "rhcos", "pod": "pod"}, "values": [[1685838435, "3.0482985848760746"], [1685838450, "3.0482985848760746"], [1685838510, "3.604911126207486"]]}]}} {"status": "success", "data": {"resultType": "vector", "result": []}}
第二个查询应返回第一个查询结果的平均值,但实际返回空;增大window_sec后虽有结果,但数值并非正确平均值且存在偏差。已知第一个rate()查询正确,请问第二个查询是否编写错误?
问题分析与修正
第二个查询存在两处关键问题:
标签过滤不匹配
从第一个查询的输出可见,实际数据的namespace标签值为ingress,但第二个查询中写的是arka-ingress,这直接导致没有匹配到任何时间序列,返回空结果。聚合逻辑错误
你需要计算的是时间维度上多个速率值的平均值,但avg()是对同一时刻的多个序列做聚合,并非对单个序列的多个时间点求平均。正确的做法是使用avg_over_time()函数,它会对指定时间范围内的时间序列样本求平均。
修正后的查询
window_sec=120 curl -s -G "http://master.com:30355/api/v1/query" \ --data-urlencode "query=avg_over_time(rate(container_cpu_usage_seconds_total{namespace='ingress', pod='pod', container=''}[${window_sec}s])[$(($(date +%s)-window_sec)):15s]) * 1000" | jq
逻辑说明
rate(container_cpu_usage_seconds_total[${window_sec}s]):计算每个滑动窗口内的CPU使用率速率,和第一个查询的逻辑一致;[$(($(date +%s)-window_sec)):15s]:指定要计算平均的时间范围(和第一个query_range的start/end一致)以及步长(和step一致);avg_over_time(...):对这个范围内的所有速率样本求平均,得到的就是第一个查询结果的平均值。
至于增大window_sec后有结果但数值偏差,是因为此时rate()计算的是更长窗口内的整体平均速率,和第一个查询中多个短窗口的速率平均值逻辑完全不同,因此结果会出现偏差。
内容的提问来源于stack exchange,提问作者mberge
相关产品推荐
相关产品推荐

