AI Infra 训练营
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub
总览
  • Day 1 · 集群起步 + CNI
  • Day 2 · 控制面 + etcd
  • Day 3 · CRD + Operator + Webhook
  • Day 4 · 存储深度
  • Day 5 · 卷扩容 + 安全
  • Day 6 · 调度 + 可观测
  • Day 7 · Harbor + ArgoCD + Mesh
  • Day 8 · AI Infra
  • Day 9 · Triton + GPU
  • Day 10 · MIG + HPA + 量化
  • Day 11 · AI Agent 端到端
  • Day 12 · 灾备
  • Day 13 · Operator + 联邦 + Mesh + RAG
  • Day 14 · CKA / CKS + 总结
  • LLM 训练手册
  • RAG + Agent 手册
  • 推理优化手册
  • 上下文工程手册
  • Agent 开发手册
  • 面试深度复盘
  • 训练 v2 深度手册
  • 心智模型
  • 看懂命令输出
  • 容器网络底层
  • K8s 网络深入
  • DNS 全套
  • 故障排查方法论
  • 心智模型
  • 容器挂载完整指南
  • K8s Volumes 大全
  • PV/PVC/CSI 深入
  • NFS 深入
  • 分布式存储概览
  • 故障排查 runbook
HiHuo 主站
GitHub

alertmanager / amtool —— 告警分组、抑制、路由

一句话定义

alertmanager 是 Prometheus 全家桶的告警分发组件:接收 prometheus 发来的告警,按规则分组、抑制、静默、路由到不同接收方(PagerDuty / 钉钉 / Slack / 邮件 / Webhook)。amtool 是它的命令行客户端,比 web UI 更适合自动化。

典型场景

  • 看当前 firing 告警:amtool alert
  • 创建临时静默(升级窗口):amtool silence add
  • 验证配置:amtool check-config
  • 路由测试(哪条 receiver 会收到):amtool config routes test
  • 批量管理 silence

Prometheus 触发 alert,alertmanager 分发。两个分开理解。


装

amtool 装:

# 单机
apt install prometheus-alertmanager       # Ubuntu

# 容器 / K8s 里 alertmanager pod 自带 amtool
kubectl exec -n monitoring alertmanager-xxx-0 -- amtool --help

# 单独下载
curl -L https://github.com/prometheus/alertmanager/releases/download/v0.27.0/alertmanager-0.27.0.linux-amd64.tar.gz | tar xz
mv alertmanager-*/amtool /usr/local/bin/

amtool 配置(让它知道 alertmanager 在哪)

# 选项 1:每次命令行加
amtool --alertmanager.url http://amgr:9093 alert

# 选项 2:写配置文件
mkdir -p ~/.config/amtool
cat > ~/.config/amtool/config.yml <<'EOF'
alertmanager.url: http://amgr:9093
EOF

amtool alert                            # 自动读 config

K8s 里通常 port-forward:

kubectl port-forward -n monitoring svc/alertmanager 9093:9093 &

看 firing 告警

amtool alert
# Alertname               Starts At                Summary
# KubeNodeNotReady        2026-05-27 14:00:00 UTC  Node m4 not ready
# HighMemoryUsage         2026-05-27 14:05:00 UTC  Pod memory > 80%
# ...

amtool alert --inhibited                # 含被抑制的
amtool alert --silenced                  # 含被静默的
amtool alert --active                    # 只看 active(默认)
amtool alert -o extended                  # 详细输出

按 label 过滤:

amtool alert alertname=HighMemoryUsage
amtool alert severity=critical
amtool alert namespace=my-app

label=value 是 selector 语法。


静默(silence)

升级窗口、计划维护、误报抑制 —— 都靠 silence。

添加 silence

# 静默某 alert 4 小时
amtool silence add alertname=HighMemoryUsage --duration=4h --comment="维护中"

# 静默某 ns 所有 alert 1 小时
amtool silence add namespace=my-app --duration=1h --comment="升级"

# 静默某 severity 30 分钟
amtool silence add severity=warning --duration=30m --comment="噪音过滤"

# 多 label
amtool silence add severity=warning namespace=test --duration=1h

看现有 silence

amtool silence query
amtool silence query --within=1h            # 1 小时内创建的
amtool silence query expired                 # 过期的
amtool silence query <id>                    # 看单个

删 silence

amtool silence expire <silence-id>           # 让它立即过期
amtool silence expire $(amtool silence query -q)   # 删所有(小心)

-q quiet 模式只输出 ID(管道用)。


验证配置

amtool check-config /etc/alertmanager/alertmanager.yml
# Checking '/etc/alertmanager/alertmanager.yml'
#   SUCCESS
# Found:
#  - global config
#  - route
#  - 5 inhibit rules
#  - 10 receivers
#  - 5 templates

