4. Alertmanager 架构:分组、抑制、静默、路由树,高可用部署模式
Alertmanager 是 Prometheus 生态中负责告警路由、去重、降噪与发送的核心组件。它接收来自 Prometheus Server 的告警,经过分组、抑制、静默等逻辑处理后,将告警通知发送到邮件、PagerDuty、Slack、Webhook 等接收端。理解其内部架构与高可用部署模式,是构建可靠巡检方案的基础。
4.1 核心处理流程与路由树
Alertmanager 内部采用管道式架构,告警依次经过以下阶段:
- 接收(Inhibition):通过 HTTP API 接收 Prometheus 推送的告警。
- 静默检查(Silence Check):匹配当前活跃的静默规则,匹配的告警被标记为静默状态,不发送通知。
- 分组(Grouping):根据
group_by标签将告警归入同一组,等待组内合并。 - 抑制(Inhibition):根据抑制规则,如果存在更高优先级的告警,则抑制低优先级告警。
- 路由(Routing):根据路由树匹配告警的标签,决定发送到哪个接收器(Receiver)。
- 发送(Dispatch):通过接收器配置的通知渠道发送告警。
关键概念: 路由树是一棵基于标签匹配的决策树。每个路由节点可以定义匹配规则(
match / match_re)、分组配置、接收器以及子路由。告警从根路由开始逐级向下匹配,直到找到第一个匹配的叶子节点。
4.2 分组(Grouping)
分组是 Alertmanager 最重要的降噪机制。它将同一时间窗口内、具有相同标签集的告警合并为一条通知,避免告警风暴。
| 配置项 | 说明 | 典型值 |
|---|---|---|
group_by |
指定用于分组的标签列表,如 ['alertname', 'severity'] |
['alertname', 'cluster'] |
group_wait |
首次告警后等待同一组内其他告警的时间,用于合并 | 30s |
group_interval |
同一组告警发送通知的最小间隔 | 5m |
repeat_interval |
告警已解决后重新发送通知的间隔 | 4h |
巡检最佳实践: 在容量水位场景中,建议按
['alertname', 'namespace', 'node'] 分组,避免同一节点上多个 Pod 的 CPU 告警被拆成多条通知。
4.3 抑制(Inhibition)
抑制规则用于在存在更高优先级告警时,自动屏蔽低优先级告警。例如,当节点宕机时,抑制该节点上所有 Pod 的不可用告警。
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['node']
上述规则表示:当存在 severity=critical 的告警时,如果目标告警的 severity=warning 且 node 标签相同,则抑制该 warning 告警。
4.4 静默(Silence)
静默允许运维人员手动或通过 API 临时屏蔽特定告警,常用于计划内维护窗口。静默规则基于标签匹配,支持设置持续时间。
- 创建方式:通过 Alertmanager Web UI 或
amtool命令行工具。 - 匹配逻辑:静默规则中的标签必须与告警标签完全匹配(支持正则)。
- 过期机制:静默到期后自动失效,告警恢复发送。
注意: 静默规则在 Alertmanager 集群中默认不自动同步。如果使用高可用部署,需要配置
--cluster.peer 参数使静默状态在节点间传播。
4.5 高可用部署模式
Alertmanager 支持通过 Gossip 协议组成集群,实现告警去重与高可用。典型部署模式有两种:
| 模式 | 架构 | 优点 | 缺点 |
|---|---|---|---|
| Gossip 集群 | 多个 Alertmanager 实例通过 --cluster.peer 互联,共享告警状态 |
自动去重,任一节点故障不影响告警发送 | 网络分区可能导致重复通知 |
| 负载均衡 + 独立实例 | Prometheus 通过 DNS 轮询或 LB 将告警分发到多个独立 Alertmanager | 部署简单,无状态 | 无法去重,可能收到重复告警 |
在生产环境中,推荐使用 Gossip 集群模式。Prometheus 配置中通过 alertmanagers 字段指定所有 Alertmanager 实例地址,Prometheus 会自动将告警发送到所有实例,由 Alertmanager 集群内部通过 Gossip 协议协商去重。
4.6 配置示例:完整路由树与高可用
以下是一个适用于容量巡检场景的 Alertmanager 配置片段,包含分组、抑制、路由树与集群配置:
global:
resolve_timeout: 5m
smtp_smarthost: 'smtp.example.com:587'
route:
receiver: 'default-receiver'
group_by: ['alertname', 'namespace']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- match:
severity: critical
receiver: 'pagerduty-critical'
repeat_interval: 1h
- match_re:
team: (infra|sre)
receiver: 'slack-infra'
inhibit_rules:
- source_match:
severity: critical
target_match:
severity: warning
equal: ['node', 'namespace']
receivers:
- name: 'default-receiver'
email_configs:
- to: 'ops@example.com'
- name: 'pagerduty-critical'
pagerduty_configs:
- routing_key: 'YOUR_KEY'
- name: 'slack-infra'
slack_configs:
- api_url: 'https://hooks.slack.com/services/...'
# 高可用集群配置
alertmanager:
cluster:
peer: ['alertmanager-0:9094', 'alertmanager-1:9094', 'alertmanager-2:9094']
巡检方案集成: 在容量水位巡检中,建议将
group_by 设置为 ['alertname', 'namespace', 'node'],并配置抑制规则:当节点级 NodeDiskPressure 告警触发时,抑制该节点上所有 Pod 级别的 PodDiskPressure 告警,避免告警冗余。