3. Runbook 基础概念:什么是 Runbook,手动 Runbook vs 自动化 Runbook 的对比

3.1 什么是 Runbook

Runbook(运维手册/故障响应手册)是一套标准化的操作流程文档,用于指导运维人员处理特定系统事件、故障或例行任务。在 SRE 实践中,Runbook 是保障服务可靠性的核心知识载体,它将隐性的运维经验转化为显性的、可重复执行的步骤。

核心定义:Runbook = 触发条件 + 诊断步骤 + 执行动作 + 预期结果 + 回滚方案

一个完整的 Runbook 通常包含以下要素:

要素 说明 示例
触发条件 什么告警或现象触发该 Runbook Prometheus Alert: CPUUsage > 90% 持续 5 分钟
诊断步骤 如何确认问题根因 查询 node_cpu_seconds_total 指标,按 mode 分组
执行动作 具体的修复操作 重启异常进程 / 扩容 Pod 副本数
预期结果 操作成功后的指标变化 CPU 使用率降至 60% 以下
回滚方案 操作失败或误操作时的恢复手段 回滚到上一版本 / 恢复原始副本数

3.2 手动 Runbook vs 自动化 Runbook 对比

传统的手动 Runbook 依赖人工阅读文档并逐条执行命令,而自动化 Runbook 则将流程编码为可自动触发的脚本或工作流。两者在效率、可靠性和可审计性上存在显著差异。

手动 Runbook vs 自动化 Runbook 流程对比 手动 Runbook 流程 ① 收到告警 → 查找文档 ② 人工阅读步骤 → 复制命令 ③ 手动执行 → 观察输出 ④ 人工判断 → 手动回滚 自动化 Runbook 流程 ① Prometheus 告警 → 自动触发 ② 执行预定义诊断脚本 ③ 自动修复 + 验证指标 ④ 自动回滚 + 通知结果 手动 Runbook 依赖人工阅读和判断,自动化 Runbook 由事件驱动、自动执行并反馈结果

3.3 关键维度对比表

以下从 8 个核心维度对两种 Runbook 进行系统化对比:

对比维度 手动 Runbook 自动化 Runbook
触发方式 人工收到告警后查阅文档 Prometheus Webhook 自动触发
执行速度 分钟级(查找 + 阅读 + 执行) 秒级(脚本直接执行)
错误率 高(手误、漏步骤、环境差异) 低(标准化执行,可重复验证)
可审计性 差(依赖人工记录) 强(全流程日志 + 指标记录)
知识传承 依赖个人经验,人员离职即丢失 代码化存储,团队共享
回滚能力 需人工判断并手动回滚 内置回滚逻辑,自动执行
扩展性 每新增一个系统需重写文档 模块化设计,可复用组件
与 Prometheus 集成 人工查看 Alertmanager 页面 自动拉取指标、联动告警标签

3.4 自动化 Runbook 的典型架构

在 Prometheus 生态中,自动化 Runbook 通常采用以下架构:

自动化 Runbook 与 Prometheus 联动架构 Prometheus 指标采集 + 告警规则 Alertmanager 告警路由 + 去重 + 静默 Runbook 引擎 Ansible / StackStorm / 自研 告警推送 Webhook 触发 诊断模块 查询 PromQL / 日志 / 配置 修复模块 重启 / 扩容 / 回滚 / 清理 验证模块 指标回查 / 健康检查 结果通知:Slack / 钉钉 / 邮件 + 写入 Prometheus 事件指标 反馈闭环:修复结果写入 Prometheus,更新告警状态
实践建议:在从手动 Runbook 向自动化 Runbook 迁移时,建议采用"渐进式自动化"策略——先为高频、低风险的故障场景编写自动化 Runbook,积累经验后再覆盖复杂场景。每次自动化后保留手动回退入口,确保兜底能力。

3.5 自动化 Runbook 的代码示例

以下是一个与 Prometheus 告警联动的自动化 Runbook 片段(Python + Prometheus API):

# auto_runbook_cpu_throttling.py
import requests
import json
from prometheus_api_client import PrometheusConnect

prom = PrometheusConnect(url="http://prometheus:9090", disable_ssl=True)

def diagnose_cpu_throttling(alert_labels):
    """诊断 CPU 节流问题"""
    pod = alert_labels["pod"]
    namespace = alert_labels["namespace"]

    # 查询 CPU 限流指标
    query = f'rate(container_cpu_cfs_throttled_seconds_total{{pod="{pod}",namespace="{namespace}"}}[5m])'
    result = prom.custom_query(query=query)

    if result and float(result[0]["value"][1]) > 0.1:
        return {"root_cause": "CPU 限流严重", "throttle_rate": result[0]["value"][1]}
    return {"root_cause": "非 CPU 限流问题", "throttle_rate": 0}

def auto_remediate(action, params):
    """执行自动修复"""
    if action == "increase_cpu_limit":
        # 调用 Kubernetes API 调整 CPU 资源限制
        print(f"[ACTION] 增加 CPU 限制: {params}")
        # 实际调用 k8s API 代码...
        return {"status": "success", "message": "CPU limit increased"}
    elif action == "scale_up_replicas":
        print(f"[ACTION] 扩容副本: {params}")
        return {"status": "success", "message": "Replicas scaled up"}
    return {"status": "skipped", "message": "No action taken"}

# 主流程
if __name__ == "__main__":
    # 模拟从 Alertmanager Webhook 接收的告警
    alert = {
        "labels": {"alertname": "CPUThrottlingHigh", "pod": "api-server-7d8f9", "namespace": "prod"},
        "annotations": {"summary": "Pod CPU throttling > 5%"}
    }

    diagnosis = diagnose_cpu_throttling(alert["labels"])
    print(f"[DIAGNOSIS] {diagnosis}")

    if diagnosis["root_cause"] == "CPU 限流严重":
        result = auto_remediate("increase_cpu_limit", {"pod": alert["labels"]["pod"], "new_limit": "2.0"})
        print(f"[REMEDIATION] {result}")
    else:
        print("[INFO] 无需自动修复,转人工处理")
注意事项:自动化 Runbook 必须包含"熔断机制"——当同一故障在短时间内被重复触发超过阈值(如 3 次/小时),应自动暂停自动化修复并升级到人工处理,避免陷入"修复-告警-再修复"的死循环。