📈 第05章 · 告警规则与 Alertmanager
rules + 告警路由
告警规则与 Alertmanager¶
数据全了,也画成图了,但监控的最终目的是出事时立刻有人知道。这就是告警的活:Prometheus 根据规则评估表达式,命中后把"报警"交给 Alertmanager,由它负责"去告诉谁、怎么告诉、几轮提醒"。这一章从规则文件讲起,再到 Alertmanager 的配置与路由。
告警链路长什么样¶
规则评估(Prometheus) → 生成告警 → Alertmanager → 接收方(邮件/飞书/钉钉)
rule_files firing/pending /api/v2/alerts route + receiver
- Prometheus 定期(默认
evaluation_interval,这里 15s)评估规则,命中条件进入pending,持续满足超过for时长进入firing; - Alertmanager 收到
firing告警,按路由规则分发到响应的接收渠道。
rule_files:挂规则文件¶
告警规则写在独立 YAML 文件里,由 rule_files 加载(第 2 章说过目前是注释状态,要用就得打开):
rule_files:
- "/etc/prometheus/rules/alert.rules.yml"
易错 当前
/etc/prometheus/prometheus.yml的rule_files下两行都是注释。不取消注释,就算规则文件存在也永远不会评估——这是"为什么告警不触发"的高频元凶。路径写绝对路径最稳。
规则文件结构¶
一个规则文件包含若干 groups,组里是若干常用 rules:
groups:
- name: node_rules
rules:
- record: job:node:up # 记录规则:预计算,存成新指标
expr: up{job="node"}
- alert: InstanceDown # 告警规则
expr: up{job="node"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "节点 {{ $labels.instance }} 已宕机"
| 字段 | 含义 |
|---|---|
record |
记录规则,把表达式算成新指标存起来复用 |
alert |
告警规则名称 |
expr |
触发条件表达式,为真则进入告警 |
for |
持续多久才真正 firing,能避免瞬时抖动误报 |
labels |
附加标签(最常用 severity) |
annotations |
告警说明文字,可用模板变量 $labels/$value |
三套实用告警规则¶
结合本机实际,写一组可直接用的:
groups:
- name: alerting_rules
rules:
- alert: InstanceDown
expr: up{job="node"} == 0
for: 1m
labels: { severity: critical }
annotations:
summary: "节点 {{ $labels.instance }} 无响应"
description: "Prometheus 已连续 1 分钟抓取失败。"
- alert: HighCPUUsage
expr: 100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m]))*100) > 85
for: 5m
labels: { severity: warning }
annotations:
summary: "CPU 使用率过高 ({{ $value }}%)"
description: "近 5 分钟 CPU 超过 85%,需关注是否被压满。"
- alert: DiskAlmostFull
expr: 1 - node_filesystem_free_bytes{mountpoint="/"}/node_filesystem_size_bytes{mountpoint="/"} > 0.85
for: 10m
labels: { severity: warning }
annotations:
summary: "根分区即将用满 ({{ $value | humanizePercentage }})"
description: "根分区使用率连续 10 分钟超过 85%,建议清理日志。"
提示
for是误报的"减压阀"。CPU 瞬时冲高可能是正常业务尖峰,for: 5m表示持续 5 分钟才真正告警;而InstanceDown本身已是强信号,for: 1m就够。新规则先给一个宽松的for,跑几天观测再收紧。
告警生命周期¶
| 状态 | 含义 |
|---|---|
pending |
表达式命中,但还没持续到 for 阈值 |
firing |
已持续超过 for,真正发往 Alertmanager |
resolved |
条件恢复满足,Alertmanager 发"恢复"通知 |
用 CLI 查看当前告警状态:
curl -s "localhost:9090/api/v1/alerts" | python3 -m json.tool
Alertmanager:收件与分发¶
Alertmanager 是独立二进制(默认端口 9093),负责去重、分组、路由、抑制与静默。配置示例 alertmanager.yml:
route:
group_by: ['alertname']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receiver: 'default'
routes:
- match: { severity: critical }
receiver: 'pager'
receivers:
- name: 'default'
webhook_configs:
- url: 'http://localhost:8080/notify'
- name: 'pager'
email_configs:
- to: 'oncall@example.com'
| 配置段 | 作用 |
|---|---|
route |
告警路由:按标签匹配决定发谁 |
group_by |
按什么维度打包(避免刷屏) |
group_wait/interval |
打包前的等待窗口 |
repeat_interval |
重复提醒间隔 |
inhibit_rules |
抑制规则:高阶告警压制低阶 |
receivers |
具体渠道(邮件/webhook/飞书/钉钉) |
易错/安全 目前这台服务器的
alerting.alertmanagers指向localhost:9093,但9093并未监听,即 Alertmanager 尚未安装启动。配置就绪≠链路通了;要用告警,必须先安装并启动 Alertmanager,再确认9093在监听。
检查链路是否打通¶
# 1. 配置文件校验
promtool check config /etc/prometheus/prometheus.yml
promtool check rules /etc/prometheus/rules/alert.rules.yml
# 2. 重载生效
systemctl reload prometheus
# 3. 查看已加载的规则
curl -s "localhost:9090/api/v1/rules" | python3 -m json.tool | grep -E '"name"|"state"'
# 4. 确认告警、Alertmanager 可达
curl -s "localhost:9093/api/v2/alerts" # 需 Alertmanager 在跑
易错点¶
rule_files忘了取消注释:规则文件存在但 Prometheus 根本不知道。for太小:生产里瞬时抖动会频繁误报,新规则先宽松再收紧。alerting.alertmanagers指向一个没跑的 9093:配置合法但告警始终发不出去。expr比较方向写反:如 CPU 用了> 85变成"低于85告警",检查阈值方向。- 模板变量用错:
{{ $value }}得到的是数值,{{ $labels.instance }}得到主机;想要百分比要用humanizePercentage。
相关命令¶
promtool check rules <file>、curl -s localhost:9090/api/v1/rules、curl -s localhost:9090/api/v1/alerts、curl -s localhost:9093/api/v2/alerts、systemctl reload prometheus。