服务端阅读 05月27日 18:01
Prometheus Alertmanager 告警怎么配置?
线上服务出问题却收不到告警,或者告警多到看不过来——这是很多团队上 Prometheus 后遇到的典型问题。核心原因往往出在两个环节:告警规则写得不准,或者 Alertmanager 路由配置没理顺。下面从规则定义到通知分发,把完整链路讲清楚。告警规则:Prometheus 端定义触发条件告警规则写在独立的规则文件中,由 Prometheus 负责评估。一条规则的核心要素:expr:PromQL 表达式,定义什么条件算异常for:条件持续多久才触发,避免瞬时抖动误报labels:附加标签,供 Alertmanager 路由和分组使用annotations:告警描述,出现在通知内容里示例——CPU 使用率超过 80% 持续 5 分钟:groups: - 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 和内存往往配对出现: - 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 加载:rule_files: - "alerts/*.yml"for 子句的工作机制for 不是简单的延迟。Prometheus 内部对每条规则维护三个状态:Inactive:表达式不满足,无告警Pending:表达式满足,但还没持续到 for 指定的时间Firing:表达式满足且持续了 for 时间,告警真正触发并推送给 Alertmanager理解这个状态机有助于排查告警"延迟触发"的问题——如果 for 设了 10m,但指标在 9 分钟时恢复正常又再次超限,Pending 计时器会重置。连接 Alertmanager:让告警有去处Prometheus 自身不发送通知,需要把告警推给 Alertmanager。在 prometheus.yml 中配置:alerting: alertmanagers: - static_configs: - targets: - alertmanager:9093如果部署了多个 Alertmanager 实例做高可用,直接列出所有目标即可:alerting: alertmanagers: - static_configs: - targets: - alertmanager-1:9093 - alertmanager-2:9093 - alertmanager-3:9093Prometheus 会向所有实例推送告警,Alertmanager 内部通过 Gossip 协议同步状态,确保同一条告警不会重复发送通知。配置完成后,Prometheus 会将 Firing 状态的告警持续推送到 Alertmanager。Alertmanager 路由:决定谁收到什么通知Alertmanager 的核心逻辑是「收到告警 → 分组 → 路由 → 抑制/静默检查 → 发送通知」。路由配置决定了告警最终走向哪个接收器。路由是一个树状结构:根节点是默认路由,子节点通过标签匹配来覆盖默认行为。告警从根节点进入,深度优先遍历,匹配到第一个符合条件的节点就停下来处理。基础路由示例:route: 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:正则匹配,标签值满足正则表达式即可routes: - match_re: service: nginx|apache receiver: 'web-team' - match_re: service: mysql|mongodb|redis receiver: 'db-team'当一个告警可能匹配多条子路由时,默认只走第一条匹配到的。如果需要一条告警同时发送给多个接收器,在子路由中加上 continue: true:routes: - match: severity: critical receiver: 'oncall' continue: true - match: team: infra receiver: 'infra-team'这样 critical 级别的告警会同时发给 oncall 和 infra-team。接收器配置:通知发到哪里Alertmanager 支持多种通知渠道,包括 Email、Slack、PagerDuty、Webhook、企业微信、钉钉等:receivers: - 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 自定义通知内容。在全局配置中指定模板文件路径:templates: - '/etc/alertmanager/templates/*.tmpl'模板中可以引用告警的 Labels 和 Annotations,灵活组织通知内容。告警抑制:高优先级告警压制低优先级当集群整体故障时,不需要再收到该集群上每个服务的低级别告警。抑制规则实现这个逻辑:inhibit_rules: - source_match: severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'cluster']含义:当同一个集群同一种告警存在 critical 级别时,warning 级别的不再单独通知。equal 列表是判断「同一种告警」的依据。也可以同时定义多条抑制规则,覆盖不同场景:inhibit_rules: - source_match: severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'cluster'] - source_match: alertname: 'NodeDown' target_match: severity: 'warning' equal: ['instance']第二条规则表示:当某个节点宕机时,该节点上的所有 warning 级别告警都抑制掉,因为它们大概率是节点宕机的连锁反应。告警静默:维护窗口免打扰计划内维护期间可以通过 API 创建静默规则,匹配到的告警不会发送通知:curl -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_timeoutAlertmanager 的全局配置中有一个容易忽略的参数 resolve_timeout:global: resolve_timeout: 5m含义是:如果 Alertmanager 在 5 分钟内没有收到某条告警的更新(即 Prometheus 不再推送该告警),就认为该告警已恢复。这个机制是告警自动恢复的兜底策略——正常情况下 Prometheus 会主动发送 resolved 事件,但如果 Prometheus 重启或网络中断,resolved 事件可能丢失,此时 resolve_timeout 就起作用了。生产环境建议根据告警的重要程度调整:关键告警可以设长一些(15m-30m),避免因短暂断连导致误报恢复。配置验证与常见问题修改 Alertmanager 配置后,用 amtool 检查语法:amtool check-config alertmanager.yml也可以用 amtool 测试路由匹配结果,确认一条告警会走哪个接收器:amtool 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: trueHA 部署下重复通知:确认多个 Alertmanager 实例之间网络互通,Gossip 协议正常同步