Prometheus Alertmanager 告警怎么配置?
线上服务出问题却收不到告警,或者告警多到看不过来——这是很多团队上 Prometheus 后遇到的典型问题。核心原因往往出在两个环节:告警规则写得不准,或者 Alertmanager 路由配置没理顺。下面从规则定义到通知分发,把完整链路讲清楚。
告警规则:Prometheus 端定义触发条件
告警规则写在独立的规则文件中,由 Prometheus 负责评估。一条规则的核心要素:
- expr:PromQL 表达式,定义什么条件算异常
- for:条件持续多久才触发,避免瞬时抖动误报
- labels:附加标签,供 Alertmanager 路由和分组使用
- annotations:告警描述,出现在通知内容里
示例——CPU 使用率超过 80% 持续 5 分钟:
yamlgroups: - name: node_alerts rules: - alert: HighCPUUsage expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80 for: 5m labels: severity: warning team: infra annotations: summary: "{{ $labels.instance }} CPU 使用率过高" description: "当前值 {{ $value }}%,阈值 80%"
再补一个内存告警的例子,实际生产中 CPU 和内存往往配对出现:
yaml- alert: HighMemoryUsage expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 85 for: 5m labels: severity: critical team: infra annotations: summary: "{{ $labels.instance }} 内存使用率过高" description: "当前值 {{ $value }}%,阈值 85%"
规则文件在 prometheus.yml 中通过 rule_files 加载:
yamlrule_files: - "alerts/*.yml"
for 子句的工作机制
for 不是简单的延迟。Prometheus 内部对每条规则维护三个状态:
- Inactive:表达式不满足,无告警
- Pending:表达式满足,但还没持续到
for指定的时间 - Firing:表达式满足且持续了
for时间,告警真正触发并推送给 Alertmanager
理解这个状态机有助于排查告警"延迟触发"的问题——如果 for 设了 10m,但指标在 9 分钟时恢复正常又再次超限,Pending 计时器会重置。
连接 Alertmanager:让告警有去处
Prometheus 自身不发送通知,需要把告警推给 Alertmanager。在 prometheus.yml 中配置:
yamlalerting: alertmanagers: - static_configs: - targets: - alertmanager:9093
如果部署了多个 Alertmanager 实例做高可用,直接列出所有目标即可:
yamlalerting: alertmanagers: - static_configs: - targets: - alertmanager-1:9093 - alertmanager-2:9093 - alertmanager-3:9093
Prometheus 会向所有实例推送告警,Alertmanager 内部通过 Gossip 协议同步状态,确保同一条告警不会重复发送通知。
配置完成后,Prometheus 会将 Firing 状态的告警持续推送到 Alertmanager。
Alertmanager 路由:决定谁收到什么通知
Alertmanager 的核心逻辑是「收到告警 → 分组 → 路由 → 抑制/静默检查 → 发送通知」。路由配置决定了告警最终走向哪个接收器。
路由是一个树状结构:根节点是默认路由,子节点通过标签匹配来覆盖默认行为。告警从根节点进入,深度优先遍历,匹配到第一个符合条件的节点就停下来处理。
基础路由示例:
yamlroute: group_by: ['alertname', 'cluster'] group_wait: 30s group_interval: 5m repeat_interval: 4h receiver: 'default' routes: - match: severity: critical receiver: 'oncall' repeat_interval: 1h - match: team: infra receiver: 'infra-team'
四个时间参数的含义:
- group_wait:收到该组第一条告警后等多久再发通知,目的是攒一批一起发
- group_interval:同组后续告警的最小发送间隔
- repeat_interval:同一条告警重复通知的最小间隔
- group_by:按哪些标签分组,相同标签值的告警合并为一条通知
子路由 routes 支持按标签匹配,实现不同级别的告警走不同通道。
match 和 match_re 的区别
- match:精确匹配,标签值必须完全相等
- match_re:正则匹配,标签值满足正则表达式即可
yamlroutes: - match_re: service: nginx|apache receiver: 'web-team' - match_re: service: mysql|mongodb|redis receiver: 'db-team'
当一个告警可能匹配多条子路由时,默认只走第一条匹配到的。如果需要一条告警同时发送给多个接收器,在子路由中加上 continue: true:
yamlroutes: - match: severity: critical receiver: 'oncall' continue: true - match: team: infra receiver: 'infra-team'
这样 critical 级别的告警会同时发给 oncall 和 infra-team。
接收器配置:通知发到哪里
Alertmanager 支持多种通知渠道,包括 Email、Slack、PagerDuty、Webhook、企业微信、钉钉等:
yamlreceivers: - name: 'default' email_configs: - to: 'ops@example.com' from: 'alertmanager@example.com' smarthost: 'smtp.example.com:587' - name: 'oncall' webhook_configs: - url: 'https://hooks.example.com/alert' send_resolved: true - name: 'infra-team' email_configs: - to: 'infra@example.com'
send_resolved: true 表示告警恢复时也发通知,生产环境建议开启。
通知模板自定义
默认通知格式信息量有限,可以通过 Go Template 自定义通知内容。在全局配置中指定模板文件路径:
yamltemplates: - '/etc/alertmanager/templates/*.tmpl'
模板中可以引用告警的 Labels 和 Annotations,灵活组织通知内容。
告警抑制:高优先级告警压制低优先级
当集群整体故障时,不需要再收到该集群上每个服务的低级别告警。抑制规则实现这个逻辑:
yamlinhibit_rules: - source_match: severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'cluster']
含义:当同一个集群同一种告警存在 critical 级别时,warning 级别的不再单独通知。equal 列表是判断「同一种告警」的依据。
也可以同时定义多条抑制规则,覆盖不同场景:
yamlinhibit_rules: - source_match: severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'cluster'] - source_match: alertname: 'NodeDown' target_match: severity: 'warning' equal: ['instance']
第二条规则表示:当某个节点宕机时,该节点上的所有 warning 级别告警都抑制掉,因为它们大概率是节点宕机的连锁反应。
告警静默:维护窗口免打扰
计划内维护期间可以通过 API 创建静默规则,匹配到的告警不会发送通知:
bashcurl -X POST http://alertmanager:9093/api/v2/silences \ -H 'Content-Type: application/json' \ -d '{ "matchers": [ {"name": "cluster", "value": "prod-east", "isRegex": false} ], "startsAt": "2026-05-27T02:00:00Z", "endsAt": "2026-05-27T06:00:00Z", "createdBy": "ops-team", "comment": "Planned maintenance" }'
也可以在 Alertmanager Web UI(默认 9093 端口)中可视化创建和管理静默规则。
静默与抑制的区别:抑制是配置文件中静态定义的规则,随 Alertmanager 启动生效;静默是运行时动态创建的,适合临时场景,到期自动失效。
全局配置与 resolve_timeout
Alertmanager 的全局配置中有一个容易忽略的参数 resolve_timeout:
yamlglobal: resolve_timeout: 5m
含义是:如果 Alertmanager 在 5 分钟内没有收到某条告警的更新(即 Prometheus 不再推送该告警),就认为该告警已恢复。这个机制是告警自动恢复的兜底策略——正常情况下 Prometheus 会主动发送 resolved 事件,但如果 Prometheus 重启或网络中断,resolved 事件可能丢失,此时 resolve_timeout 就起作用了。
生产环境建议根据告警的重要程度调整:关键告警可以设长一些(15m-30m),避免因短暂断连导致误报恢复。
配置验证与常见问题
修改 Alertmanager 配置后,用 amtool 检查语法:
bashamtool check-config alertmanager.yml
也可以用 amtool 测试路由匹配结果,确认一条告警会走哪个接收器:
bashamtool config routes test --config.file alertmanager.yml \ severity=critical team=infra alertname=HighCPUUsage
几个生产环境常见的坑:
- 告警一直 Firing 不恢复:检查
for时间是否过长,或 PromQL 表达式本身是否有问题;另外确认resolve_timeout是否合理 - 收不到通知:确认 Prometheus 能连通 Alertmanager,检查路由匹配条件是否正确,用
amtool config routes test验证 - 通知太频繁:增大
repeat_interval,启用group_by合并同类告警 - 静默未生效:确认 matchers 的标签名和值与告警标签完全一致,注意大小写敏感
- 子路由不生效:检查是否因为前面的子路由已经匹配,后面被跳过了;需要同时匹配时加
continue: true - HA 部署下重复通知:确认多个 Alertmanager 实例之间网络互通,Gossip 协议正常同步