Prometheus 规则与告警
本文档涵盖 Recording Rules(记录规则)、Alerting Rules(告警规则)以及 Alertmanager 告警管理——分组、抑制、静默、路由和通知。
符号说明
| 符号 | 含义 |
|---|---|
| 🚨 | 陷阱 / Pitfall |
| 💡 | 最佳实践 / Best practice |
| 🔬 | 深入原理 / Deep-dive |
| ⚡ | 性能提示 / Performance note |
1. Recording Rules 与 Alerting Rules
1.1 Recording Rules(记录规则)
作用: 将复杂/昂贵的 PromQL 查询预计算,存储为新的时间序列,加速看板查询。
groups:
- name: cpu_aggregations
interval: 60s # 可选,覆盖 global.evaluation_interval
rules:
- record: job:node_cpu_usage:avg_rate5m
expr: |
100 - avg by(job) (
rate(node_cpu_seconds_total{mode="idle"}[5m]) * 100
)
- record: instance_mode:node_cpu:rate1m
expr: sum without(cpu) (rate(node_cpu_seconds_total[1m]))
labels:
source: 'recording_rule'💡 命名规范: level:metric:operation,如 job:node_cpu_utilization:avg_rate5m。使用冒号分隔聚合级别、指标名和操作。
1.2 Alerting Rules(告警规则)
groups:
- name: application_alerts
rules:
# === 基础告警 ===
- alert: HighErrorRate
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ (sum(rate(http_requests_total[5m])) > 0)
* 100 > 5
for: 5m # 持续 5 分钟才触发(防抖动)
labels:
severity: warning
team: backend
annotations:
summary: "错误率超过 5% (当前: {{ $value | humanizePercentage }})"
description: "服务 {{ $labels.job }} 在实例 {{ $labels.instance }} 上错误率过高"
runbook_url: "https://wiki.example.com/alerts/high-error-rate"
# === 服务宕机 ===
- alert: ServiceDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "{{ $labels.job }} 在 {{ $labels.instance }} 已宕机"
# === P99 延迟过高 ===
- alert: HighP99Latency
expr: |
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service)
) > 2
for: 10m
labels:
severity: critical
annotations:
summary: "P99 延迟超过 2 秒: {{ $value }}s"
# === 磁盘空间不足 ===
- alert: LowDiskSpace
expr: |
(node_filesystem_avail_bytes{mountpoint="/"}
/ node_filesystem_size_bytes{mountpoint="/"})
* 100 < 10
for: 5m
labels:
severity: warning
annotations:
summary: "磁盘使用率超过 90%,剩余 {{ $value | humanize }}%"
# === 证书即将过期 ===
- alert: SSLCertExpiringSoon
expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 7
for: 1h
labels:
severity: warning
annotations:
summary: "SSL 证书将在 7 天内过期: {{ $labels.instance }}"1.3 规则文件关键字段
| 字段 | 说明 |
|---|---|
alert |
告警名称(alerting rules) |
record |
输出指标名(recording rules) |
expr |
PromQL 表达式 |
for |
持续多久才触发(防抖动) |
keep_firing_for |
条件恢复后继续触发多久 |
labels |
额外的分类标签(用于 Alertmanager 路由) |
annotations |
描述信息(支持 {{ $labels.xxx }}、{{ $value }} 模板语法) |
🚨 告警规则一定要加
for。 不加for会在每次短暂毛刺时都触发告警,造成严重的告警风暴。💡 规则文件加载顺序: 同一 group 内的规则顺序执行(后面的可以引用前面的结果),不同 group 并行执行。如果有依赖关系,放到同一 group 中。
⚡ 在 Recording Rules 中预聚合可以显著减少看板查询延迟,特别是跨许多实例的 Heavy 聚合查询。
1.4 验证与热加载
# 检查规则文件语法
promtool check rules /path/to/rules.yml
# 热加载(无需重启 Prometheus)
curl -X POST http://localhost:9090/-/reload2. Alertmanager 告警管理
Alertmanager 负责接收 Prometheus 发来的告警,然后进行分组、抑制、静默、路由,最终通知到人。
2.1 核心概念
Prometheus Alert → Alertmanager → [分组] → [抑制] → [静默] → [路由] → Slack/Email/PagerDuty...| 概念 | 说明 |
|---|---|
| Grouping(分组) | 将同类告警合并成一条通知,避免一次性收到 100 条相同类型的告警 |
| Inhibition(抑制) | 高优先级告警触发后,抑制相关的低优先级告警(如:节点宕机后不再发 Pod 告警) |
| Silence(静默) | 在指定时间范围内不发送特定告警(如:计划中的维护窗口) |
| Routing(路由) | 根据标签将告警分发到不同的接收者 |
2.2 alertmanager.yml 完整示例
global:
resolve_timeout: 5m # 告警恢复后多久发送 resolved 通知
smtp_smarthost: 'smtp.example.com:587'
smtp_from: 'alertmanager@example.com'
smtp_auth_username: 'alertmanager@example.com'
smtp_auth_password: 'your-password'
slack_api_url: 'https://hooks.slack.com/services/xxx'
# === 路由树 ===
route:
group_by: ['alertname', 'namespace', 'severity']
group_wait: 30s # 收到第一条告警后等多久(等后续告警一起发)
group_interval: 5m # 同组有新告警时,间隔多久发更新
repeat_interval: 4h # 告警仍在触发时,多久重发一次
receiver: 'slack-general' # 默认接收者
routes:
# 关键告警 → PagerDuty + Slack
- match:
severity: critical
receiver: 'pagerduty-critical'
group_wait: 10s
repeat_interval: 1h
continue: true # 继续匹配后续路由(同时发给 Slack)
- match:
severity: critical
receiver: 'slack-critical'
repeat_interval: 1h
# 警告 → Slack 警告频道
- match:
severity: warning
receiver: 'slack-warnings'
# 数据库相关告警 → DBA 邮件
- match_re:
service: 'postgres|mysql|redis'
receiver: 'email-dba'
continue: true
# === 接收者(通知渠道)===
receivers:
- name: 'slack-general'
slack_configs:
- channel: '#alerts-general'
send_resolved: true
title: '[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}'
text: |-
{{ range .Alerts }}
*Alert:* {{ .Annotations.summary }}
*Description:* {{ .Annotations.description }}
*Severity:* {{ .Labels.severity }}
{{ end }}
- name: 'slack-critical'
slack_configs:
- channel: '#alerts-critical'
send_resolved: true
color: '{{ if eq .Status "firing" }}danger{{ else }}good{{ end }}'
title: '🚨 {{ .CommonAnnotations.summary }}'
- name: 'pagerduty-critical'
pagerduty_configs:
- routing_key: 'your-pagerduty-integration-key'
severity: critical
description: '{{ .CommonLabels.alertname }}: {{ .CommonAnnotations.summary }}'
- name: 'email-dba'
email_configs:
- to: 'dba@example.com'
send_resolved: true
headers:
Subject: '[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}'
# === 抑制规则 ===
inhibit_rules:
# 有 critical 告警时,抑制同名 warning 告警
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'namespace']
# 节点宕机时,抑制 Pod 相关的所有告警
- source_match:
alertname: 'NodeDown'
target_match_re:
alertname: 'Pod.*'
equal: ['node']2.3 路由匹配方式
| 匹配器 | 语法 | 示例 |
|---|---|---|
| 精确匹配 | match |
severity: critical |
| 正则匹配 | match_re |
service: 'postgres|mysql' |
| 否定匹配 | matchers |
severity != info |
| 继续向下 | continue: true |
命中后继续匹配后续路由 |
2.4 时间相关参数
| 参数 | 默认值 | 意义 |
|---|---|---|
group_wait |
30s | 等多久才发第一条通知,用于收集同组新告警 |
group_interval |
5m | 同组已有告警更新时,间隔多久再发 |
repeat_interval |
4h | 告警一直触发时,间隔多久重复发 |
resolve_timeout |
5m | 告警恢复后多久发 resolved 通知 |
2.5 命令行操作
# 验证配置
amtool check-config alertmanager.yml
# 测试路由
amtool config routes test severity=critical team=backend
# 查看当前告警
amtool alert --alertmanager.url=http://localhost:9093
# 添加静默
amtool silence add --alertmanager.url=http://localhost:9093 \
'alertname=HighCPUUsage' --duration=2h --comment='计划维护'2.6 通知渠道汇总
| 渠道 | 配置块 | 关键参数 |
|---|---|---|
| Slack | slack_configs |
channel, api_url, send_resolved |
email_configs |
to, send_resolved, headers |
|
| PagerDuty | pagerduty_configs |
routing_key, severity |
| OpsGenie | opsgenie_configs |
api_key, priority |
| 企业微信 | wechat_configs |
corp_id, api_secret |
| Webhook | webhook_configs |
url, send_resolved |
| VictorOps | victorops_configs |
api_key, routing_key |
参考资料: