为何cAdvisor指标添加过滤条件后container_memory_working_set_bytes数值减半
测试了如下两个PromQL查询,发现第一个查询的返回值仅为第二个查询的一半:
sum(container_memory_working_set_bytes{image!="",name=~"^k8s_.*",pod=~"$pod"}) by (pod)sum (container_memory_working_set_bytes{pod=~"$pod"}) by (pod)
请问为何添加image!="",name=~"^k8s_.*"过滤条件后,查询得到的数值会减半?
原因分析
该差异是container_memory_working_set_bytes指标的上报逻辑和过滤条件的筛选范围共同导致的,具体说明如下:
- kubelet上报该指标时会覆盖cgroup的所有层级:既会上报Pod根cgroup层级的整体内存统计值,也会上报Pod下每个独立容器(业务容器、pause基础设施容器)的单独内存统计值。
- 第一个查询的过滤条件仅统计容器级的业务容器内存:
name=~"^k8s_.*"正则仅匹配k8s标准业务容器的统计项,Pod根层级的统计项name标签不符合该规则,直接被过滤image!=""进一步过滤掉无镜像属性的统计项,再次排除了无镜像的Pod根层级聚合项、空镜像残留容器的统计
- 未加过滤的第二个查询存在重复统计:求和范围同时包含Pod根层级的总内存值、以及所有容器的内存值,而正常场景下Pod根层级的总内存数值和所有容器的内存总和基本一致,两者相加后总数值是容器总和的两倍,因此第一个查询的结果刚好是第二个的一半。
用法建议
- 如果需要统计Pod的整体内存占用,推荐直接查询Pod根层级的统计项即可,避免重复计算:
sum(container_memory_working_set_bytes{pod=~"$pod", container=""}) by (pod) - 如果需要统计Pod内所有业务容器的内存总和,使用第一个查询的写法即可,统计结果准确。
内容的提问来源于stack exchange,提问作者redmagic0099
相关产品推荐
相关产品推荐

