Runbook 编写
让 Agent 把告警、仪表盘与 CLI 查询串成逐步指令,包含前置权限、预期输出与「何时停手升级」的明确阈值;禁止臆造指标名或集群上下文。
开篇写服务范围、依赖与维护窗口;每一步命令可复制粘贴,并注明只读 vs 有副作用操作。与相关 playbook、dashboard 深链减少上下文切换。
在 SKILL 中若信息不足,输出「需确认」占位而非编造;常见误报与快速排除路径单独成节,便于 on-call 在压力下跳过无关分支。
范围、依赖与读者
标明本 runbook 覆盖的组件、环境(prod/stage)、数据面与控制面边界;列出必读权限(只读角色、break-glass 账号是否允许)与维护窗口说明。
完整 Runbook 模板头部(每个 Runbook 必须包含):
# Runbook: 数据库连接池耗尽
**服务**: payment-svc (prod, k8s/ns: payments)
**版本**: v3 — 最后更新: 2024-03-20 by @sre-alice
**所有者**: SRE Team (PagerDuty: pd.link/payment-sre)
**触发告警**: PaymentDB_PoolExhausted / PaymentAPI_HighErrorRate
## 读者与权限
- **L1 on-call**: 只读权限足够执行诊断步骤
- **L2 专家**: 需要 payment-admin 角色执行缓解步骤
- **管理层通知**: 影响 >5% 用户或持续 >30min 时通知 @eng-manager
## 依赖服务
- PostgreSQL 15 (RDS: payment-db-prod)
- Redis 7 (ElastiCache: payment-cache-prod)
- 依赖方:order-svc、notification-svc
## 不适用场景
- 数据库磁盘满:请使用 [db-disk-full runbook](./db-disk-full.md)
- Redis 连接问题:请使用 [redis-slow runbook](./redis-slow.md)
- 维护窗口期间:按 [planned-maintenance](./maintenance.md) 流程
- 读者:一线 on-call、二级专家、是否需要管理层知会。
- 外链:架构图、SLO 页、相关服务 runbook 索引。
- 不适用场景:写清「请改用 xxx runbook」,避免误用。
触发条件与前置检查
触发
- 具体告警名、查询或仪表盘面板(可复制 PromQL / LogQL 片段)。
- 阈值:例如错误率 > 1% 持续 5m(写死数字,不写「偏高」)。
- 与业务事件的关联(发布、切流、活动)若有则注明。
前置
- 确认当前无计划内变更或已知 incident。
- 确认 kubectl / cloud CLI 上下文与项目 ID(命令示例)。
- 只读检查通过后再执行有副作用步骤。
触发条件与前置检查代码示例:
## 触发条件
# 告警: PaymentDB_PoolExhausted
# PromQL:
hikaricp_connections_active{pool="payment-db"} /
hikaricp_connections_max{pool="payment-db"} > 0.9
# 阈值: 连接池使用率 > 90% 持续 2min → warning
# 连接池使用率 > 98% 持续 1min → critical(触发本 runbook)
## 前置检查(只读,约 2 分钟)
# 1. 确认 kubectl 上下文
kubectl config current-context
# 期望输出: prod-cluster
# 2. 确认无计划内变更
kubectl get events -n payments --field-selector reason=Killing --sort-by='.lastTimestamp' | tail -5
# 期望输出: 无近期 pod 重启事件
# 3. 确认告警真实性(非监控抖动)
kubectl exec -n payments deployment/payment-svc -- \
curl -s http://localhost:8080/actuator/health/db
# 期望输出: {"status":"UP"} 或 "DOWN"(异常时继续下一步)
诊断流水线(只读优先)
[ 告警 / 工单触发 ]
│
▼
┌─────────────┐ 只读:metrics / logs / traces / 健康检查端点
│ 收敛范围 │──── 输出:受影响副本、区域、依赖服务状态
└─────────────┘
│
▼
┌─────────────┐ 对照「预期输出」表;不符则记下实际值与时间点
│ 逐步命令 │──── 每步注明:权限、是否可并行、预计耗时
└─────────────┘
│
▼
┌─────────────┐ 满足升级阈值 → 停止自愈尝试,带证据升级
│ 决策:缓解 │ 否则 → 误报路径或文档化新根因后结案
│ 或 升级 │
└─────────────┘
数据库连接池耗尽的具体诊断步骤(每步:命令+预期输出+失败时处理):
## 诊断步骤(只读,约 5 分钟)
### 步骤 1: 确认连接池当前状态
kubectl exec -n payments deployment/payment-svc -- \
curl -s http://localhost:8080/actuator/metrics/hikaricp.connections.active
# 预期输出(正常): {"name":"hikaricp.connections.active","measurements":[{"statistic":"VALUE","value":12.0}]}
# 失败时: value >= max_pool_size(默认50)→ 确认为连接池耗尽,继续步骤2
# 注意: 只读操作,无副作用
### 步骤 2: 查看慢查询日志(只读)
kubectl exec -n payments \
$(kubectl get pod -n payments -l app=payment-svc -o jsonpath='{.items[0].metadata.name}') \
-- cat /var/log/app/slow-queries.log | tail -50
# 预期输出(正常): 无 duration>1000ms 的记录
# 异常标志: 大量 duration>5000ms 或相同 SQL → 记录查询语句,继续步骤3
### 步骤 3: 检查数据库连接数
kubectl exec -n payments deployment/payment-svc -- \
psql "$DB_URL" -c "SELECT count(*), state FROM pg_stat_activity GROUP BY state;"
# 预期输出:
# count | state
# -------+--------
# 45 | active
# 5 | idle
# 异常: active 连接 >= max_connections(100) → 进入缓解流程
# 失败时(无权限): 联系 DBA 或升级至 L2
每一步写清「期望看到什么」与「若相反则下一步」;避免开放式「检查一下数据库」而无具体命令与判据。
缓解、回滚与特性开关
缓解步骤按风险排序:先扩容、限流、降级读,再考虑重启或切流。回滚写清顺序:特性开关 → 应用版本 → 数据库迁移是否可逆。
## 缓解步骤(按风险从低到高排序)
### 选项 A: 临时增大连接池(低风险,需要 payment-admin 权限)
# 前提:已确认数据库 max_connections 允许更多连接
kubectl set env -n payments deployment/payment-svc \
HIKARI_MAX_POOL_SIZE=80
# 验证: 等待 30s,重新检查步骤1,期望 active < 70
### 选项 B: 杀掉空闲超时连接(中风险)
kubectl exec -n payments deployment/payment-svc -- \
psql "$DB_URL" -c "
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle' AND state_change < NOW() - INTERVAL '10 minutes';"
# 预期:返回 pg_terminate_backend 列有 true 值
# 警告:此操作会中断已有连接,验证后续请求是否正常
### 选项 C: 回滚应用版本(高风险,影响所有进行中请求)
# 1. 先关闭特性开关(若适用)
kubectl set env -n payments deployment/payment-svc \
FEATURE_NEW_QUERY_OPTIMIZER=false
# 等待 60s,观察错误率
# 2. 若无效则回滚版本
kubectl rollout undo deployment/payment-svc -n payments
kubectl rollout status deployment/payment-svc -n payments
# 期望: deployment "payment-svc" successfully rolled out
# 回滚验证(与触发条件相同的检查命令)
kubectl exec -n payments deployment/payment-svc -- \
curl -s http://localhost:8080/actuator/health/db
# 期望: {"status":"UP"}
- 每条有副作用命令前重复确认上下文(集群、命名空间、release 名)。
- 回滚后验证:与触发段落相同的检查命令,期望恢复区间。
- 若回滚被禁止(合规、数据迁移),写明替代缓解与升级条件。
升级路径(L1 → L2 → 管理)
列出升级到 L2 的硬条件:例如用户影响 > N、数据损坏风险、30 分钟内无法缓解、需跨团队权限等;附 on-call 通讯录或 PagerDuty 策略链接。
- L1:按本 runbook 执行到决策点;收集时间线、命令输出片段。
- L2:领域专家;可能涉及代码热修或基础设施变更。
- 管理层:对外沟通、客户承诺、资源特批;注明谁有权批准停机。
误报与快速排除
单独一节列出已知误报(监控抖动、依赖服务例行维护、采样率问题)与 2~3 条最快排除命令;与主诊断树分叉,减少主流程噪音。
- 若确认为误报:建议的 silence 时长、标签、跟进工单(更新阈值或告警规则)。
- 与「触发条件」交叉引用,避免两处阈值矛盾。
事后:监控与 runbook 修订
事件结束后勾选:是否需更新告警阈值、是否新增仪表盘、本 runbook 哪一步描述不清;链接到 postmortem 模板(若适用)。
Runbook 测试策略(定期演练方法):
# Runbook 有效性验证清单(每季度执行一次)
## 演练方式
1. 在 staging 环境注入故障(chaos engineering)
kubectl exec -n payments-staging deployment/payment-svc -- \
curl -X POST http://localhost:8080/actuator/chaos/pool-exhaust
# 然后按 runbook 步骤排查,记录实际耗时
2. 干跑(Dry run)评审
- 新成员独立阅读 runbook,尝试复述步骤
- 记录卡壳点 → 更新文档
## 有效性判断标准
- [ ] 所有命令在当前版本可执行(无过期 API)
- [ ] 每步「预期输出」与实际环境一致
- [ ] 新 on-call 成员(无背景)能在 10min 内完成诊断
- [ ] 升级条件与当前 SLA 定义一致
- [ ] 外链(dashboard、PD 策略、相关 runbook)均可访问
## 修订记录
| 日期 | 修订人 | 变更说明 | 版本 |
|------|--------|----------|------|
| 2024-03-20 | @sre-alice | 新增连接池诊断步骤3 | v3 |
| 2024-01-15 | @sre-bob | 更新升级条件阈值 | v2 |
- 升级路径:L1 → L2 → 管理层通知条件(与上文一致时可简写「同 § 升级路径」)。
- 回滚:特性开关、部署版本、数据库补丁顺序(与缓解节呼应)。
- 文档债:OWNER、截止日、验证方式(与工单互链)。
Runbook 大纲实验室
填写标题与可选服务名,勾选要纳入的章节,生成可粘贴到 Wiki / 仓库的 Markdown 骨架;再根据真实告警与命令替换占位符。
占位符用 <需确认> 标出;Agent 生成内容时应替换为仓库内真实链接、查询与阈值,不得留空杜撰。
---
name: runbook-authoring
description: 从告警与架构信息生成运维 Runbook 骨架
model: claude-sonnet-4-5
---
# Runbook 必含章节
sections:
- 头部:服务/版本/所有者/触发告警
- 范围:环境/读者权限/依赖/不适用场景
- 触发条件:PromQL/阈值/业务关联
- 前置检查:只读命令确认上下文
- 诊断步骤:命令+预期输出+失败时处理
- 缓解与回滚:按风险从低到高排序
- 升级路径:L1→L2→管理层硬条件
- 误报与快速排除
- 事后修订:测试记录与文档债
# 步骤写作规范
step_format: |
### 步骤 N: [操作描述]([只读|有副作用])
命令: `kubectl ...`
预期输出: [具体内容]
失败时: [下一步或升级条件]
# 禁止事项
forbidden:
- 不得编造指标名、集群名或配置值
- 信息不足时输出 <需确认> 占位
- 不得省略权限说明和预期输出