改完 amgr 配置必跑这条——避免 reload 失败。

CI 流水线里:

amtool check-config alertmanager.yml || exit 1

路由测试 —— 哪个 alert 会去哪个 receiver

这是 amtool 最强大的功能:给定一组 label,告诉你这个 alert 会走到哪条 receiver。

amtool config routes test alertname=HighMemoryUsage severity=critical
# Matches the following routes:
#   default-route → critical-pagerduty

或者交互式:

amtool config routes
# 显示路由树

写完复杂 route 必跑这个验证。

看 receiver 列表

amtool config show
# 输出整个 alertmanager 配置(mask 敏感字段)

Alertmanager 配置心智模型

# /etc/alertmanager/alertmanager.yml
global:
  resolve_timeout: 5m
  smtp_smarthost: 'smtp.example.com:587'

# 模板(用于消息渲染)
templates:
  - '/etc/alertmanager/templates/*.tmpl'

# 路由树:从 root 开始匹配 → 命中 → receiver
route:
  receiver: default-email
  group_by: ['alertname', 'cluster']
  group_wait: 10s
  group_interval: 5m
  repeat_interval: 4h

  routes:
    - matchers:
        - severity=~"critical|emergency"
      receiver: pagerduty
      continue: false               # 默认不 continue
    - matchers:
        - team=infra
      receiver: slack-infra

# 接收方定义
receivers:
  - name: default-email
    email_configs:
      - to: 'oncall@example.com'

  - name: pagerduty
    pagerduty_configs:
      - service_key: 'xxx'

  - name: slack-infra
    slack_configs:
      - api_url: 'https://hooks.slack.com/...'

# 抑制规则(某 alert 触发时压制其它 alert)
inhibit_rules:
  - source_matchers: ['severity=critical']
    target_matchers: ['severity=warning']
    equal: ['alertname', 'instance']    # 同 alertname + instance 时

核心机制

  1. 分组(group_by)—— 把相同 group 的多个 alert 聚合成一个通知
  2. 抑制(inhibit)—— 某 alert 在 firing 时压制其它 alert
  3. 静默(silence)—— 临时关闭某些 alert(amtool silence add)
  4. 路由(route)—— 把 alert 分配给合适的 receiver

reload 配置

# 通过 HTTP(要启动时加 --web.enable-lifecycle)
curl -X POST http://amgr:9093/-/reload

# 或者 send SIGHUP
kubectl exec -n monitoring alertmanager-xxx-0 -- kill -HUP 1

HTTP API(用 curl 调)

# 看 alerts
curl -s http://amgr:9093/api/v2/alerts | jq

# 看 silences
curl -s http://amgr:9093/api/v2/silences | jq

# 创建 silence
curl -X POST http://amgr:9093/api/v2/silences \
  -H 'Content-Type: application/json' \
  -d '{
    "matchers": [{"name":"alertname","value":"HighMem","isRegex":false}],
    "startsAt": "2026-05-27T14:00:00Z",
    "endsAt": "2026-05-27T18:00:00Z",
    "createdBy": "alice",
    "comment": "维护"
  }'

# 删 silence
curl -X DELETE http://amgr:9093/api/v2/silence/<id>

# 看状态
curl -s http://amgr:9093/api/v2/status | jq

集群模式(HA)

生产 alertmanager 都跑 2-3 副本(防单点)。它们之间用 gossip 同步状态(silence、notification log),避免重复发:

# alertmanager Deployment args
- --cluster.listen-address=0.0.0.0:9094
- --cluster.peer=alertmanager-0.alertmanager:9094
- --cluster.peer=alertmanager-1.alertmanager:9094

kube-prometheus-stack helm 默认装 3 副本 + 自动配 peer。

看集群状态:

amtool cluster show
# Cluster Status: ready
# Peers:
#   10.244.0.5:9094
#   10.244.1.6:9094

实战场景

1. 升级集群前批量 silence

# 静默 monitoring 整个 ns 2 小时
amtool silence add namespace=monitoring \
  --duration=2h \
  --comment="K8s upgrade $(date +%F)"

# 静默 K8s 节点 ready 类告警
amtool silence add alertname=~"Kube.*NotReady|KubeletDown" \
  --duration=2h \
  --comment="rolling upgrade"

2. 误报抑制 —— 临时静默某个 noisy alert

amtool silence add alertname=DiskSpaceLow instance=worker-broken-disk \
  --duration=24h \
  --comment="盘要换、忽略告警"

3. 看哪些 alert 没人管(没静默没解决)

amtool alert --active | grep -v Silenced

4. 验证路由(写新规则后)

