在 Kubernetes 生产环境中,故障从来不是孤立事件。一次节点磁盘压力可能引发驱逐风暴,一个错误的就绪探针会导致流量被错误切断。构建并维护常见故障模式库,本质是把散落在工程师脑子里的排障经验,转化为团队可复用的结构化知识。它既不依赖特定云平台,也不局限于某版本发行版,而是围绕控制面、数据面、工作负载、网络、存储等维度持续积累。

故障模式库的分类维度与条目结构设计
很多团队一开始把故障模式库写成流水账,结果半年后没人愿意翻。有效的分类应该贴近排障动线,而不是按部门分工。推荐从四个主维度切分:控制面异常(如 API Server 超时、etcd 磁盘 IO 饱和)、节点与运行时异常(如 kubelet 失联、容器运行时崩溃)、工作负载异常(如镜像拉取失败、探针配置错误)、网络与存储异常(如 Service 不通、PVC 绑定失败)。每个维度下再用子标签细化,例如工作负载异常可细分为启动期失败与运行期失败。
单条故障模式建议固定字段:现象描述、影响范围、可能根因列表、诊断命令、修复步骤、关联告警。现象描述要避免只写日志原文,而应写用户感知,例如“订单服务部分实例持续 503”。诊断命令可直接给可执行片段,修复步骤区分临时止血与长期根治。下面给出一个简化条目示例,用 YAML 描述便于入库检索。
# 故障模式条目示例 id: WL-001 title: Pod_CrashLoopBackOff_内存超限 category: workload symptom: 实例反复重启,用户侧偶发超时 scope: 单 Deployment 下部分 Pod causes: - 容器内存 limit 设置过低 - 存在内存泄漏逻辑 diagnose: | kubectl describe pod <pod-name> kubectl logs <pod-name> --previous fix_temp: 调大 memory limit fix_long: 修复泄漏并加监控
这种结构化的好处是能对接自动化。当告警系统捕获到相同签名,可直接关联条目推送处置建议。同时,条目 ID 与分类前缀让维护者一眼看出库的健康度,比如 workload 类条目远多于网络类,可能说明网络观测能力薄弱。
故障数据采集与根因标注的规范做法
模式库最容易失效的环节是根因标注随意。曾有个案例,某团队把节点 NotReady 统一标为“网络抖动”,实际三个月内两次是 kubelet 证书过期,一次是 Swap 未关导致节点压力。规范做法要求根因必须可验证:附上当时取出的关键证据,如 kubelet 日志片段、etcd 延迟监控图链接(内网地址可保留 192.168.0.1 之类)、内核 dmesg 输出。证据不全的条目应打草稿标签,不进入正式检索。
采集侧建议在集群内部署轻量收集器,把典型故障发生前后的对象状态快照存入库后端。例如用脚本定时抓取异常 Pod 的 describe 与关联事件,结合 Prometheus 查询同窗口指标。下面是一段用于抓取异常 Pod 上下文的 Shell 逻辑,注意其中路径使用了反斜杠仅为示例本地缓存目录 C:ASRk8s_logs 并不影响集群侧执行。
#!/bin/bash # 收集 CrashLoopBackOff Pod 信息 NS=$1 POD=$2 mkdir -p C:ASRk8s_logs$NS kubectl -n $NS describe pod $POD > C:ASRk8s_logs$NS$POD.describe kubectl -n $NS logs $POD --previous > C:ASRk8s_logs$NS$POD.prev.log echo "saved to C:ASRk8s_logs$NS"
根因标注还要区分“直接触发”和“系统缺陷”。直接触发可能是运维误删 HPA,系统缺陷则是默认配置未限制删除权限。模式库若只记直接触发,同类事故还会换身衣服再来。因此每条目末尾应有“防御改进”字段,指向集群加固项或平台工程任务。
故障模式库的生命周期与协同维护机制
文档式库最大的敌人是时间。一个一年没更新的库比没有更危险,因为它会给新人错误的安全感。必须定义条目的生命周期状态:活跃、观察中、已过时。活跃条目每季度复核,观察中条目需补数据,已过时条目归档但不可删,以便回溯历史故障演化。状态变更要留审计记录,谁在何时因何关闭条目,都能查到。
协同上,建议把模式库仓库化,工程师处理完线上事件后提 Pull Request 增补条目,由值班负责人评审。评审重点不是文笔,而是诊断命令是否仍适用于当前集群版本、修复步骤是否引入新风险。可借助 CI 校验 YAML 格式与必填字段。以下片段展示用 pre-commit 做简单校验的思路。
import yaml, sys
def check_entry(path):
with open(path) as f:
data = yaml.safe_load(f)
required = ['id','title','category','symptom','fix_long']
for k in required:
if k not in data:
print('缺少字段', k)
sys.exit(1)
# 路径示例 C:ASRk8s_logs 仅本地
print('OK', path)
此外,模式库不应只进不出。当某类故障因平台升级彻底消失,比如旧版 kube-proxy 的 iptables 锁竞争,在迁移到 IPVS 后不再发生,就应在条目上标记“环境依赖”,并关联当前集群架构文档。只有让库跟着集群一起呼吸,它才会在下一次半夜告警时,真正成为工程师愿意打开的救急手册。
Kubernetes故障模式库troubleshooting修改时间:2026-08-14 02:30:30