如何编写事故响应运维手册(含模板)
大多数事故运维手册都会陷入两种失败模式。一种是太长(三十页的 Wiki,没有哪个 On-Call 工程师会在凌晨三点去读),另一种是太含糊(一句话写着 check the logs)。在事故中真正被使用的运维手册都遵循一种紧凑的结构,包含具体的命令和明确的决策点。本指南介绍切实可行的结构,并提供三个针对最常见事故类型的可复用模板。
运维手册是什么,不是什么
运维手册是针对某种已知事故类型的检查清单。它不是介绍系统的 Wiki 页面,不是架构图,也不是事后回顾模板。读者是一位疲惫的、可能半睡半醒的 On-Call 工程师,需要在接下来的十分钟内做出正确的处置。
如果你的运维手册解释了系统的工作原理,那它就太长了。如果它没有列出具体的命令和具体的决策点,那它就太含糊了。单个运维手册的合理篇幅大约为一屏内容。如果需要更多,就拆分。
行之有效的五段式结构
五个部分涵盖了 On-Call 工程师所需的一切。请为你集合中的每一个运维手册采用这一结构。
- 症状:告警看起来是什么样的。引用实际的告警文本。工程师应能在几秒内识别出来。
- 影响:谁受到影响以及如何受到影响。面向客户的?内部的?仅仅是监控噪声?这决定了紧迫程度。
- 诊断:用于确认诊断的三条命令或三个链接。不是泛泛的 check the logs,而是具体的 kubectl logs -n prod web-deployment -c app。
- 修复:用于解决问题的具体命令或操作。编号列出、幂等且可安全重试。
- 升级:如果修复无效,需要叫醒谁。姓名和电话号码。
模板:数据库连接饱和运维手册
最常见的生产事故类型。数据库连接池已满,新请求超时,监控触发高延迟告警。
症状:/api/health 上的 p95 响应时间超过 5 秒。影响:面向客户的 API 端点超时。诊断:kubectl exec 进入应用 Pod 并运行 pg_stat_activity。查找长时间运行的查询。修复:使用 pg_cancel_backend 取消运行最久的查询,使用 helm upgrade 将连接池大小扩大 20%,重启受影响的 Pod。升级:如果连接池在 10 分钟后仍然饱和,则呼叫数据库负责人。
模板:SSL 证书过期运维手册
可预测、可预防,但最终几乎每个团队都还是会遇到。这本运维手册篇幅很短,因为答案本身就很短。
- 症状:SSL 监控触发 expires in 7 days 或 expired。
- 影响:一旦证书失效,每个浏览器都会显示红色警告页面。转化率归零。
- 诊断:运行 `echo
- openssl s_client -servername DOMAIN -connect DOMAIN:443 2>/dev/null
- openssl x509 -noout -dates` 查看当前证书的 notAfter 日期。
- 修复:手动运行续期脚本(`certbot renew --force-renewal` 或等效命令),然后重载 nginx 或负载均衡器。用同样的 openssl 命令进行验证。
- 升级:如果 certbot 失败,则呼叫 DevOps。必须在过期之前手动续期证书。
模板:上游提供商故障运维手册
当第三方依赖(Stripe、Postmark、S3、身份认证提供商)才是故障的真正源头时,你的工作是识别它、对外沟通它,而不是浪费时间调试自家的代码。
症状:相关功能出现故障,而你自己的监控其余部分都是绿色的。诊断:在新标签页中打开提供商的状态页面。在最近的提交中搜索任何与该集成相关的更改。修复:在你自己的状态页面发布一条更新,确认上游事故,并附上指向提供商状态页面的链接。如果降级严重,则通过功能开关禁用该功能。升级:仅当降级持续超过一小时且上游提供商仍未确认时才升级。
将其保存在何处以及如何保持更新
将运行手册保存在与应用程序代码相同的 git 仓库中。在告警消息中直接链接到它们。每次事故后都进行审查:如果运行手册有误,请趁事故记忆新鲜时立即更新。一年未更新的运行手册可能已不再准确。安排每季度对运行手册集进行一次审查。删除不再适用的条目,添加新的条目。像对待代码一样对待它们。