我正在计算 Kubernetes 集群所有节点的内存利用率。指标由 Node Exporter 收集。我最终想要一个数字来代表整个集群在过去 24 小时内的平均效率。
使用 Prometheus,我可以使用如下查询获取单个节点的“即时”值(其中节点过滤器正是节点名称):
100 -
(
avg(node_memory_MemAvailable_bytes{jobLabel="node-exporter", node="aks-spot-62019936-vmss0000j5"})
/
avg(node_memory_MemTotal_bytes{jobLabel="node-exporter", node="aks-spot-62019936-vmss0000j5"})
* 100
)
但是,如果我将节点过滤器更改为类似运算符,则它无法返回单个值,如下所示:
100 -
(
avg(node_memory_MemAvailable_bytes{jobLabel="node-exporter", node=~"aks-spot-.*"})
/
avg(node_memory_MemTotal_bytes{jobLabel="node-exporter", node=~"aks-spot-.*"})
* 100
)
奇怪的是,如果我将过滤器更改为:node=~“aks-linux-.*”,这是AKS节点池中的节点,其数量不会改变。 另外,如果我更改为使用“范围”查询,而不是“即时”查询,它就可以工作。
你能告诉我为什么以及它是如何发生的吗?请问如何实现我的目标? 非常感谢
要使用通配符实现跨所有节点的聚合,您需要按要聚合的标签对结果进行分组。但是,由于您想要一个代表整个簇的数字,因此您根本不应该按
node
标签进行分组;相反,您应该将所有结果汇总在一起。
以下是计算过去 24 小时内所有匹配节点的平均内存利用率的正确查询:
100 * (1 - (
sum(avg_over_time(node_memory_MemAvailable_bytes{job="node-exporter", instance=~"10\\.224\\.\\d+\\.\\d+:9100"}[24h]))
/
sum(avg_over_time(node_memory_MemTotal_bytes{job="node-exporter", instance=~"10\\.224\\.\\d+\\.\\d+:9100"}[24h]))
))
在这里,
avg_over_time()
计算过去 24 小时内向量中每个时间序列的平均值。sum()
然后将所有平均值相加,得到集群范围内可用内存和总内存的总数。MemAvailable
与 MemTotal
之和的比率,减去 1 得到利用率,最后乘以 100 转换为百分比。group by
子句,sum()
函数会在所有节点上聚合,忽略各个 node
标签。您可能无法在节点标签中获取具有通配符模式的单个值的原因是,不带组修饰符的
avg
函数计算向量中所有元素的平均值。当您在节点标签中使用模式匹配时,您将创建一个包含多个元素的向量(每个元素对应一个与模式匹配的节点),并且 Prometheus 不会隐式聚合这些不同的系列,因为它使用不同的序列来对待每个系列node
标记为唯一。
参考资料: