【前情提要】 告警规则写好了,Prometheus 能判断“什么时候该喊人”了。但 Prometheus 只会“喊”,不会“通知”。谁负责把告警发到你邮箱?老周说:“Alertmanager。”小林打开 Alertmanager 文档,准备配置。但他不知道,route、receiver、group_by、repeat_interval,每一个都有讲究。

一、Prometheus 的“喊”和 Alertmanager 的“通知”

早上到工位,小林在 Prometheus 的 Alerts 页面,看着刚才触发的 HighCpuUsage 告警,状态是 firing。

“周哥,告警触发了,但我没收到任何通知啊。”

“因为 Prometheus 只会‘喊’,不会‘通知’。”老周说,“它告诉你‘条件满足了’,但它不知道怎么发邮件、发短信、发钉钉。Alertmanager 就是负责‘通知’的那个人。”

“那 Prometheus 和 Alertmanager 怎么配合?”

“Prometheus 触发告警后,把告警推给 Alertmanager。Alertmanager 收到后,根据配置,决定发给谁、发几次、什么时候不发。”老周说,“你可以把 Prometheus 理解成‘报警器’,Alertmanager 理解成‘值班调度员’。”

“调度员干啥?”

“三件事。”老周竖起三根手指。

第一,路由(route)。

“告警发给谁。severity: critical 发给运维负责人,severity: warning 发给普通值班。这叫路由。”

第二,分组(group)。

“同一类告警,合并成一条发。比如你十台机器同时磁盘满,Alertmanager 合并成一条‘10 台机器磁盘满’,而不是发十条。”

第三,抑制和静默(inhibit & silence)。

“抑制:一台机器挂了,它上面的所有服务告警都别发了,因为你知道是机器挂了。静默:你正在维护,手动把告警静音一段时间。”

小林在笔记本上写下:

  • Prometheus:判断什么时候告警
  • Alertmanager:决定告警发给谁、怎么发、发几次
  • 核心功能:路由、分组、抑制、静默

二、安装 Alertmanager

“Alertmanager 也是二进制安装。”老周说,“跟 Prometheus 一样。”

小林打开 Alertmanager 的 GitHub Releases 页面,找 ARM64 版本。

wget https://github.com/prometheus/alertmanager/releases/download/v0.x.x/alertmanager-0.x.x.linux-arm64.tar.gz
tar -xzvf alertmanager-0.x.x.linux-arm64.tar.gz
cd alertmanager-0.x.x.linux-arm64
ls

输出:

alertmanager
amtool
LICENSE
NOTICE
alertmanager.yml

“跟 Prometheus 一样。”小林说,“主程序、工具、配置文件。”

“对。”老周说,“alertmanager 是主程序,amtool 是命令行工具,alertmanager.yml 是配置文件。”

“放哪?”

“程序放 /usr/local/bin/,配置放 /etc/alertmanager/,数据放 /var/lib/alertmanager/。”

sudo mv alertmanager amtool /usr/local/bin/
sudo mkdir -p /etc/alertmanager /var/lib/alertmanager
sudo mv alertmanager.yml /etc/alertmanager/

“创建用户和权限。”

sudo useradd --no-create-home --shell /bin/false alertmanager
sudo chown -R alertmanager:alertmanager /etc/alertmanager /var/lib/alertmanager
sudo chown alertmanager:alertmanager /usr/local/bin/alertmanager /usr/local/bin/amtool

“写 systemd 服务。”

sudo nano /etc/systemd/system/alertmanager.service

写入:

[Unit]
Description=Alertmanager
Wants=network-online.target
After=network-online.target

[Service]
User=alertmanager
Group=alertmanager
Type=simple
ExecStart=/usr/local/bin/alertmanager \
    --config.file=/etc/alertmanager/alertmanager.yml \
    --storage.path=/var/lib/alertmanager/

[Install]
WantedBy=multi-user.target

“启动。”

sudo systemctl daemon-reload
sudo systemctl start alertmanager
sudo systemctl enable alertmanager
sudo systemctl status alertmanager

输出:

● alertmanager.service - Alertmanager
     Active: active (running)

“验证端口。”

sudo ss -lntp | grep 9093

输出:

LISTEN 0 4096 *:9093 *:* users:(("alertmanager",pid=1234,fd=7))

“9093 端口。”老周说,“打开浏览器,访问 http://localhost:9093。”

小林在 Ubuntu 里打开 Firefox,Alertmanager 的 Web UI 出现了。

“但现在是空的。”小林说,“啥都没有。”

“因为 Prometheus 还没连上它。”老周说,“你先看配置文件。”

三、alertmanager.yml:配置文件

cat /etc/alertmanager/alertmanager.yml

输出:

global:
  resolve_timeout: 5m

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'default-receiver'

receivers:
  - name: 'default-receiver'
    email_configs:
      - to: 'your-email@example.com'
        from: 'alertmanager@example.com'
        smarthost: 'localhost:25'
        require_tls: false

“这是默认配置。”老周说,“它已经有一个 email_configs,但收件人和发件人都是假的。你今天先不配邮件,先把 Prometheus 和 Alertmanager 连上,让告警能在 UI 里看到。邮件明天再配。”

“那今天要改什么?”

“只需要确认 route 和 receivers 的基础结构。”老周说,“我给你解释一下这几个字段。”

global.resolve_timeout

“告警恢复后,多久标记为已解决。默认 5 分钟。”

route

“路由规则。告警从 Prometheus 推过来后,Alertmanager 根据 route 决定发给哪个 receiver。”

group_by: ['alertname']

“按告警名称分组。同一类告警合并成一条。”

group_wait: 10s

“收到告警后,等 10 秒再发。为什么等?因为可能还有同类告警进来,等一等,合并成一条。”

group_interval: 10s

“同一组告警,两次发送之间的最小间隔。”

repeat_interval: 1h

“告警一直没恢复,每隔 1 小时再发一次提醒。不然你会被重复告警烦死。”

receiver: 'default-receiver'

“默认接收器。没有匹配到其他路由的告警,都发给它。”

receivers

“接收器列表。每个接收器定义一种通知方式。你今天先不改邮件,等明天。”

小林记下:

  • route:路由规则
  • group_by:分组依据
  • group_wait:首次等待时间
  • group_interval:同组发送间隔
  • repeat_interval:重复提醒间隔
  • receiver:默认接收器

四、让 Prometheus 连上 Alertmanager

“配置好了,现在让 Prometheus 把告警推给 Alertmanager。”老周说。

“在哪配?”

“prometheus.yml 里的 alerting 部分。”

小林打开:

sudo nano /etc/prometheus/prometheus.yml

找到:

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          # - alertmanager:9093

改成:

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - localhost:9093

“localhost:9093 是 Alertmanager 的地址。”老周说,“注意缩进,- targets: 下面那行 - localhost:9093,前面有两个 -,一个是指标列表,一个是目标列表。”

“那如果 Alertmanager 在另一台机器上呢?”

“写那台机器的 IP 和端口。”老周说,“但你现在本地,用 localhost 就行。”

“保存后先检查配置。”

promtool check config /etc/prometheus/prometheus.yml

输出:

SUCCESS: 1 rule files found

“重启 Prometheus。”

sudo systemctl restart prometheus
sudo systemctl status prometheus

输出:

Active: active (running)

“现在去 Prometheus 的 Web UI,点 Status → Runtime & Build Information,看 Alertmanagers 那一栏。”

小林点进去,看到:

Alertmanagers
  alertmanager:9093
    state: up
    ...

“state: up。”小林说,“Prometheus 连上 Alertmanager 了。”

“对。”老周说,“现在告警触发后,Prometheus 会推给 Alertmanager。Alertmanager 的 UI 里就能看到了。”

五、看 Alertmanager UI

“现在你再触发一次 CPU 告警。”老周说。

小林跑:

stress --cpu 4 --timeout 300

等了几分钟,刷新 Prometheus 的 Alerts 页面,HighCpuUsage 变成 firing。

再打开 Alertmanager 的 UI:

http://localhost:9093

首页出现了一个告警:

HighCpuUsage
  severity: warning
  instance: localhost:9100
  summary: CPU 使用率超过 80%
  state: active

“看到了吗?”老周说,“告警从 Prometheus 推到了 Alertmanager。Alertmanager 正在‘准备通知’。但因为你的 email_configs 是假的,它发不出去,所以卡在这了。”

“那它会不会一直卡着?”

“不会。”老周说,“它会尝试发送,失败后记录日志。但 UI 里能看到告警,说明链路通了。”

小林点进告警详情,看到:

Status
  State: Active
  Silenced: No
  Inhibited: No

Labels
  alertname: HighCpuUsage
  instance: localhost:9100
  severity: warning

Annotations
  summary: CPU 使用率超过 80%
  description: CPU 使用率已持续 2 分钟超过 80%,当前值 85.3%

“Active 表示告警正在触发,Silenced 和 Inhibited 都是 No,说明没有静默和抑制。”老周说,“你以后在 UI 里点 Silence,可以手动静默这个告警。”

“静默是干啥的?”

“比如你在维护,知道会触发告警,就先静默掉,别让它发邮件。”老周说,“静默有有效期,过期自动恢复。”

小林记下:

  • Alertmanager UI:http://localhost:9093
  • 告警状态:Active、Silenced、Inhibited
  • 可以在 UI 里手动静默告警

六、告警分组:别被十条告警淹没

“你现在只有一个告警,感觉不到分组的作用。”老周说,“假设你有十台机器,同时磁盘满,Prometheus 会推十条告警给 Alertmanager。Alertmanager 根据 group_by: ['alertname'],把这十条合并成一条,只发一封邮件。”

“那如果我想按机器分组呢?”

“改 group_by。”老周说,“group_by: ['alertname', 'instance'],这样同一台机器的同类告警合并,不同机器分开。”

“那 group_wait 和 group_interval 呢?”

“group_wait 是‘等一等,看看还有没有同组告警’。group_interval 是‘同一组告警,两次发送之间的最小间隔’。”老周说,“你以后配告警,这三个参数要根据场景调。比如磁盘告警,group_wait 可以长一点,等所有机器都报上来再一起发。”

“那 repeat_interval 呢?”

“告警一直没恢复,每隔多久再提醒一次。”老周说,“默认 1 小时。你如果嫌烦,可以改成 4 小时。但有些严重告警,你希望半小时提醒一次,就单独配。”

“怎么单独配?”

“在 route 下面加子路由。”老周说,“比如:”

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'default-receiver'
  routes:
    - match:
        severity: critical
      receiver: 'critical-receiver'
      repeat_interval: 30m

“match 匹配 severity: critical 的告警,走 critical-receiver,repeat_interval 改成 30 分钟。其他告警走默认的 default-receiver。”

小林记下:

  • group_by:按什么分组
  • group_wait:首次等待时间
  • group_interval:同组发送间隔
  • repeat_interval:重复提醒间隔
  • 子路由可以覆盖全局配置

七、amtool:命令行管理 Alertmanager

“除了 Web UI,Alertmanager 还有个命令行工具 amtool。”老周说,“你以后写脚本、查状态,用它。”

“怎么用?”

“先看告警。”

amtool alert

输出:

Alertname     Starts At                Summary
HighCpuUsage  2026-09-13 14:05:00 UTC  CPU 使用率超过 80%

“看静默。”

amtool silence query

“添加静默。”

amtool silence add alertname=HighCpuUsage --duration=1h --comment="维护中"

“--duration=1h 静默 1 小时,--comment 备注。”老周说,“你以后维护前,先静默告警,维护完再删。”

“那怎么看 Alertmanager 状态?”

amtool check-config /etc/alertmanager/alertmanager.yml

输出:

Checking '/etc/alertmanager/alertmanager.yml'  SUCCESS
Found:
 - global config
 - route
 - 1 receiver(s)

“check-config 检查配置文件语法。”老周说,“跟 Prometheus 的 promtool check config 一样。”

小林记下:

  • amtool alert:查看告警
  • amtool silence query:查看静默
  • amtool silence add:添加静默
  • amtool check-config:检查配置

八、排错挑战:Alertmanager UI 看不到告警

下午,小林故意停掉 node_exporter,想看看 InstanceDown 告警能不能在 Alertmanager UI 里看到。

等了两分钟,刷新 Prometheus Alerts 页面:

InstanceDown
  state: firing

“Firing 了。”小林说。

但打开 Alertmanager UI,首页空空如也。

“啥?”小林刷新了几次。还是没有。

他检查 Prometheus 的 Status → Runtime & Build Information:

Alertmanagers
  alertmanager:9093
    state: up

“Prometheus 连上 Alertmanager 了啊。”

他检查 Alertmanager 日志:

sudo journalctl -u alertmanager -n 30

输出:

level=warn msg="Alertmanager is not configured with any receivers"

“没配 receiver?”小林懵了,“我配置文件里有 default-receiver 啊。”

他打开配置文件:

cat /etc/alertmanager/alertmanager.yml

输出:

global:
  resolve_timeout: 5m

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'default-receiver'

receivers:
  - name: 'default-receiver'
    email_configs:
      - to: 'your-email@example.com'
        from: 'alertmanager@example.com'
        smarthost: 'localhost:25'
        require_tls: false

“有啊。”小林说。

他喊来老周。

老周看了一眼,问:“你改过配置之后,重启 Alertmanager 了吗?”

