3. Runbook 基础:定义、场景与编写规范

Runbook(运行手册)是运维和SRE领域的核心文档化实践,它将可重复的操作流程从“人脑记忆”转化为“标准化可执行程序”。在CI/CD流水线中,Runbook是连接自动化触发与人工干预的桥梁,确保故障恢复和变更执行的一致性与可审计性。

3.1 什么是Runbook

Runbook是一份结构化的操作文档,详细描述了在特定运维场景下(如服务宕机、部署失败、配置变更)需要执行的一系列步骤、检查点、回退方案和预期结果。它不仅仅是操作清单,更是知识沉淀和自动化脚本的入口。

维度 传统运维笔记 标准化Runbook
结构 自由文本,无固定格式 模板化,包含元数据、前置条件、步骤、回退
可执行性 依赖个人经验解读 步骤清晰,可被新手或自动化工具直接执行
版本控制 通常无版本管理 纳入Git仓库,每次变更可追溯
与CI/CD联动 无 可通过Webhook或API被流水线触发
审计 无执行记录 每次执行自动记录日志、耗时、操作人
核心价值: Runbook将运维操作从“英雄主义”转变为“工程化流程”,降低MTTR(平均修复时间),消除单点故障风险。

3.2 Runbook的典型场景

Runbook在CI/CD流水线中主要服务于两大核心场景:故障恢复和变更执行。下面通过两个独立的结构图来展示其典型流程。

3.2.1 场景一:故障恢复

当监控系统或CI/CD流水线检测到服务异常时,自动触发对应的故障恢复Runbook。该Runbook指导操作员或自动化系统执行诊断、隔离、恢复和验证步骤。

故障恢复Runbook典型流程 1. 告警触发 2. 诊断与影响评估 3. 执行恢复操作 4. 验证恢复状态 5. 事后复盘与更新 关键检查点: • 是否影响数据库? • 是否需要回滚版本? • 是否有临时规避方案? • 是否通知了相关方?
最佳实践: 故障恢复Runbook应包含明确的“决策树”或“条件分支”。例如:“如果步骤3执行失败,则跳转到步骤3.1(回退方案)”,避免操作员在高压下做出错误判断。

3.2.2 场景二:变更执行

变更执行Runbook用于标准化CI/CD流水线中的发布、配置更新、扩缩容等操作。它确保每次变更都遵循相同的审批、执行和验证流程,降低人为失误。

变更执行Runbook典型流程 1. 变更请求提交 2. 自动/人工审批 3. 灰度发布 4. 全量发布 5. 回滚操作 6. 健康检查验证 验证失败 验证通过 变更执行Runbook关键要素: • 明确的变更窗口(Change Window)和冻结期。 • 每一步的预期输出和验证命令(如 curl 健康检查端点)。 • 明确的回滚触发条件和回滚脚本入口。

3.3 Runbook的编写规范

高质量的Runbook需要遵循统一的编写规范,以确保可读性、可执行性和可维护性。以下是推荐的Runbook结构模板和编写原则。

3.3.1 标准Runbook模板结构

章节 内容要求 示例
元数据 名称、ID、版本、所有者、创建日期、标签 name: "数据库主从切换"
version: "2.1.0"
owner: "sre-team"
触发条件 明确什么事件会启动此Runbook “当数据库主库延迟 > 5秒 或 主库宕机”
前置条件 执行前必须满足的环境或权限要求 “操作员需拥有DBA角色权限;已确认从库数据同步正常”
步骤列表 有序的操作指令,包含命令、预期输出、检查点 “步骤1:执行 mysql -e 'STOP SLAVE'”
回退方案 当步骤失败时的替代路径或回滚命令 “若步骤3失败,执行 mysql -e 'START SLAVE' 回退”
验证方法 如何确认操作成功完成 “执行 mysql -e 'SHOW SLAVE STATUS\G' 确认 IO/SQL 线程为 Yes”
通知与升级 操作完成后通知谁,失败时升级给谁 “成功:通知 @oncall;失败:升级至 @sre-lead”

3.3.2 编写原则

  • 原子性: 每个步骤只做一件事,避免“组合拳”式的大步骤。例如,将“停止服务并备份数据库”拆分为“步骤1:停止服务”和“步骤2:执行数据库备份”。
  • 可测试性: 每个步骤都应包含明确的“预期输出”或“验证命令”。操作员执行后能立即判断步骤是否成功。
  • 幂等性: 尽可能设计为可重复执行而不产生副作用。例如,使用 CREATE TABLE IF NOT EXISTS 而非 CREATE TABLE。
  • 版本化: Runbook必须与代码一样纳入Git版本管理,每次变更都需经过Pull Request审查。
  • 自动化优先: 如果某个步骤可以写成脚本,则应在Runbook中直接嵌入脚本或指向自动化Job的链接,减少人工输入。
常见反模式: 避免在Runbook中出现“请联系XX同事获取密码”或“根据经验调整参数”等模糊描述。所有依赖项和参数必须显式声明。

3.3.3 代码示例:Runbook中的步骤定义

以下是一个Runbook步骤的YAML定义示例,展示了如何将步骤、验证和回退结构化。

# runbooks/db-failover.yaml
name: "数据库主从故障切换"
version: "2.1.0"
trigger: "主库健康检查连续3次失败"

steps:
  - id: "step-1"
    description: "确认从库状态"
    command: "mysql -h slave-host -e 'SHOW SLAVE STATUS\G'"
    expected_output: "Slave_IO_Running: Yes; Slave_SQL_Running: Yes"
    on_failure: "升级至DBA团队,中止Runbook"

  - id: "step-2"
    description: "将从库提升为新主库"
    command: "mysql -h slave-host -e 'STOP SLAVE; RESET SLAVE ALL;'"
    expected_output: "Query OK"
    on_failure:
      rollback_command: "mysql -h slave-host -e 'START SLAVE;'"
      rollback_note: "如果提升失败,重新启动从库复制"

  - id: "step-3"
    description: "验证新主库可写"
    command: "mysql -h slave-host -e 'CREATE TABLE test.health (id INT); DROP TABLE test.health;'"
    expected_output: "Query OK"
    on_failure: "触发回滚Runbook v2.0.0"

rollback:
  - id: "rollback-1"
    description: "将原主库恢复为从库"
    command: "mysql -h original-master -e 'CHANGE MASTER TO ...; START SLAVE;'"