news 2026/7/29 4:38:07

【K8S 运维实战】22-故障演练ChaosMesh

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【K8S 运维实战】22-故障演练ChaosMesh

故障演练:Chaos Mesh 与应急 SOP

一句话定位:没出过事的集群最危险——主动制造故障,才能在真出事时从容应对。

写在前面

我带过一个团队,集群跑了半年没出过故障,大家觉得"稳了"。结果某天一个 etcd 节点磁盘满,触发连锁反应,半数 Pod 被驱逐,业务挂了 40 分钟才定位到根因。事后复盘,我们一致同意上 Chaos Mesh 做故障演练。半年里我们主动注入了 30 多种故障,提前暴露了 5 个潜在隐患。从此团队的口头禅变成:"不演练,就没有真正的稳。"这篇把 Chaos Mesh 故障注入和应急 SOP 一起讲,让"主动出事"成为运维习惯。

核心问题

  • 没出过事的集群最危险,怎么主动制造故障?Chaos Mesh 注入网络/IO/Pod/时间等故障,模拟真实异常。
  • 演练怎么设计才不搞砸生产?稳态假设 → 受控注入 → 观察 → 恢复 → 复盘,严格守边界。
  • 出事时怎么快速响应?应急 SOP 分级响应,通报链清晰,复盘闭环。

一、原理剖析

1.1 Chaos Mesh 架构

Chaos Mesh 是 PingCAP 开源的云原生混沌工程平台:

调度

监听 CRD

注入故障

网络/IO 操作

记录

创建实验

chaos-mesh-controller

chaos-daemon DaemonSet

ChaosEngine CRD

目标 Pod

节点内核

chaos-dashboard

chaos-mesh CLI

核心组件:

  • chaos-controller-manager:控制器,监听 Chaos CRD,调度实验
  • chaos-daemon:DaemonSet,在每个节点执行故障注入(网络 tc、IO 等)
  • chaos-dashboard:Web UI,管理实验和归档
  • chaosctl:命令行工具

1.2 故障注入类型全景

Chaos Mesh 提供丰富的 CRD,覆盖主流故障类型:

CRD类型模拟什么真实场景对应
PodChaosPodPod Kill/Pod Failure/Container Kill节点宕机、OOMKill
NetworkChaos网络延迟/丢包/重复/带宽限制网络抖动、跨机房延迟
IOChaos磁盘 IO读写延迟/错误/有限带宽磁盘慢、IO 阻塞
TimeChaos时钟时间偏移NTP 失同步
StressChaos资源CPU/内存压测资源争抢、内存泄漏
DNSChaosDNSDNS 解析失败/延迟DNS 服务故障
HTTPChaosHTTP请求延迟/错误响应上游服务异常
JVMChaosJVM方法异常/延迟/GCJava 应用故障

1.3 演练工作流设计

一次完整的演练遵循稳态假设方法:

1. 定义稳态假设

2. 基线观察

3. 注入故障

4. 观察系统响应

稳态是否保持?

5a. 恢复,演练成功

5b. 紧急回滚

6. 事后复盘

稳态假设(Steady State Hypothesis)是核心——先定义"什么是正常",再注入故障看系统是否仍保持正常。比如"P99 延迟 < 200ms"“错误率 < 0.1%”,注入后系统违反假设就说明有隐患。

二、实战操作

2.1 Chaos Mesh 安装

# 添加 Chaos Mesh 仓库helm repoaddchaos-mesh https://charts.chaos-mesh.org helm repo update# 安装(指定版本支持 K8s 1.30)helminstallchaos-mesh chaos-mesh/chaos-mesh\-nchaos-testing\--create-namespace\--version2.7.0\--setchaosDaemon.runtime=containerd\--setchaosDaemon.socketPath=/run/containerd/containerd.sock\--setcontrollerManager.replicaCount=3\--setdashboard.replicaCount=2\--setdashboard.securityMode=false# 生产可开启 RBAC# 验证kubectl get pods-nchaos-testing# chaos-controller-manager / chaos-daemon / chaos-dashboard 都 Running# 暴露 dashboard(测试用)kubectl port-forward-nchaos-testing svc/chaos-dashboard2333:2333# 访问 http://localhost:2333

2.2 PodChaos 实验:模拟 Pod 被杀

模拟某个 Deployment 的 Pod 被随机杀死,验证副本自愈:

