Prometheus 重启之后报警竟然自动解决了。。
更多奇技淫巧欢迎订阅博客:https://fuckcloudnative.io
前言
最近我在看 Prometheus 重启之后,报警自动解决并且稍后又重新触发的问题,所以就定位了一下原因,然后觉得可以从社区得到解决方案。没想到社区上已经有了解决方案,并且已经实现了,思路不谋而合,下面就翻译一下开发这个 feature 的人所写的一篇记录。
这恰好是我在 GSoC 期间解决的第一个问题。你可以在这里找到 PR#4061[1],它已经被合并到 Prometheus master 中,并且从 “v2.4.0 “开始就可以使用。
这篇文章假设你已经基本了解了什么是监控以及报警的关系。如果您是新手,那么 这篇文章[2] 应该可以帮助您开始学习。
1. 问题
简单来说,Prometheus 中的警报,一个警报规则由一个 条件
、for
持续时间和一个 黑盒
来处理警报。所以这里简单的技巧就是,如果 条件
在 for
持续时间内是 true
,我们就会触发一个警报(称为产生警报),并把它交给 黑匣子
,让它按照自己想要的方式处理,可以是发送邮件,也可以是 Slack 消息等等。
前面说了报警的产生,假设你有一个 for
持续时间为 24小时
的警报,而 Prometheus 在该警报处于活动状态(condition
为 true
)的 23小时
时崩溃,也就是说,在它即将触发前的 1 小时。现在,当 Prometheus 再次启动时,它将不得不再次等待 24小时
后才会触发!你可以在这里找到 GitHub issue #422[3]
2. 修复方式
用时间序列来存储状态!在 Prometheus 中的代码就是这么处理的。
在每次评估告警规则的过程中,我们将历史的告警的 ActiveAt
(什么时候condition
第一次变成了true
)记录在一个名称为ALERTS_FOR_STATE
的时间序列中,其中包括该告警的所有标签。这和其他时间序列一样,但只存储在本地;当 Prometheus 被重新启动时,会有一个工作运行,用于恢复第二次评估后的警报状态。我们等到第二次评估时,这样我们就有足够的采集数据来了解当前的活跃报警; 对于每一个当前处于活跃状态的报警,作业寻找其对应的 ALERTS_FOR_STATE
时间序列。时间戳和 series 的最后一个样本的值给我们提供了 Prometheus 什么时候宕机的信息,以及报警最后活跃的时间;因此,如果 for
持续时间是D
,报警在X
开始激活,而 Prometheus 在Y
崩溃,那么警报必须等待更多D-(Y-X)
持续时间(为什么?想想看!)。所以对警报的变量进行调整,让它等待更多的D-(Y-X)
时间再触发,而不是D
;
3. 需要注意的事项
rules.alert.for-outage-tolerance | default=1h
这个标志指定了 Prometheus 对宕机的容忍时间。所以如果 Prometheus 宕机时间超过了这个 flag 中设置的时间,那么报警的状态就不会恢复。所以一定要根据你的需要改变 flag 的值,或者让 Prometheus 尽快起来!
rules.alert.for-grace-period | default=10m
我们不希望在 Prometheus 启动后就发出报警。所以我们引入了一个叫做
宽限期
的东西,如果D-(Y-X)
恰好小于rules.alert.for-grace-period
,那么我们就等待宽限期的持续时间,然后再发出警报。
注意:只有当 for
持续时间本身是 ≥rules.alert.for-grace-period
时,我们才会遵循这个逻辑。
4. 疑难杂症
由于 ALERTS_FOR_STATE
series 存储在本地存储中,如果在 Prometheus 宕机时恰好丢失了本地的 TSDB 数据,那么就会永久丢失报警的状态。
参考资料
PR#4061: https://github.com/prometheus/prometheus/pull/4061
[2]这篇文章: https://www.digitalocean.com/community/tutorials/an-introduction-to-metrics-monitoring-and-alerting
[3]GitHub issue #422: https://github.com/prometheus/prometheus/issues/422
原文链接:https://liqiang.io/post/6997f1d8
你可能还喜欢
点击下方图片即可阅读
云原生是一种信仰 ?
扫码关注公众号
后台回复◉k8s◉获取史上最方便快捷的 Kubernetes 高可用部署工具,只需一条命令,连 ssh 都不需要!
点击 "阅读原文" 获取更好的阅读体验!
❤️给个「在看」,是对我最大的支持❤️