← 返回文章列表
Grafana 可视化与 Alertmanager 告警实战
23 分钟阅读
字号
Grafana 可视化与 Alertmanager 告警实战
本文介绍 Grafana 出图配置、Alertmanager 告警机制、告警优化策略,以及钉钉 webhook 集成。
一、Grafana 出图
1.1 官方资源
| 资源 | 地址 |
|---|---|
| Grafana 官网 | https://grafana.com/ |
| Docker 镜像 | https://hub.docker.com/r/grafana/grafana/ |
| Dashboard 模板 | https://grafana.com/grafana/dashboards/ |
1.2 推荐模板 ID
| Exporter | 模板 ID | 说明 |
|---|---|---|
| node_exporter | 8919、1860、15172(基于 11074 优化) | 主机监控(CPU、内存、磁盘、网络) |
| redis_exporter | 14615 | Redis 监控 |
| mysqld_exporter | 7362、11323 | MySQL 监控 |
| mysqld_exporter(主从) | 11323 | 主从复制专项监控 |
| mariadb_exporter | 13106 | MariaDB 监控 |
| haproxy_exporter | 367、2428 | HAProxy 监控 |
| nginx_exporter | 14900 | Nginx 监控 |
| blackbox_exporter | 7587 | HTTP/TCP/ICMP 探测 |
| jmx_exporter | 8563 | Java JVM 监控 |
| postgres_exporter | 9628 | PostgreSQL 监控 |
1.3 导入 Dashboard 模板
- 登录 Grafana → 点击左侧
+→ Import - 输入模板 ID(如 8919)→ 点击 Load
- 选择数据源(Prometheus)→ 点击 Import
- 模板自动生成对应监控面板
1.4 常用 PromQL 示例
CPU 使用率
# 方法一:基于 idle 计算(非idle时间 / 总时间)
(1 - sum(increase(node_cpu_seconds_total{mode="idle", instance=~"node01"}[1m])) by (instance)
/
sum(increase(node_cpu_seconds_total{instance=~"node01"}[1m])) by (instance)
) * 100
# 方法二:直接用 mode!="idle"(更简洁)
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle", instance=~"node01"}[5m]))) * 100内存使用率
# 已用内存 / 总内存
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100磁盘使用率
# 根分区使用率
100 - (node_filesystem_avail_bytes{mountpoint="/", instance=~"node01"} / node_filesystem_size_bytes{mountpoint="/", instance=~"node01"}) * 100
# 特定分区
100 - (node_filesystem_avail_bytes{mountpoint="/data", instance=~"node01"} / node_filesystem_size_bytes{mountpoint="/data", instance=~"node01"}) * 100网络流量
# 入方向流量(按字节)
sum by (instance) (rate(node_network_receive_bytes_total{instance=~"node01"}[5m]))
# 出方向流量
sum by (instance) (rate(node_network_transmit_bytes_total{instance=~"node01"}[5m]))Pod CPU 使用率(cAdvisor)
# Pod CPU 使用率 = Pod 实际 CPU / Node 总 CPU
sum by (pod) (rate(container_cpu_usage_seconds_total{name=~".+"}[5m])) by (pod)
/
count by (pod) (machine_cpu_cores{name=~".+"})
* 1001.5 Grafana 变量
Dashboard 模板中常用变量实现动态筛选:
| 变量 | 用途 | 示例 |
|---|---|---|
$instance | 选择主机 | node_cpu_seconds_total{instance=~"$instance"} |
$service | 选择服务 | up{job=~"$service"} |
$bucket | 选择 Histogram 分桶 | node_network_receive_bytes_bucket{instance=~"$instance"} |
设置方式:Dashboard → Settings → Variables → Add variable
1.6 如何知道有哪些指标
方法一:Prometheus Web UI
访问 http://localhost:9090/graph,点 "Insert Metric" 下拉菜单,可以看到所有指标名。
方法二:查询所有指标名
# 查看所有指标(只看名字,不看数据)
{__name__=~".+"}方法三:命令行查看
# 直接调 Prometheus API 获取所有指标名
curl http://localhost:9090/api/v1/label/__name__/values方法四:查 Exporter 文档
每个 Exporter 官方文档会列出所有导出的指标:
| Exporter | 文档地址 |
|---|---|
| node_exporter | https://github.com/prometheus/node_exporter |
| mysqld_exporter | https://github.com/prometheus/mysqld_exporter |
| redis_exporter | https://github.com/oliver006/redis_exporter |
| blackbox_exporter | https://github.com/prometheus/blackbox_exporter |
1.7 常用指标名汇总
不用死记,看到名字能猜出意思即可。
node_exporter(主机监控)
# CPU
node_cpu_seconds_total # CPU 时间(mode: idle/user/sys/idle)
# 内存
node_memory_MemAvailable_bytes # 可用内存
node_memory_MemTotal_bytes # 总内存
node_memory_MemFree_bytes # 空闲内存
# 磁盘
node_filesystem_size_bytes # 磁盘总大小
node_filesystem_avail_bytes # 可用磁盘
# 网络
node_network_receive_bytes_total # 接收字节
node_network_transmit_bytes_total # 发送字节
# 负载
node_load1 / node_load5 / node_load15 # 系统负载cAdvisor(容器监控)
container_cpu_usage_seconds_total # 容器 CPU
container_memory_usage_bytes # 容器内存
container_network_receive_bytes_total # 容器网络入
container_network_transmit_bytes_total # 容器网络出自定义应用指标
通过 Prometheus Client 暴露,常见模式:
http_requests_total # HTTP 请求总数(标签:status, handler, method)
http_request_duration_seconds # 请求延迟
order_count_total # 订单数(业务自定义)
payment_amount_sum # 支付金额(业务自定义)1.8 PromQL 入门基础
数据模型
每条数据叫时序数据,格式:
node_cpu_seconds_total{mode="idle", instance="node01", job="node_exporter"} 0.85
↑ ↑
标签 值基础查询
# 1. 查指标名(查所有数据)
node_cpu_seconds_total
# 2. 加标签筛选
node_cpu_seconds_total{mode="idle"}
# 3. 正则匹配(=~ 开头)
node_cpu_seconds_total{instance=~"node.*"}
# 4. 组合条件
node_cpu_seconds_total{mode="idle", instance=~"node.*"}核心函数
| 函数 | 作用 | 例子 |
|---|---|---|
rate() | 计算速率(最常用) | rate(http_requests_total[5m]) |
irate() | 即时速率(波动大时用) | irate(http_requests_total[5m]) |
increase() | 增长量 | increase(http_requests_total[1h]) |
sum() | 求和 | sum(rate(http_requests_total[5m])) |
avg() | 平均值 | avg by (job)(rate(...)) |
histogram_quantile() | 分位数 | histogram_quantile(0.99, ...) |
为什么需要 rate()
# 错误:直接查是累计值,没意义(永远是增长的)
node_cpu_seconds_total
# 正确:算每秒增长多少
rate(node_cpu_seconds_total{mode="idle"}[5m])[5m] = 取最近 5 分钟的数据来算
聚合
# 求和
sum(node_cpu_seconds_total)
# 按 instance 分组求平均
avg by (instance) (node_cpu_seconds_total{mode="idle"})常用公式
# CPU 使用率
(1 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m]))) * 100
# 内存使用率
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# 磁盘使用率
100 - (node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100
# QPS 每秒请求数
sum by (status) (rate(http_requests_total[5m]))
# P99 延迟
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))1.9 学习建议
- 先会用 Grafana — Grafana 的 Explore 页面可以写 PromQL 查数据,看结果
- 记住 3 个公式 — CPU、内存、磁盘使用率
- 多练习 — 拿真实数据自己写,写多了就熟了
二、Alertmanager 告警机制
2.1 官方资源
| 资源 | 地址 |
|---|---|
| 二进制包 | https://github.com/prometheus/alertmanager/releases |
| 官方文档 | https://prometheus.io/docs/alerting/configuration/ |
2.2 告警三种状态
┌─────────────────────────────────────────────────────────┐
│ 告警生命周期 │
├─────────────────────────────────────────────────────────┤
│ │
│ inactive ──────► pending ──────► firing │
│ │ │ │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ 条件不满足 条件首次满足 持续超过 for │
│ 或从未触发 但未达 for 时长 时长,发送通知 │
│ │
└─────────────────────────────────────────────────────────┘| 状态 | 含义 | 动作 |
|---|---|---|
| inactive | 告警条件不满足,或从未触发过 | 不做任何事 |
| pending | 条件满足但持续时间不足 for 阈值 | 等待中,不发通知 |
| firing | 条件满足且持续超过 for 阈值 | 发送告警到 Alertmanager |
2.3 状态转换详解
以"内存使用率 > 80%"告警为例,for 设置为 2 分钟:
时间轴:
0min ─────────────────────────────────────────────────────►
告警条件:内存使用率 > 80%
0:00 ─ 内存使用率首次超过 80%
│
▼
pending(等待 2 分钟)
0:00 - 2:00 ─ 内存使用率持续超过 80%
│
├─ 如果在 2:00 前恢复正常 → inactive(从未触发过)
│
└─ 持续到 2:00 仍超标 → firing(发送告警)
2:00 ─ 发送邮件/钉钉通知
│
▼
firing(持续告警,每 repeat_interval 重复发送)
│
▼
内存恢复正常 2 分钟后 → inactive(发送恢复通知)2.4 Prometheus 告警规则配置
groups:
- name: node_alerts # 告警组名
interval: 30s # 评估间隔
rules:
# 告警实例:节点宕机
- alert: NodeDown
expr: up{job="node_exporter"} == 0
for: 1m # 宕机 1 分钟后才触发
labels:
severity: critical
team: infra
annotations:
summary: "节点 {{ $labels.instance }} 已宕机"
description: "{{ $labels.instance }} 已经宕机超过 1 分钟"
# 告警实例:内存使用率高
- alert: HighMemoryUsage
expr: (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 80
for: 2m # 持续 2 分钟
labels:
severity: warning
annotations:
summary: "内存使用率过高:{{ $value }}%"
description: "节点 {{ $labels.instance }} 内存使用率已超过 80%"
# 告警实例:磁盘空间不足
- alert: DiskWillFillIn4Hours
expr: (node_filesystem_size_bytes - node_filesystem_avail_bytes) / node_filesystem_size_bytes > 0.9
for: 1h # 持续 1 小时才告警(避免临时波动)
labels:
severity: warning
annotations:
summary: "磁盘将在 4 小时内用尽"
description: "节点 {{ $labels.instance }} 磁盘使用率:{{ $value | humanizePercentage }}"2.5 Alertmanager 安装
# 下载(选择对应版本)
wget https://github.com/prometheus/alertmanager/releases/download/v0.27.0/alertmanager-0.27.0.linux-amd64.tar.gz
tar -xzf alertmanager-0.27.0.linux-amd64.tar.gz
mv alertmanager-0.27.0.linux-amd64 /usr/local/alertmanager
# 目录结构
/usr/local/alertmanager/
├── alertmanager # 主程序
├── amtool # 命令行工具
├── alertmanager.yml # 配置文件
└── data/ # 数据目录(存储 silence 等)2.6 Alertmanager 系统服务
# /lib/systemd/system/alertmanager.service
[Unit]
Description=Alertmanager
After=network.target
[Service]
ExecStart=/usr/local/alertmanager/alertmanager \
--config.file=/usr/local/alertmanager/alertmanager.yml \
--storage.path=/usr/local/alertmanager/data \
--web.listen-address=:9093
Restart=on-failure
[Install]
WantedBy=multi-user.targetsystemctl daemon-reload
systemctl enable --now alertmanager2.7 Alertmanager 配置详解
# alertmanager.yml
global:
resolve_timeout: 5m # 告警恢复后多久标记为 resolved
# 模板配置
templates:
- '/etc/alertmanager/template/*.tmpl'
# 路由树
route:
# 根路由:所有告警先到这里
receiver: 'default-receiver'
group_by: ['alertname', 'cluster', 'namespace'] # 按这些标签分组
group_wait: 30s # 等待 30s 收集同组告警,再发送
group_interval: 5m # 同组告警的发送间隔
repeat_interval: 4h # 重复告警间隔(避免告警疲劳)
# 子路由:根据 severity 分发到不同 receiver
routes:
# severity=critical 立即发送,不等待
- match:
severity: critical
receiver: 'critical-receiver'
group_wait: 0s
continue: true # 继续匹配后续路由(可选)
- match:
severity: warning
receiver: 'warning-receiver'
# 路由匹配流程
# 1. 告警进入根路由,按 group_by 分组
# 2. 遍历子路由,找到第一个匹配的
# 3. 如果 continue: true,继续匹配后续路由
# 4. 无匹配则使用根路由的 receiver
# 接收者配置
receivers:
- name: 'default-receiver'
email_configs:
- to: 'ops@example.com'
send_resolved: true
headers:
subject: '[{{ status }}] {{ .GroupLabels.alertname }}'
- name: 'critical-receiver'
pagerduty_configs:
- service_key: 'YOUR_SERVICE_KEY'
severity: critical
- name: 'warning-receiver'
webhook_configs:
- url: 'http://localhost:8060/dingtalk/webhook1/send'
send_resolved: true
# 抑制规则
inhibit_rules:
- source_match:
alertname: 'NodeDown'
target_match_re:
alertname: 'ServiceDown|DiskIOHigh|NetworkDown'
equal: ['instance']2.8 路由 continue 参数
continue: true 让告警继续匹配后续路由:
route:
receiver: 'default-receiver'
routes:
# 匹配 severity=critical,继续匹配
- match:
severity: critical
receiver: 'email-receiver'
continue: true
# 继续匹配 alertname
- match:
alertname: 'NodeDown'
receiver: 'critical-receiver'
# 所有匹配不到的一直流到 default-receiver三、告警优化策略
告警杂乱且频繁是生产环境常见痛点,解决方案分四层:
3.1 第一层:Prometheus 规则优化
for 的作用
for 是最容易忽视但最重要的参数:
# 没有 for:条件一满足立即触发(容易误报)
- alert: HighMemory
expr: memory_usage > 80
# 没有 for
# 有 for:持续 5 分钟才触发(更稳定)
- alert: HighMemory
expr: memory_usage > 80
for: 5m阈值优化
根据真实业务调整阈值,避免过于敏感:
# 过于敏感:每次高峰都触发
- alert: HighCPU
expr: cpu_usage > 70
# 更合理:根据业务峰谷调整
- alert: HighCPU
expr: cpu_usage > 85 # 非高峰期 70 足够多条件组合
# 单一条件容易误报
- alert: HighMemory
expr: memory_usage > 80
# 组合条件:内存高 + 磁盘 swap 高(更精确)
- alert: HighMemoryAndSwap
expr: memory_usage > 80 AND (node_memory_SwapTotal_bytes - node_memory_SwapFree_bytes) / node_memory_SwapTotal_bytes > 0.5
for: 3m3.2 第二层:Alertmanager 分组合并
为什么需要分组合并
假设某服务有 10 个 Pod 同时重启,会产生 10 条告警。如果不合并:
❌ 未合并:收到 10 条独立告警
- [NodeDown] instance-1 已宕机
- [NodeDown] instance-2 已宕机
- [NodeDown] instance-3 已宕机
...(刷屏)
✅ 已合并:只收到 1 条告警
- [NodeDown] 3 个节点已宕机 (instance-1, instance-2, instance-3)分组合并配置
route:
# 按 alertname + cluster 分组
# 同一组内的告警会被合并为一条
group_by: ['alertname', 'cluster', 'namespace']
# 等待 30 秒收集同组告警
# 30 秒内新产生的同组告警会合并到同一条里
group_wait: 30s
# 发送后,再过 5 分钟有新告警才会再发送
group_interval: 5m
# 同一个告警恢复后 4 小时再发送重复告警
repeat_interval: 4h实际效果
| 场景 | group_wait=30s | 无合并 |
|---|---|---|
| 10 个 Pod 同时重启 | 30s 后收到 1 条合并告警 | 立即收到 10 条 |
| 告警持续未恢复 | 每 4h 重复一次 | 每 5m 重复一次(告警风暴) |
3.3 第三层:抑制(Inhibition)
什么是抑制
当某个告警触发时,自动压制与其相关的一些告警。
典型场景:节点宕机
节点 instance-1 宕机
│
├─► [NodeDown] instance-1 已宕机 ← 根因告警(保留)
├─► [ServiceDown] nginx on instance-1 ← 伴随告警(抑制)
├─► [ServiceDown] mysql on instance-1 ← 伴随告警(抑制)
└─► [DiskIOHigh] disk on instance-1 ← 伴随告警(抑制)抑制配置
inhibit_rules:
# 当 NodeDown 触发时,抑制同 instance 的 ServiceDown
- source_match:
alertname: 'NodeDown'
target_match_re:
alertname: 'ServiceDown|DiskIOHigh|NetworkDown'
equal: ['instance'] # instance 标签相同的才抑制
# 注意:抑制规则只看你配置的 source_match/target_match 和 equal 标签
# 不自动比较 severity 高低抑制原理
Alertmanager 收到告警:
│
▼
┌──────────────────┐
│ 检查 inhibition │
│ rules │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ source_match │──否──► 发送告警
│ 满足? │
└────────┬─────────┘
│是
▼
┌──────────────────┐
│ 查找同 equal 标签 │
│ 的被抑制告警 │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 标记为 inhibited │──► 不发送,仅保留记录
│ 不发送 │
└──────────────────┘3.4 第四层:静默(Silence)
什么是静默
在特定时间段内,让某些告警"闭嘴"。
典型场景
| 场景 | 效果 |
|---|---|
| 凌晨 2-4 点定期维护 | 维护窗口内不发告警 |
| 已知问题处理中 | 问题处理期间不重复发告警 |
| 业务低峰期 | 临时提高阈值,静默低优先级告警 |
使用方式
两种方式:
方式一:Alertmanager Web UI
http://localhost:9093/#/silences
→ Create silence
→ 输入匹配条件(alertname=xxx, instance=yyy)
→ 设置起始和结束时间
→ 提交方式二:amtool 命令行
# 创建静默
amtool silence create \
--alertname=HighMemoryUsage \
--instance=node01 \
--start=2024-01-15T02:00:00+08:00 \
--end=2024-01-15T04:00:00+08:00 \
--reason="凌晨维护窗口"
# 查询静默
amtool silence query
# 删除静默
amtool silence expire <silence-id>3.5 告警模板定制
默认模板问题
Alertmanager 默认发送的告警信息冗长,包含大量 Prometheus 自动添加的元数据,不利于快速阅读。
模板示例
// /etc/alertmanager/template/default.tmpl
{{ define "dingtalk.title" }}
{{ if eq .Status "firing" }}🔴 【告警】{{ .GroupLabels.alertname }}{{ else }}✅ 【恢复】{{ .GroupLabels.alertname }}{{ end }}
{{ end }}
{{ define "dingtalk.content" }}
{{ if eq .Status "firing" }}
告警级别:{{ .Labels.severity }}
{{ end }}
{{ range .Alerts }}
实例:{{ .Labels.instance }}
详情:{{ .Annotations.description }}
开始时间:{{ .StartsAt.Format "2006-01-02 15:04:05" }}
{{ if eq .Status "resolved" }}恢复时间:{{ .EndsAt.Format "2006-01-02 15:04:05" }}{{ end }}
{{ end }}
{{ end }}钉钉效果
🔴 【告警】HighMemoryUsage
告警级别:warning
实例:node01
详情:内存使用率超过 80%,当前值 86.5%
开始时间:2024-01-15 10:30:003.6 Recording Rule 性能优化
问题背景
假设有 5 个告警规则都用了同一个表达式:
# 每个规则都重复计算同一表达式
- alert: HighCPU1
expr: rate(node_cpu_seconds_total{instance="node01"}[5m]) * 100 > 80
- alert: HighCPU2
expr: rate(node_cpu_seconds_total{instance="node01"}[5m]) * 100 > 85
- alert: HighCPU3
expr: rate(node_cpu_seconds_total{instance="node01"}[5m]) * 100 > 90Prometheus 每 15 秒评估一次,每次都重复计算 3 次同一表达式。
解决:提取为 Recording Rule
groups:
- name: node_recording_rules
rules:
# 预先计算结果,存为新指标
- record: instance:node_cpu_usage:avg_rate5m
expr: |
avg by (instance) (
rate(node_cpu_seconds_total{mode!="idle"}[5m])
) * 100
- name: node_alerts
rules:
# 直接复用预计算结果,不再重复计算
- alert: HighCPU
expr: instance:node_cpu_usage:avg_rate5m > 80
for: 2m效果对比
| 指标 | 无 Recording Rule | 有 Recording Rule |
|---|---|---|
| 每轮计算次数 | 3 次(每条规则一次) | 1 次(预先算好) |
| CPU 开销 | 高 | 低 |
| 适用场景 | 指标少 | 指标多、大规模集群 |
四、钉钉 Webhook 集成
4.1 整体架构
┌─────────────────────────────────────────────────────────┐
│ 钉钉告警架构 │
├─────────────────────────────────────────────────────────┤
│ │
│ Prometheus Server │
│ │ │
│ │ 告警规则触发 │
│ ▼ │
│ Alertmanager ────────────────────────────────────────►│
│ │ │
│ │ webhook │
│ ▼ │
│ prometheus-webhook-dingtalk │
│ (中间件:转换格式 + 签名验证) │
│ │ │
│ │ HTTPS + 签名 │
│ ▼ │
│ 钉钉群机器人 │
│ │ │
│ ▼ │
│ 群成员收到通知 🔔 │
│ │
└─────────────────────────────────────────────────────────┘4.2 钉钉群配置步骤
第一步:创建群聊
- 打开钉钉 → 新建群聊
- 至少添加 2 人(钉钉规则)
- 设置群名,如"运维告警群"
第二步:添加机器人
- 进入群设置 → 智能群助手 → 添加机器人
- 选择"自定义机器人"
- 填写机器人名称(如 prometheus-alert)
- 安全设置:勾选"加签",钉钉会生成 secret
- 点击完成,获得
access_token和secret
访问地址:https://oapi.dingtalk.com/robot/send?access_token=xxxxx
签名密钥:SECxxxxxxxxxxxxxxxxxxxxxxxxxxxxx4.3 部署 prometheus-webhook-dingtalk
下载安装
# 下载(注意选择正确版本,linux-amd64)
wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v2.1.0/prometheus-webhook-dingtalk-2.1.0.linux-amd64.tar.gz
# 解压
tar -xzf prometheus-webhook-dingtalk-2.1.0.linux-amd64.tar.gz
mv prometheus-webhook-dingtalk-2.1.0.linux-amd64 /usr/local/prometheus-webhook-dingtalk配置文件
# /usr/local/prometheus-webhook-dingtalk/config.yml
# 可以在一个配置文件里定义多个 target
targets:
# 基础 webhook(不 @ 任何人)
webhook1:
url: https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN
secret: YOUR_SECRET
# @所有人
webhook_mention_all:
url: https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN
secret: YOUR_SECRET
mention:
all: true
# @指定人员(填手机号)
webhook_mention_users:
url: https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN
secret: YOUR_SECRET
mention:
mobiles:
- '18611453110'
- '13800138000'系统服务
# /lib/systemd/system/dingtalk.service
[Unit]
Description=Prometheus DingTalk Webhook
Documentation=https://github.com/timonwong/prometheus-webhook-dingtalk
After=network.target
[Service]
Type=simple
Restart=on-failure
RestartSec=5s
WorkingDirectory=/usr/local/prometheus-webhook-dingtalk
ExecStart=/usr/local/prometheus-webhook-dingtalk/prometheus-webhook-dingtalk \
--web.listen-address=0.0.0.0:8060 \
--config.file=/usr/local/prometheus-webhook-dingtalk/config.yml
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.targetsystemctl daemon-reload
systemctl enable --now dingtalk
systemctl status dingtalk验证
# 测试 webhook 是否正常
curl -X POST 'http://localhost:8060/dingtalk/webhook1/send' \
-H 'Content-Type: application/json' \
-d '{"msgtype": "text", "text": {"content": "测试消息"}}'4.4 Alertmanager 对接
# alertmanager.yml
global:
resolve_timeout: 5m
templates:
- '/etc/alertmanager/template/*.tmpl'
route:
receiver: 'dingtalk-webhook'
group_by: ['alertname', 'cluster']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
receivers:
- name: 'dingtalk-webhook'
webhook_configs:
# 对接多个 target
- url: 'http://localhost:8060/dingtalk/webhook1/send'
send_resolved: true # 告警恢复时也发送通知
- url: 'http://localhost:8060/dingtalk/webhook_mention_all/send'
send_resolved: false # 恢复通知不发 @all
inhibit_rules: []4.5 自定义钉钉模板
// /etc/alertmanager/template/dingtalk.tmpl
{{ define "dingtalk.markdown" }}
## {{ if eq .Status "firing" }}🔴 告警{{ else }}✅ 恢复{{ end }}
**告警名称**:{{ .GroupLabels.alertname }}
{{ range .Alerts }}
**级别**:{{ .Labels.severity }}
**实例**:{{ .Labels.instance }}
**描述**:{{ .Annotations.description }}
**时间**:{{ .StartsAt.Format "2006-01-02 15:04:05" }}
{{ end }}
{{ end }}在 config.yml 中指定使用该模板:
targets:
webhook1:
url: https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN
secret: YOUR_SECRET
mention:
all: false
# 指定模板文件
templates:
- '/etc/alertmanager/template/dingtalk.tmpl'五、完整配置示例
prometheus.yml 中启用 alertmanager
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
- localhost:9093
rule_files:
- '/etc/prometheus/rules/*.yml'目录结构
/etc/prometheus/
├── prometheus.yml
├── alertmanager.yml
├── rules/
│ ├── node_alerts.yml
│ └── service_alerts.yml
└── template/
└── dingtalk.tmpl
/usr/local/
├── prometheus-webhook-dingtalk/
│ ├── prometheus-webhook-dingtalk
│ └── config.yml检查配置
# 检查 Prometheus 规则语法
promtool check rules /etc/prometheus/rules/*.yml
# 检查 Alertmanager 配置
amtool check-config /etc/alertmanager/alertmanager.yml
# 重新加载 Alertmanager(不重启)
curl -X POST http://localhost:9093/-/reload六、总结
整体架构
┌─────────────────────────────────────────────────────────┐
│ Prometheus │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 告警规则(rule_files):什么情况算告警 │ │
│ │ - expr: cpu > 80 │ │
│ │ - for: 2m │ │
│ │ - labels: severity: critical │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ │ firing │
│ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Alertmanager:触发后怎么处理 │ │
│ │ ├─ route + receiver:发给谁 │ │
│ │ ├─ group_by:怎么合并 │ │
│ │ ├─ inhibit_rules:怎么压制 │ │
│ │ └─ silence:怎么静默 │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 邮件 / 钉钉 / Slack │
└─────────────────────────────────────────────────────────┘四个核心概念
| 概念 | 作用 | 解决什么问题 |
|---|---|---|
| route + receiver | 告警发给谁 | critical 发电话,warning 发邮件 |
| group_by | 告警怎么合并 | 10个Pod重启 → 1条告警 |
| inhibit_rules | 告警怎么压制 | 节点宕机时只发1条,不发服务告警 |
| silence | 告警怎么静默 | 维护期间不发 |
告警状态
inactive → pending → firing
│ │ │
│ │ └─ 发送通知
│ └─ 等待 for 时长
└─ 条件不满足PromQL 语法注意
# CPU 使用率(注意括号位置)
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m]))) * 100
# 内存使用率
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# 磁盘使用率
100 - (node_filesystem_avail_bytes / node_filesystem_size_bytes) * 100常用命令
# Prometheus 端
promtool check rules /etc/prometheus/rules/*.yml # 检查规则语法
# Alertmanager 端
amtool check-config /etc/alertmanager/alertmanager.yml # 检查配置
amtool silence query # 查看静默
amtool silence add --alertname=HighCPU --instance=node01 # 创建静默
curl -X POST http://localhost:9093/-/reload # 重载配置分享