# podchaos-kill.yamlapiVersion:chaos-mesh.org/v1chaoskind:PodChaosmetadata:name:pod-kill-app1namespace:chaos-testingspec:action:pod-kill# 杀 Podmode:one# 一次杀一个containerName:""selector:namespaces:-app1labelSelectors:"app":"backend"# 只针对 backendscheduler:cron:"@every 5m"# 每 5 分钟杀一次duration:"30m"# 演练持续 30 分钟
kubectl apply-fpodchaos-kill.yaml# 观察实验状态kubectl get podchaos-nchaos-testing kubectl describe podchaos pod-kill-app1-nchaos-testing# 观察 Pod 自愈watch-n2'kubectl get pods -n app1 -l app=backend'

2.3 NetworkChaos 实验:模拟网络延迟

模拟 app1 → app2 的网络延迟,验证超时重试:

# networkchaos-delay.yamlapiVersion:chaos-mesh.org/v1chaoskind:NetworkChaosmetadata:name:net-delay-app1-to-app2namespace:chaos-testingspec:action:delaymode:all# 所有匹配 Podselector:namespaces:-app1labelSelectors:"app":"backend"direction:to# 出方向流量target:selector:namespaces:-app2labelSelectors:"app":"frontend"mode:alldelay:latency:"500ms"# 延迟 500mscorrelation:"50"# 50% 相关性jitter:"100ms"# 抖动 100msduration:"10m"
kubectl apply-fnetworkchaos-delay.yaml# 观察 app1 调 app2 的延迟变化kubectlexec-napp1 deploy/backend --curl-w"%{time_total}\n"-o/dev/null-shttp://frontend.app2:80

2.4 IOChaos 实验:模拟磁盘慢

模拟 PV 读写延迟,验证应用对慢 IO 的容忍:

# iochaos-delay.yamlapiVersion:chaos-mesh.org/v1chaoskind:IOChaosmetadata:name:io-delay-app1namespace:chaos-testingspec:action:latencymode:allselector:namespaces:-app1labelSelectors:"app":"db"volumePath:/var/lib/postgresql/datapath:"/var/lib/postgresql/data/**/*"delay:"200ms"# 每次 IO 延迟 200mspercent:50# 50% 的 IO 受影响duration:"10m"

2.5 StressChaos 实验:模拟 CPU 打满

# stresschaos-cpu.yamlapiVersion:chaos-mesh.org/v1chaoskind:StressChaosmetadata:name:cpu-stress-app1namespace:chaos-testingspec:mode:oneselector:namespaces:-app1labelSelectors:"app":"backend"stressors:cpu:workers:2load:80# CPU 打到 80%duration:"5m"

2.6 演练工作流(Workflow CRD)

把多步演练编排成 Workflow,串行/并行执行:

# workflow-drill.yamlapiVersion:chaos-mesh.org/v1alpha1kind:Workflowmetadata:name:app1-drillnamespace:chaos-testingspec:entry:maintemplates:-name:maintemplateType:Serial# 串行children:-kill-pod-network-delay-cpu-stress-name:kill-podtemplateType:PodChaosdeadline:"5m"podChaos:action:pod-killmode:oneselector:namespaces:[app1]labelSelectors:{"app":"backend"}-name:network-delaytemplateType:NetworkChaosdeadline:"10m"networkChaos:action:delaymode:allselector:namespaces:[app1]labelSelectors:{"app":"backend"}delay:latency:"300ms"direction:to-name:cpu-stresstemplateType:StressChaosdeadline:"5m"stressChaos:mode:oneselector:namespaces:[app1]labelSelectors:{"app":"backend"}stressors:cpu:workers:2load:90
kubectl apply-fworkflow-drill.yaml kubectl get workflow-nchaos-testing# dashboard 里可看到可视化执行流程

三、踩坑与排查

坑1:Chaos Mesh 注入后没生效

现象:创建了 PodChaos,但目标 Pod 没被杀。

原因:selector 没匹配到 Pod,或 chaos-daemon 没在该节点运行。

解决:

# 1. 检查 selector 是否匹配kubectl get pods-napp1-lapp=backend# 没结果说明 label 写错# 2. 查看 experiment 状态kubectl get experiment-nchaos-testing kubectl describe experiment<name>-nchaos-testing# 看 failed 或 not match 信息# 3. 确认 chaos-daemon 在所有节点 Runningkubectl get ds-nchaos-testing chaos-daemon

