Prometheus:如何用通配符计算AKS集群节点平均内存利用率
问题原因分析
1. 标签聚合逻辑导致多结果返回
使用通配符node=~"aks-spot-.*"时,若当前集群存在多个Spot节点,原始查询中的avg()函数默认会保留node标签(未通过by()/without()移除标签维度),因此会返回每个节点的单独计算结果,而非单个集群级数值。而固定节点池aks-linux-.*可能节点数量少(甚至只有1个),聚合后恰好返回单个值。
2. Spot节点动态伸缩的影响
AKS Spot节点池支持自动扩缩容,部分节点可能在过去24小时内被销毁,对应的指标时间序列中断。若直接用瞬时查询的avg()聚合,会忽略已销毁节点的历史数据,既无法反映完整24小时的平均状态,还可能因部分节点指标缺失导致结果异常。
集群过去24小时平均内存利用率的实现方案
根据节点规格是否统一,选择以下两种查询方式:
方式一:节点内存规格统一时(简单平均)
先计算每个节点过去24小时内的平均利用率,再对所有节点的平均值做聚合,得到集群整体平均:
avg( avg_over_time( 100 - (node_memory_MemAvailable_bytes{jobLabel="node-exporter", node=~"aks-spot-.*"} / node_memory_MemTotal_bytes{jobLabel="node-exporter", node=~"aks-spot-.*"} * 100)[24h] ) ) by ()
方式二:节点内存规格不同时(加权平均)
以节点总内存为权重,计算加权平均利用率,避免因节点配置差异导致结果偏差:
sum( avg_over_time( 100 - (node_memory_MemAvailable_bytes{jobLabel="node-exporter", node=~"aks-spot-.*"} / node_memory_MemTotal_bytes{jobLabel="node-exporter", node=~"aks-spot-.*"} * 100)[24h] ) * avg_over_time(node_memory_MemTotal_bytes{jobLabel="node-exporter", node=~"aks-spot-.*"}[24h]) ) / sum(avg_over_time(node_memory_MemTotal_bytes{jobLabel="node-exporter", node=~"aks-spot-.*"}[24h]))
核心逻辑说明
avg_over_time(...):对单个节点的指标时间序列,计算过去24小时内的平均值,保留每个节点的历史数据(包括已销毁节点的周期数据)。by ():移除所有标签维度,将多节点的聚合结果合并为单个集群级数值。- 加权平均通过“节点平均利用率 × 节点总内存”的求和,再除以集群总内存,确保大内存节点的利用率对结果影响更合理。
内容的提问来源于stack exchange,提问作者Xun Ren
相关产品推荐
相关产品推荐

