那是因为 cAdvisor 从 cgroups 获取这些值。 cgroups 的结构看起来像一棵树,其中每个 pod 都有分支,每个 pod 中的每个容器都有子 cgroups。这就是它的外观(systemd-cgls):
├─kubepods
│ ├─podb0c98680-4c6d-4788-95ef-0ea8b43121d4
│ │ ├─799e2d3f0afe0e43d8657a245fe1e97edfdcdd00a10f8a57277d310a7ecf4364
│ │ │ └─5479 /bin/node_exporter --path.rootfs=/host --web.listen-address=0.0.0.0:9100
│ │ └─09ce1040f746fb497d5398ad0b2fabed1e4b55cde7fb30202373e26537ac750a
│ │ └─5054 /pause
每个cgroup 的资源值是其所有子代的累积值。这就是您将内存利用率翻倍的方式,您只需汇总 pod 总消耗量和其中的每个容器。
如果您在 Prometheus 中执行这些查询,您会注意到重复的值:
{pod="cluster-autoscaler-58b9c77456-krl5m"} 59076608
{container="POD",pod="cluster-autoscaler-58b9c77456-krl5m"} 708608
{container="cluster-autoscaler",pod="cluster-autoscaler-58b9c77456-krl5m"} 58368000
第一个是父cgroup。如您所见,它没有container 标签。此示例中的另外两个是the pause container 和实际应用程序。结合它们的值,您将得到父 cgroup 的值:
>>> 708608 + 58368000 == 59076608
True
解决方案取决于您的需求,但无论如何它都会修复查询。例如,您可以使用 container_name!="" 标签过滤器从没有容器名称的聚合指标中删除(container_name 标签可以在您的设置中以不同的方式命名)。