坑2:网络故障注入后没清理干净

现象:NetworkChaos 已删除,但节点上 tc 规则还在,网络仍异常。

原因:chaos-daemon 异常退出,没清理 tc 规则。

解决:

# 手动清理 tc 规则ssh<node>tc qdisc del dev eth0 root# 或用 chaosctl 工具清理curl-sSLhttps://mirrors.chaos-mesh.org/latest/install.sh|shchaosctl clean

坑3:演练误伤生产,业务挂了

现象:演练 Pod Kill 误删了没有副本的 Pod,业务中断。

原因:selector 范围太大,或没设演练边界。

解决(预防为主):

  • 演练前确认目标 Pod 都有 ≥2 副本 + PDB
  • 用 namespace 隔离演练对象
  • 先在测试环境演练,验证后再上预发
  • 设置duration上限,防实验忘记删
  • 开启--webhook拦截高风险注入

四、应急 SOP 与复盘

4.1 应急响应分级

等级定义响应时间通报范围处理人
P0核心业务全挂<5 分钟全员+管理层值班 SRE
P1核心业务降级<15 分钟SRE+业务负责人值班 SRE
P2非核心受影响<30 分钟SRE 团队值班 SRE
P3单节点/告警<2 小时SRE 内部当班 SRE

4.2 应急响应 SOP

┌─────────────────────────────────────────────┐ │ 应急响应 SOP 流程 │ ├─────────────────────────────────────────────┤ │ 1. 告警触发 → 值班确认(5 分钟内) │ │ 2. 通报:群里发"P0 事件,启动应急" │ │ 3. 止血:先恢复业务(重启/回滚/切流) │ │ 4. 定位:查日志、metrics、最近变更 │ │ 5. 修复:根因修复 │ │ 6. 验证:业务恢复正常 │ │ 7. 收尾:通报"已恢复",建复盘工单 │ │ 8. 复盘:24 小时内出复盘报告 │ └─────────────────────────────────────────────┘

4.3 事后复盘模板

# 故障复盘报告:<标题> ## 一、故障概述 - 发生时间:2026-07-18 02:00 ~ 02:40(40 分钟) - 影响范围:app1 命名空间所有服务,约 5000 用户受影响 - 故障等级:P0 ## 二、故障影响 - 业务层面:订单服务不可用,损失预估 X 万 - 数据层面:无数据丢失 - 用户层面:下单失败,部分用户重复下单 ## 三、时间线 | 时间 | 事件 | |---|---| | 02:00 | 告警触发:app1 Pod 大量 CrashLoopBackOff | | 02:05 | 值班 SRE 确认,启动应急 | | 02:10 | 初步定位:etcd db 满,apiserver 只读 | | 02:20 | 执行 etcd compact + defrag | | 02:30 | apiserver 恢复,Pod 重建 | | 02:40 | 全部业务恢复 | ## 四、根因分析 - 直接原因:etcd db 写满(2GB quota),转只读保护 - 深层原因:未开启 auto-compaction,db 增长无监控 ## 五、改进措施 | 措施 | 负责人 | 截止日期 | 状态 | |---|---|---|---| | 开启 etcd auto-compaction | 张三 | 2026-07-20 | 进行中 | | 增加 etcd db size 监控告警(70%) | 李四 | 2026-07-19 | 完成 | | 把 etcd quota 调到 8GB | 王五 | 2026-07-20 | 进行中 | | 增加 Chaos Mesh 演练:etcd 满场景 | 赵六 | 2026-07-25 | 计划中 | ## 六、经验教训 - 备份和监控同等重要,缺一不可 - etcd 是集群命根子,要有专项巡检 - 应急流程要演练,不能只在文档里

4.4 演练安全边界

  • 演练范围明确(selector 精确匹配,namespace 隔离)
  • 演练目标 Pod 必须有 ≥2 副本 + PDB
  • 每个实验设duration上限,防遗忘
  • 先测试环境,再预发,最后生产灰度
  • 演练前通知业务方,避开高峰
  • 准备一键回滚(删除 Chaos CR 即可恢复)
  • 演练时有人盯监控,异常立即终止
  • 生产演练从低烈度开始(Pod Kill 单个 → 网络延迟 → 资源压力)
  • 记录演练日志,便于复盘

