运维人最容易忽视的一件事:Runbook 不结构化,迟早会出事故
运维人最容易忽视的一件事:Runbook 不结构化,迟早会出事故
作者:Echo_Wish
我做运维这么多年,见过太多团队在一个地方翻车,而且是反复翻车。
不是技术不行,也不是系统太复杂。
而是一个看起来特别不起眼的问题:
内部文档和 Runbook 写得太随意。
很多团队的文档是这样的:
- Word 文档
- Confluence 页面
- 飞书笔记
- 一堆截图
- 还有人把关键步骤写在微信群里
结果是什么?
凌晨 3 点报警的时候,值班同事翻文档翻半天:
“这个操作步骤到底在哪个版本的文档里?”
更可怕的是:
不同人写的 Runbook 完全不是一个结构。
有人写故事,有人写流水账,有人写小说。
所以今天想聊一个很多团队忽略,但其实极其重要的话题:
内部文档与 Runbook 的结构化 + 版本化管理。
如果你是 SRE、运维负责人、平台工程师,这个问题迟早会遇到。
一、Runbook 最大的问题:不是没有,而是太乱
很多团队都会说:
“我们有文档啊。”
但真实情况往往是:
wiki/
├─ mysql问题处理
├─ mysql异常处理
├─ mysql故障排查
├─ mysql排错指南
看起来很多。
但你打开之后发现:
- 内容重复
- 版本冲突
- 操作步骤不一致
最要命的是:
没有统一结构。
真正好用的 Runbook,一定是结构化的。
我一般建议一个标准结构:
Runbook结构
├─ 背景说明
├─ 触发条件
├─ 影响范围
├─ 诊断步骤
├─ 处理步骤
├─ 回滚方案
├─ 验证方法
└─ 相关链接
举个简单例子。
二、一个结构化 Runbook 示例
比如:Redis CPU 飙高故障处理
# Redis CPU 使用率异常
## 背景说明
Redis CPU 持续超过 80%,可能导致请求延迟上升。
## 触发条件
Prometheus 触发告警:
redis_cpu_usage > 80% for 5m
## 影响范围
- API 响应时间上升
- 缓存 miss 率增加
## 诊断步骤
1. 查看 Redis CPU
```bash
top -p $(pidof redis-server)
- 查看慢查询
redis-cli slowlog get 10
- 查看大 key
redis-cli --bigkeys
处理步骤
- 如果慢查询异常
优化对应业务 SQL
- 如果大 key
拆分 key
回滚方案
重启 Redis 节点
systemctl restart redis
验证方法
查看 CPU 是否恢复:
redis-cli info cpu
你会发现一个变化:
**结构清晰。**
凌晨值班的人只需要按步骤走。
---
# 三、Runbook 其实也应该版本化
很多团队忽略一个事情:
**Runbook 也是代码。**
既然是代码,就应该:
- Git 管理
- Code Review
- 版本历史
推荐一个最简单的结构:
ops-runbook/
├─ mysql
│ ├─ replication_lag.md
│ ├─ disk_full.md
│
├─ redis
│ ├─ cpu_high.md
│ ├─ memory_fragment.md
│
├─ k8s
│ ├─ pod_crash.md
│ ├─ node_not_ready.md
全部放在 Git。
比如:
git commit -m “update redis cpu troubleshooting”
好处很多:
### 1 可追溯
谁改的?
什么时候改的?
为什么改?
Git 都知道。
---
### 2 可 Review
很多事故其实来自:
**错误操作步骤。**
如果 Runbook 可以 PR:
PR -> Review -> Merge
错误概率会低很多。
---
### 3 可以和代码一起发布
很多团队会把 Runbook 跟服务放一起。
例如:
service-repo/
├─ service
├─ deployment
└─ runbook
部署脚本更新时,Runbook 同步更新。
---
# 四、Runbook 最好的形态:可执行
很多人写 Runbook 只是写文档。
但更高级的方式是:
**Runbook 自动化。**
举个例子。
假设我们要检查 Kubernetes Pod Crash。
传统 Runbook:
1 查看 Pod
2 查看日志
3 查看事件
其实可以写成脚本。
```bash
#!/bin/bash
echo "=== 检查Pod状态 ==="
kubectl get pods -A | grep CrashLoopBackOff
echo "=== 最近事件 ==="
kubectl get events --sort-by=.lastTimestamp | tail -20
echo "=== Pod日志 ==="
kubectl logs $1 --tail=50
这样 Runbook 就变成:
执行脚本
而不是:
人工操作
再进一步可以做成:
自动诊断工具。
例如 Python:
import subprocess
def check_pods():
cmd = "kubectl get pods -A"
result = subprocess.check_output(cmd, shell=True)
print(result.decode())
def check_events():
cmd = "kubectl get events --sort-by=.lastTimestamp"
result = subprocess.check_output(cmd, shell=True)
print(result.decode())
if __name__ == "__main__":
check_pods()
check_events()
这样 Runbook 就升级成:
Ops Toolkit。
五、真正成熟团队的 Runbook 体系
很多成熟团队 Runbook 其实是三层结构:
Level 1 告警说明
Level 2 诊断步骤
Level 3 自动化脚本
比如:
alert -> runbook -> script
举个例子:
Prometheus 告警:
ALERT RedisHighCPU
Runbook:
https://runbook.company.com/redis/high_cpu
Runbook 页面:
诊断步骤
↓
一键执行脚本
这才是 SRE 的标准玩法。
六、一个很多团队忽视的细节
Runbook 写得再好,如果 找不到,也没用。
我见过最离谱的一次:
运维文档分布在:
- Confluence
- 飞书
- GitHub
- 本地 Word
最后大家干脆问:
“谁知道这个怎么处理?”
所以我一直强调:
Runbook 一定要统一入口。
比如:
runbook.company.com
或者:
docs.company.com/runbook
配合全文搜索。
值班同事只要搜:
mysql replication lag
就能找到。
七、我自己的一个小感悟
运维工作很多时候不是写代码,而是:
减少人的不确定性。
凌晨值班的人可能是:
- 新同事
- 不熟悉系统的人
- 刚入职的工程师
如果 Runbook 写得好:
他只需要 照步骤执行。
如果 Runbook 写得乱:
就只能 靠经验猜。
而运维最怕的就是:
在不确定的情况下做操作。
所以在我看来:
Runbook 其实是一种工程化经验沉淀。
它把一个人脑子里的经验,变成团队资产。
最后
很多团队喜欢追新技术:
- Kubernetes
- Serverless
- AI Ops
但真正影响稳定性的,往往不是这些。
而是一些很基础的东西:
- 文档
- Runbook
- 监控
- 操作规范
这些东西做得好,系统很难出大事故。
如果做得不好,再先进的架构也救不了。
- 点赞
- 收藏
- 关注作者
评论(0)