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 标签命名规范(字母、数字、下划线)。命名应遵循 “组件_异常现象” 的约定,例如:

  • EtcdLeaderChangesHigh
  • APIServerConfigVersionMismatch
  • ControllerManagerHeartbeatLoss

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 告警规则生命周期

一条告警规则从定义到触发告警,经历以下状态转换:

Pending(待触发)→ Firing(触发中)→ Resolved(已解决)

当 expr 条件首次满足时,告警进入 Pending 状态;持续满足 for 指定的时间后,转换为 Firing 状态并发送通知;当条件不再满足时,告警自动进入 Resolved 状态。

告警规则生命周期状态转换 Inactive 条件不满足 Pending 条件满足,等待 for Firing 发送告警通知 Resolved 条件恢复 expr 为 true 持续 for 时间 条件恢复 返回 Inactive

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,提升排障效率