“没有……我改完 alertmanager.yml 之后,只重启了 Prometheus。”

“那就对了。”老周说,“Alertmanager 的配置改了,得 reload 或 restart Alertmanager。你只重启 Prometheus,Alertmanager 还在用旧配置——旧配置里可能没有 receiver。”

“那怎么 reload?”

“amtool 或者 curl。”

curl -X POST http://localhost:9093/-/reload

“或者直接 restart。”

sudo systemctl restart alertmanager

小林重启后,再次停掉 node_exporter,等两分钟,刷新 Alertmanager UI。

InstanceDown 出现了。

排错思路总结:

  1. Prometheus 告警 firing,但 Alertmanager UI 看不到,先检查 Prometheus 的 Alertmanagers 状态是否为 up。
  2. 如果 up,检查 Alertmanager 是否收到告警:看日志 journalctl -u alertmanager -n 30。
  3. 如果日志显示 not configured with any receivers,检查配置文件是否有 receivers。
  4. 如果配置有,但改完没生效,说明没 reload 或 restart Alertmanager。
  5. curl -X POST http://localhost:9093/-/reload 或 sudo systemctl restart alertmanager。
  6. 改了 Alertmanager 配置,必须 reload/restart 才生效。 只重启 Prometheus 没用。

“记住,”老周说,“Prometheus 和 Alertmanager 是两个独立的服务,配置也是独立的。 你改了谁的配置,就重启谁。别搞混。”

九、练习

  1. 练习一:用二进制安装 Alertmanager,创建 systemd 服务,启动并验证 9093 端口监听。在浏览器访问 http://localhost:9093,确认 UI 正常显示。
  2. 练习二:修改 prometheus.yml 的 alerting 部分,添加 localhost:9093 作为 Alertmanager 目标。用 promtool check config 检查通过后,重启 Prometheus。在 Prometheus 的 Status → Runtime & Build Information 中,确认 Alertmanagers 状态为 up。
  3. 练习三:用 stress 触发 CPU 告警,在 Prometheus Alerts 页面确认状态为 firing。然后在 Alertmanager UI 中确认能看到 HighCpuUsage 告警。用 amtool alert 查看告警列表,用 amtool silence add 静默该告警,确认 UI 中状态变为 Silenced。

参考答案

练习一:

wget https://github.com/prometheus/alertmanager/releases/download/v0.x.x/alertmanager-0.x.x.linux-arm64.tar.gz
tar -xzvf alertmanager-0.x.x.linux-arm64.tar.gz
cd alertmanager-0.x.x.linux-arm64

sudo mv alertmanager amtool /usr/local/bin/
sudo mkdir -p /etc/alertmanager /var/lib/alertmanager
sudo mv alertmanager.yml /etc/alertmanager/

sudo useradd --no-create-home --shell /bin/false alertmanager
sudo chown -R alertmanager:alertmanager /etc/alertmanager /var/lib/alertmanager
sudo chown alertmanager:alertmanager /usr/local/bin/alertmanager /usr/local/bin/amtool

sudo nano /etc/systemd/system/alertmanager.service

服务文件参考正文。

sudo systemctl daemon-reload
sudo systemctl start alertmanager
sudo systemctl enable alertmanager
sudo systemctl status alertmanager
sudo ss -lntp | grep 9093

浏览器访问 http://localhost:9093。

练习二:

sudo nano /etc/prometheus/prometheus.yml

alerting 部分:

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - localhost:9093
promtool check config /etc/prometheus/prometheus.yml
sudo systemctl restart prometheus

Prometheus UI → Status → Runtime & Build Information,确认 Alertmanagers 的 state: up。

练习三:

stress --cpu 4 --timeout 300

Prometheus Alerts 页面确认 HighCpuUsage 为 firing。

Alertmanager UI 确认看到 HighCpuUsage。

amtool alert
amtool silence add alertname=HighCpuUsage --duration=1h --comment="测试静默"
amtool silence query

Alertmanager UI 中确认状态变为 Silenced。

十、下集预告

Alertmanager 装好了,告警能从 Prometheus 推到 Alertmanager 了。但小林还没收到任何邮件。老周说:“Alertmanager 只会‘调度’,不会‘发邮件’。发邮件得靠 Postfix。”小林打开 Postfix 文档,准备配置 SMTP。但他不知道,QQ 邮箱授权码、sasl_passwd、main.cf,每一个都可能让他折腾。

下一集:《告警的“嘴”:配置 Postfix + QQ 邮箱,让告警发出来》