五、最佳实践

  • 生产集群部署 Chaos Mesh,定期演练(每月一次)
  • 用 Workflow CRD 编排多步演练
  • 稳态假设前置:先定义 SLO,再注入故障
  • 演练覆盖:Pod/网络/IO/CPU/内存/DNS 全类型
  • 应急 SOP 贴在值班台,P0/P1 流程烂熟于心
  • 每次故障 24 小时内出复盘报告
  • 复盘聚焦改进措施,不追责
  • 改进措施跟踪到完成,闭环管理
  • 演练结果归档,形成故障知识库
  • chaos-daemon 资源给足,避免自身故障
  • dashboard 开启 RBAC,限制演练权限
  • 把"演练成功率"作为 SRE 团队 KPI

六、小结

混沌工程的核心思想是"主动拥抱故障"。与其等故障找上门,不如我们主动制造可控的故障,提前暴露系统的薄弱点。Chaos Mesh 让故障注入变得声明式、可编排、可观测,但工具只是手段,真正有价值的是"稳态假设 → 注入 → 观察 → 复盘"这套方法论。配合应急 SOP 和复盘机制,你的团队就能从"被动救火"升级为"主动防御"。没出过事的集群最危险——把这句话刻在心里,把演练变成习惯,真到出事那天,你才能从容不迫。

思考题

  1. PodChaos 的pod-killcontainer-kill有什么区别?分别模拟什么场景?
  2. 演练时稳态假设 SLO 设的太严(如错误率 0),会导致什么问题?应该怎么设?
  3. 生产环境做 Chaos Mesh 演练,最大的风险是什么?如何把风险降到最低?

延伸阅读

  • Chaos Mesh 官方文档:https://chaos-mesh.org/docs/
  • 混沌工程原则:https://principlesofchaos.org/
  • Google SRE 应急响应:https://sre.google/sre-book/incident-response/
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/29 4:37:57

科学实验探究创新大赛:从选题到答辩的实践指南

1. 从“参赛”到“出圈”&#xff1a;重新定义科学实验探究创新大赛如果你是一名高中生、大学生&#xff0c;或者是一位科技辅导员、中学老师&#xff0c;当看到“科学实验探究创新大赛”这个标题时&#xff0c;你的第一反应是什么&#xff1f;是“又一个要写论文、做PPT的比赛…

作者头像 李华
网站建设 2026/7/29 4:33:43

GIS贴牌业务实战:技术适配与商务合作关键要点

1. GEO系统贴牌业务概述GEO&#xff08;地理信息系统&#xff09;贴牌业务是指基于成熟的GIS平台或解决方案&#xff0c;通过品牌授权和技术适配的方式&#xff0c;为客户提供定制化的地理信息产品服务。这种模式允许贴牌方在不具备底层技术研发能力的情况下&#xff0c;快速构…

作者头像 李华
网站建设 2026/7/29 4:33:06

MySQL安全危机复盘:从skip-grant-tables风险到AI自动化防御

1. 项目概述&#xff1a;一次真实的MySQL安全危机复盘 那天下午&#xff0c;我正喝着咖啡&#xff0c;突然收到一条来自监控系统的紧急告警&#xff1a;“生产数据库主节点连接数异常飙升&#xff0c;疑似存在未授权访问尝试”。冷汗瞬间就下来了。登录服务器一看&#xff0c; …

作者头像 李华
网站建设 2026/7/29 4:31:48

Python与C线程对比:GIL限制、性能差异与并发编程实战

1. 项目概述&#xff1a;为什么需要对比Python与C的线程&#xff1f;如果你同时接触过Python和C语言&#xff0c;并且在项目中尝试过使用线程&#xff0c;那你大概率会和我一样&#xff0c;经历过从“C线程真灵活”到“Python线程怎么这么慢”的困惑&#xff0c;再到“哦&#…

作者头像 李华
网站建设 2026/7/29 4:31:26

C/C++内存管理全解析:从malloc/new到智能指针与性能优化

1. 项目概述&#xff1a;从“申请内存”说起在C和C的世界里&#xff0c;“申请内存”这四个字&#xff0c;几乎是每个程序员从入门到精通都无法绕开的基石。它不像Python或Java那样&#xff0c;有垃圾回收机制在背后默默帮你打理一切。在C/C里&#xff0c;你向系统要一块内存&a…

作者头像 李华