3、告警规则基础:告警规则结构
告警规则是 Prometheus 实现主动故障发现的核心载体。在控制面状态一致性场景中,告警规则负责将指标中的异常模式(如 etcd 领导者切换频繁、配置版本不一致、节点心跳超时)转化为可路由、可分级、可关联的告警事件。理解告警规则的完整结构,是编写可靠告警策略的第一步。
3.1 告警规则文件格式
Prometheus 告警规则以 YAML 格式定义,通常保存在独立的规则文件中(如 alerts.yml),并在 Prometheus 主配置中通过 rule_files 字段加载。规则文件的基本结构如下:
groups:
- name: <group_name>
interval: <evaluation_interval>
rules:
- alert: <alert_name>
expr: <promql_expression>
for: <duration>
labels:
<label_key>: <label_value>
annotations:
<annotation_key>: <annotation_value>
| 字段 | 必填 | 说明 |
|---|---|---|
groups |
是 | 规则组列表,每组包含一组逻辑相关的告警规则 |
name |
是 | 规则组名称,在 Prometheus 内部唯一标识该组 |
interval |
否 | 该组规则的评估间隔,默认继承全局 evaluation_interval |
rules |
是 | 规则列表,每条规则包含 alert、expr、for、labels、annotations |
name: control-plane-consistency),便于统一管理评估间隔和故障域隔离。
3.2 告警规则核心字段详解
3.2.1 alert:告警名称
alert 字段定义告警的唯一名称,必须符合 Prometheus 标签命名规范(字母、数字、下划线)。命名应遵循 “组件_异常现象” 的约定,例如:
EtcdLeaderChangesHighAPIServerConfigVersionMismatchControllerManagerHeartbeatLoss
3.2.2 expr:PromQL 表达式
expr 是告警规则的灵魂,它定义触发告警的条件。表达式必须返回一个瞬时向量,当向量中的样本值满足条件时,告警进入待触发状态。在控制面状态一致性场景中,常见的表达式模式包括:
# 示例1:etcd 领导者变更次数超过阈值
rate(etcd_server_leader_changes_seen_total[5m]) > 0.1
# 示例2:API Server 配置版本不一致
count by (config_hash) (apiserver_config_hash) != 1
# 示例3:控制器管理器心跳超时
time() - controller_manager_last_heartbeat_seconds > 60
3.2.3 for:持续时间
for 字段定义告警在触发前需要持续满足条件的时间长度。这是防止告警抖动(flapping)的关键机制。在控制面状态一致性场景中,建议根据故障容忍度设置合理的 for 值:
| 场景 | 推荐 for 值 | 理由 |
|---|---|---|
| etcd 领导者频繁切换 | 2m | 短期切换可能是选举正常行为,持续 2 分钟以上表明异常 |
| 配置版本不一致 | 30s | 配置同步延迟通常较短,30 秒足以区分临时抖动 |
| 节点心跳超时 | 5m | 心跳超时容忍度较高,避免网络瞬时波动触发告警 |
3.2.4 labels:附加标签
labels 用于为告警实例添加额外的元数据标签。这些标签会覆盖从指标中继承的标签,并用于告警路由、分组和静默。在控制面状态一致性场景中,常用标签包括:
severity:告警严重级别(critical、warning、info)component:故障组件(etcd、apiserver、controller-manager)cluster:集群标识
labels:
severity: critical
component: etcd
cluster: production-us-east
3.2.5 annotations:注解信息
annotations 用于提供告警的详细描述、修复建议和关联信息。与 labels 不同,annotations 不参与告警路由,主要用于告警通知的展示。推荐包含以下信息:
| 注解键 | 说明 | 示例值 |
|---|---|---|
summary |
告警摘要,一句话描述问题 | etcd 集群领导者变更频率过高 |
description |
详细描述,包含当前值和阈值 | 过去 5 分钟内领导者变更 {{ $value | humanize }} 次,阈值 0.1 |
runbook_url |
故障处理手册链接 | https://runbook.example.com/etcd-leader-changes |
annotations:
summary: "etcd 集群领导者变更频率过高"
description: "过去 5 分钟内领导者变更 {{ $value | humanize }} 次,阈值 0.1"
runbook_url: "https://runbook.example.com/etcd-leader-changes"
3.3 告警规则生命周期
一条告警规则从定义到触发告警,经历以下状态转换:
当 expr 条件首次满足时,告警进入 Pending 状态;持续满足 for 指定的时间后,转换为 Firing 状态并发送通知;当条件不再满足时,告警自动进入 Resolved 状态。
3.4 完整告警规则示例
以下是一个针对控制面状态一致性场景的完整告警规则示例,包含上述所有字段:
groups:
- name: control-plane-consistency
interval: 30s
rules:
- alert: EtcdLeaderChangesHigh
expr: rate(etcd_server_leader_changes_seen_total[5m]) > 0.1
for: 2m
labels:
severity: critical
component: etcd
annotations:
summary: "etcd 集群领导者变更频率过高"
description: "过去 5 分钟内领导者变更 {{ $value | humanize }} 次,阈值 0.1"
runbook_url: "https://runbook.example.com/etcd-leader-changes"
- alert: APIServerConfigVersionMismatch
expr: count by (config_hash) (apiserver_config_hash) != 1
for: 30s
labels:
severity: warning
component: apiserver
annotations:
summary: "API Server 配置版本不一致"
description: "检测到 {{ $value }} 个不同的配置版本哈希值"
runbook_url: "https://runbook.example.com/apiserver-config-mismatch"
expr 中使用 == 0 或 == 1 等布尔表达式时,确保返回的瞬时向量包含预期的标签维度。例如 count by (config_hash) (apiserver_config_hash) != 1 在只有一个配置版本时不会返回任何样本,因此不会触发告警——这通常是期望的行为。
3.5 告警规则结构总结
告警规则的五个核心字段各司其职,共同构成一个完整的告警定义:
| 字段 | 作用 | 控制面状态一致性场景要点 |
|---|---|---|
alert |
唯一标识告警类型 | 使用“组件_异常”命名规范,便于告警路由和分组 |
expr |
定义触发条件 | 使用 rate、count by、time() - ... 等函数检测状态不一致 |
for |
防抖动机制 | 根据故障容忍度设置 30s~5m 的持续时间 |
labels |
附加元数据 | 设置 severity、component 等标签,用于告警路由 |
annotations |
告警详情 | 包含 summary、description、runbook_url,提升排障效率 |