Prometheus dev-23后缀容器停止告警无法获取容器名问题咨询
问题根因
你现在的告警拿不到容器名、标签全为空,核心是两个问题:
absent()函数本身的设计特性:只要它触发返回值1,返回的向量是不携带任何指标标签的纯标量,所有依赖$labels的模板自然取不到内容,最终呈现空的map。- 现有表达式的触发逻辑不符合预期:只要还有任意一个匹配dev-23后缀的运行中容器,这个表达式就会返回空向量,只有当所有匹配的容器全部消失时才会触发告警,不是单个容器停止就触发。
调整方案
方案1:用cadvisor原生指标,配置最简单
cadvisor采集的容器指标里自带container_last_seen字段:只要容器处于运行状态,每次采集时都会把这个字段的时间戳更新为当前值;容器停止后不再被采集,这个字段的时间戳会停止更新。
基于这个特性写表达式,触发时返回的结果会完整携带容器名、所在实例等所有标签,不存在空标签的问题:
- 核心表达式:
time() - container_last_seen{name=~".*dev-23"} > 60 - 逻辑:容器距离最后一次被采集的时长超过60秒,就判定为已停止
方案2:无依赖的时序差量对比
如果因为采集配置、版本问题拿不到container_last_seen指标,可以通过「历史存在的容器标签集合和当前集合做差」的方式,把消失的容器的标签带出来:
- 核心表达式:
(count by (name, instance) (container_start_time_seconds{name=~".*dev-23"} offset 2m)) unless (count by (name, instance) (container_start_time_seconds{name=~".*dev-23"})) - 逻辑:对比2分钟前存在的dev-23后缀容器集合,和当前时刻同规则的容器集合,返回2分钟前存在、但当前已消失的容器条目,结果同样携带完整的name、instance标签
调整后的完整规则示例
用方案1的写法,参考配置如下:
- alert: ContainerKilled expr: time() - container_last_seen{name=~".*dev-23"} > 60 for: 1m labels: severity: 'critical' annotations: summary: '容器停止:{{ $labels.name }}(节点 {{ $labels.instance }})' description: '匹配dev-23后缀的容器已连续1分钟无采集数据,判定为停止运行\n 容器名称:{{ $labels.name }}\n 所在节点实例:{{ $labels.instance }}\n 距最后一次采集时长:{{ $value | humanizeDuration }}'
优化注意点
- 把原来转义的
\\n换成真实换行,不然告警内容里会显示字面的\n字符串,影响可读性 - 表达式的60秒阈值可以根据实际的采集间隔调整,一般设置为采集间隔的3-4倍,避免临时网络抖动导致的误告警
- 原来的
for: 0m建议适当调整为1m左右,和表达式的检测窗口匹配,减少偶发采集中断带来的告警噪音
内容的提问来源于stack exchange,提问作者Tamar
相关产品推荐
相关产品推荐