# 拿一个真实 alert 的 labels
kubectl exec -n monitoring alertmanager-0 -- amtool alert -o json | jq '.[0].labels'

# 测试这套 labels 会路由到哪
amtool config routes test alertname=KubeNodeNotReady severity=critical
# → infra-pagerduty

5. CI 验证 alertmanager.yml

amtool check-config alertmanager.yml || exit 1
amtool check-config alertmanager.yml --templates=templates/*.tmpl

6. 用 webhook 接收测试

写个简单的 webhook 验证 receiver 配对了:

# 临时起 webhook 服务(Python)
python3 -m http.server 8000

# alertmanager 配 receiver:
# webhook_configs:
#   - url: http://my-host:8000/alert

# 触发一个测试 alert(用 amtool)
amtool alert add alertname=Test severity=critical \
  --start="$(date -u +%FT%TZ)" \
  --annotation=summary="test alert"

amtool alert add —— 手动触发 alert

测试 alertmanager 而不是真的需要 prometheus 触发:

amtool alert add alertname=TestAlert severity=critical \
  --annotation=summary="测试告警" \
  --start="$(date -u +%FT%TZ)"

会进 alertmanager 像真 alert 一样被处理。写新 route 时验证用。


常见踩坑

坑 1:silence 创建了但 alert 还在通知

amtool silence query
# 看到 silence 在

amtool alert
# alert 还显示 active 而不是 Silenced

可能:

  • silence 的 matchers 没匹配上 alert 的 labels
  • silence 还没生效(startsAt 是未来时间)

调试:

amtool silence query <id>
# Matchers: alertname=Foo
# Starts: ...
# Ends: ...

amtool alert -o extended | grep -i foo
# 看 alert 的实际 labels —— 必须包含 silence 的全部 matchers

坑 2:notification 重复发

正常 alert 每 repeat_interval(默认 4h)会再发一次提醒。要更稀疏:

route:
  repeat_interval: 24h

或者按 severity 分:

routes:
  - matchers: [severity=critical]
    receiver: pagerduty
    repeat_interval: 30m            # critical 半小时重复
  - matchers: [severity=warning]
    receiver: slack
    repeat_interval: 12h            # warning 12 小时重复

坑 3:alertmanager HA 多个 receiver 重复发

3 个副本都在 firing alert ABC
通知发了 3 次(每个副本各发一次)

通常是 cluster gossip 没正常工作 —— --cluster.peer 没配对、或者 peer pod 网络不通。

amtool cluster show
# 应该看到所有 peer

修:检查 peer DNS / port 9094 是否通。

坑 4:路由 continue: true 反直觉

routes:
  - matchers: [severity=critical]
    receiver: pagerduty
    continue: true                   # 命中后继续匹配下面的路由
  - matchers: [severity=critical]
    receiver: slack                  # 也会发

continue: true 让 critical alert 同时发 pagerduty + slack。默认 false(命中即停)。

需要某 alert 发多个 receiver 时用,但容易翻车——通知重复看着像 bug。preferred做法:写一个 multi-channel receiver。

坑 5:amtool config show 含敏感信息

amtool config show
# 密码 / API key 显示在输出(最新版会 mask、老版不会)

不要随便公开输出。

坑 6:路由树深度

route:
  routes:
    - routes:
        - routes:
            - receiver: x          # 4 层

可以但难维护。保持路由树 ≤ 2 层。复杂条件用 matchers 而不是嵌套。

坑 7:matchers vs match / match_re 老语法

# 老写法(仍支持但不推荐)
match:
  severity: critical
match_re:
  alertname: ".*Down"

# 新写法(推荐,amgr 0.22+)
matchers:
  - severity = critical
  - alertname =~ ".*Down"

新配置全用 matchers。

坑 8:reload 没生效

curl -X POST http://amgr:9093/-/reload
# {"status":"error","errorType":"unavailable"}

没启 lifecycle API。改启动参数:

args:
  - --web.enable-lifecycle

或者发 SIGHUP:

kubectl exec -n monitoring alertmanager-0 -- kill -HUP 1

坑 9:silence 太多让 amgr 慢

amtool silence query | wc -l
# 1000+

silence 默认在状态文件里存所有历史。清理过期的:

amtool silence query expired -q | xargs -r -I {} amtool silence expire {}
# 或者 alertmanager 自己定期清(24h 后过期自动删)

关联命令

  • prometheus —— amgr 的上游
  • grafana —— grafana unified alerting 也能推 amgr
  • curl —— amgr HTTP API
  • jq —— 处理 amgr API JSON
  • helm —— kube-prometheus-stack 包含 amgr
  • kubectl —— amgr 配置在 K8s Secret / ConfigMap 里
在 GitHub 上编辑此页