抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

混沌工程不是“随机搞破坏”,而是用受控实验验证系统在真实故障下是否还能守住 SLO。本文按 Principles of Chaos、Google SRE、Chaos Mesh、ChaosBlade、LitmusChaos 的官方资料,讲清实验设计、故障类型、工具选型、生产安全、Game Day、自动化和组织治理。

最后更新:2026-10-22

什么是混沌工程

Principles of Chaos 的定义:

Chaos Engineering is the discipline of experimenting on a system in order to build confidence in the system’s capability to withstand turbulent conditions in production.

翻译:混沌工程是对系统做实验,以建立“系统能在生产环境动荡条件下存活”的信心。

关键词:

  • 实验:不是随机破坏,而是有假设、有观测、有结论
  • 信心:目标是减少未知,不是制造事故
  • 生产条件:真实流量、真实依赖、真实配置
  • 受控:有范围、有中止条件、有回滚

混沌工程解决的是分布式系统的“未知未知”:

  • 单服务都正常,但服务间交互导致级联失败
  • 超时/重试配置不当导致重试风暴
  • 下游变慢导致线程池耗尽
  • 单点故障导致雪崩
  • 故障转移没演练过,真出事时切不过去

它不是:

  • 随机杀 Pod 的“破坏性测试”
  • 只做一次就结束的演练
  • 用生产事故来“验证”系统
  • 替代单元/集成/压测/灾备演练

五个核心原则

1. 围绕稳态建立假设

先定义“系统正常”是什么:

  • 成功率、延迟、错误率
  • 数据新鲜度
  • 队列 lag
  • SLO/错误预算

然后提出可证伪的假设:

在注入 100ms 网络延迟、持续 5 分钟的情况下,核心下单接口成功率仍 ≥ 99.9%,P95 延迟 < 500ms。

没有稳态指标和假设,就不是实验。

2. 变化真实世界事件

故障变量要对应真实事件:

  • 服务器宕机
  • 磁盘满
  • 网络分区/延迟/丢包
  • DNS 故障
  • 依赖超时
  • 流量突增
  • 证书过期
  • 可用区故障

按“影响大”或“发生频率高”排序,不要只做最简单的 Pod kill。

3. 在生产环境做实验

系统的行为依赖真实流量、真实数据和真实依赖。预发环境很难复制:

  • 流量模式
  • 数据规模和分布
  • 网络拓扑
  • 依赖的真实延迟
  • 配置漂移

生产实验必须配合最小爆炸半径、审批、监控和中止条件。不能一上来就全量。

4. 自动化实验以持续运行

一次性演练会过期。系统、流量、依赖都在变,实验要:

  • 定期调度
  • 进入 CI/CD
  • 自动判定成功/失败
  • 自动恢复
  • 结果可追踪

Chaos Mesh 的 Schedule、Workflow、StatusCheck 就是为持续实验设计的。

5. 最小化爆炸半径

生产实验可能造成真实影响,必须:

  • 只选少量实例/租户/流量
  • 设置短持续时间
  • 明确中止条件
  • 有 kill switch
  • 通知 on-call 和业务
  • 从非核心业务开始

原则不是“必须炸生产”,而是“在生产中学习,同时把影响控制在可接受范围”。

混沌工程与相关实践的区别

实践 目的 范围 是否有假设 典型产出
单元/集成测试 验证代码逻辑 开发/CI 是 测试报告
故障注入 注入一个故障 组件/环境 不一定 故障行为
混沌实验 验证系统在故障下的稳态 受控范围 是 假设是否成立
压测 找容量上限 环境/生产 是 容量曲线
Game Day 组织级演练 多团队 是 协作和恢复能力
灾备演练 验证 RTO/RPO 机房/区域 是 恢复报告
混沌工程 持续建立系统韧性信心 组织级 是 实验体系和文化

混沌工程可以包含故障注入、压测、Game Day、灾备演练,但不等同于其中任何一个。

成熟度模型

阶段 特征 风险
L0 手工故障注入 手动杀 Pod、断网 高,难复现
L1 预发实验 预发环境跑固定场景 低,但真实性不足
L2 生产小范围 生产 canary 租户/实例 中,需要 guardrail
L3 持续实验 定时/流水线自动实验 中,需要自动化判定
L4 混沌即代码 GitOps 管理实验、CI 门禁 低,可审计
L5 组织韧性 多团队 Game Day、灾备、持续改进 低,形成文化

不要跳级。没有可观测性、SLO 和中止机制,直接做生产混沌会把故障放大。

实验设计方法

实验文档

每个实验至少写清:

  • 实验名称、owner、日期
  • 目标服务和依赖
  • 稳态指标和基线
  • 假设
  • 故障类型和参数
  • 影响范围(namespace/label/流量比例)
  • 持续时间
  • 中止条件
  • 回滚/恢复步骤
  • 通知对象
  • 观测看板
  • 结果和 action

设计步骤

  1. 选目标:核心链路、最近故障、高风险依赖
  2. 定稳态:SLI/SLO、错误率、延迟、lag、数据新鲜度
  3. 写假设:可证伪,例如“P95 延迟不会超过 500ms”
  4. 选故障:对应真实事件,不要为了工具而工具
  5. 定范围:从 1 个实例/1 个租户/5% 流量开始
  6. 定时间:短、可中止、避开高峰
  7. 准备观测:看板、告警、日志、trace
  8. 准备恢复:kill switch、回滚、扩容、切流
  9. 执行:记录开始/结束、注入参数、观察结果
  10. 复盘:假设是否成立、系统哪里弱、action 是什么

中止条件

  • SLO 跌破阈值
  • 错误率/延迟超过红线
  • 影响范围超出预期
  • 出现数据丢失/安全事件
  • on-call 无法及时响应
  • 业务方要求停止

中止条件要在实验前写死,不能临场“再看看”。

实验分级

级别 范围 示例
组件级 单 Pod/单实例 杀一个 Pod
服务级 单服务/单租户 服务网络延迟
依赖级 数据库/缓存/MQ 主库切换、Redis 超时
区域级 AZ/机房 可用区故障
组织级 多团队/多系统 Game Day、灾备

稳态指标

黄金信号

  • Latency:P50/P95/P99
  • Traffic:QPS、吞吐
  • Errors:错误率、失败请求
  • Saturation:CPU、内存、磁盘、连接池、队列

SLO 指标

  • 可用性
  • 请求成功率
  • 数据新鲜度
  • 作业 SLA 完成率
  • 消费 lag

业务指标

  • 下单成功率
  • 支付成功率
  • 登录成功率
  • 核心报表按时率

基线

实验前至少采集:

  • 最近 1 小时/1 天的基线
  • 同时段对比
  • 依赖的健康状态
  • 容量水位

没有基线,就无法判断“变慢”是实验导致还是正常波动。

故障类型全景

资源类

  • CPU 打满
  • 内存耗尽/OOM
  • 磁盘满/inode 耗尽
  • 磁盘 IO 延迟/错误
  • 文件系统只读
  • 线程池/连接池耗尽

网络类

  • 延迟
  • 丢包
  • 重复包
  • 乱序
  • 带宽限制
  • 网络分区
  • DNS 解析失败/错误
  • TLS 握手失败
  • 端口不可达

进程/容器类

  • 杀 Pod
  • 容器重启
  • 容器 OOM
  • 镜像拉取失败
  • 进程暂停
  • 信号错误

节点类

  • 节点宕机
  • 节点 drain
  • kubelet 故障
  • 容器运行时故障
  • 内核 panic
  • 时钟偏移

中间件类

  • 数据库主库切换
  • 从库延迟
  • 连接数耗尽
  • 缓存击穿/雪崩
  • 消息队列分区不可用
  • 消费者 lag
  • 锁冲突/死锁

云与基础设施

  • 可用区故障
  • 负载均衡故障
  • 对象存储限流
  • 网络 ACL/安全组错误
  • 证书过期
  • IAM 权限失效

数据类

  • 数据损坏
  • 数据重复
  • 数据延迟
  • schema 不兼容
  • 分区丢失

安全类

  • 证书过期
  • Kerberos/Token 失效
  • 权限拒绝
  • 密钥轮换失败
  • 审计中断

工具选型

Chaos Mesh

版本:2.8.x(当前 2.8.6)

特点:

  • Kubernetes CRD:PodChaos、NetworkChaos、StressChaos、IOChaos、DNSChaos、TimeChaos、HTTPChaos、KernelChaos、JVMChaos、云厂商 Chaos 等
  • 组件:Chaos Dashboard、Chaos Controller Manager、Chaos Daemon(DaemonSet,默认 privileged)
  • Workflow/Schedule/StatusCheck 支持编排和持续实验
  • 适合 Kubernetes 原生、GitOps、多集群

注意:

  • Chaos Daemon 权限较高,必须限制 namespace/RBAC
  • 默认 privileged,生产要评估安全边界
  • 网络/内核故障依赖节点权限

ChaosBlade

版本:1.8.x(当前 1.8.2)

ChaosBlade 架构

图 1:ChaosBlade 官方整体架构

特点:

  • 阿里开源,CLI + chaosblade-box 平台
  • 支持主机、容器、Kubernetes、多语言(Java/Go/C++ 等)
  • 故障类型丰富,适合混合环境
  • 学习曲线比 Chaos Mesh 稍高

LitmusChaos

版本:3.33.0

LitmusChaos 概览

图 2:LitmusChaos 官方概览

特点:

  • CNCF 托管
  • ChaosHub、实验模板、Workflow、Probes
  • 适合 Kubernetes、GitOps、CI/CD
  • 有商业版和社区版

其他

  • Chaosd:物理机/节点级故障注入
  • AWS FIS:AWS 资源级故障注入
  • Gremlin:商业混沌工程平台
  • 自研:脚本/Operator,适合特定场景

选型对比

工具 范围 优势 注意
Chaos Mesh Kubernetes CRD、Workflow、生态好 Daemon 权限高
ChaosBlade 主机/容器/K8s 故障类型多、混合环境 平台化需额外建设
LitmusChaos Kubernetes CNCF、ChaosHub、Probes 实验模板需维护
AWS FIS AWS 云资源原生 绑定 AWS
Gremlin 商业 托管、易用 成本

Kubernetes 实验实战

安装 Chaos Mesh

helm repo add chaos-mesh https://charts.chaos-mesh.org
helm repo update
helm install chaos-mesh chaos-mesh/chaos-mesh \
--namespace chaos-mesh \
--create-namespace \
--set chaosDaemon.runtime=containerd \
--set chaosDaemon.socketPath=/run/containerd/containerd.sock

生产要固定版本、限制 RBAC、配置资源限制和 NetworkPolicy。

Pod Kill

apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
name: pod-kill
namespace: chaos-mesh
spec:
action: pod-kill
mode: one
selector:
namespaces: ["prod"]
labelSelectors:
app: web
duration: "30s"
scheduler:
cron: "@every 10m"

网络延迟

apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: net-delay
namespace: chaos-mesh
spec:
action: delay
mode: one
selector:
namespaces: ["prod"]
labelSelectors:
app: web
delay:
latency: "100ms"
correlation: "100"
jitter: "10ms"
direction: to
target:
mode: all
selector:
namespaces: ["prod"]
labelSelectors:
app: db
duration: "5m"

网络分区

apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: net-partition
namespace: chaos-mesh
spec:
action: partition
mode: all
selector:
namespaces: ["prod"]
labelSelectors:
app: web
direction: both
target:
mode: all
selector:
namespaces: ["prod"]
labelSelectors:
app: db
duration: "2m"

CPU/内存压力

apiVersion: chaos-mesh.org/v1alpha1
kind: StressChaos
metadata:
name: stress
namespace: chaos-mesh
spec:
mode: one
selector:
namespaces: ["prod"]
labelSelectors:
app: web
stressors:
cpu:
workers: 2
load: 80
memory:
workers: 1
size: "256MB"
duration: "5m"

DNS 故障

apiVersion: chaos-mesh.org/v1alpha1
kind: DNSChaos
metadata:
name: dns-error
namespace: chaos-mesh
spec:
action: error
mode: all
patterns:
- "db.prod.svc.cluster.local"
selector:
namespaces: ["prod"]
labelSelectors:
app: web
duration: "2m"

Workflow 编排

apiVersion: chaos-mesh.org/v1alpha1
kind: Workflow
metadata:
name: game-day
namespace: chaos-mesh
spec:
entry: entry
templates:
- name: entry
templateType: Serial
deadline: "30m"
children:
- delay
- kill
- name: delay
templateType: NetworkChaos
deadline: "5m"
networkChaos:
action: delay
mode: one
selector:
namespaces: ["prod"]
labelSelectors:
app: web
delay:
latency: "100ms"
duration: "5m"
- name: kill
templateType: PodChaos
deadline: "2m"
podChaos:
action: pod-kill
mode: one
selector:
namespaces: ["prod"]
labelSelectors:
app: web
duration: "30s"

生产环境安全

生产实验的底线:影响可控、可观测、可中止、可回滚。

Guardrail

  • 只允许指定 namespace/label
  • 禁止选择 kube-system、chaos-mesh、监控、etcd、Ingress 等关键组件
  • 设置最大持续时间、最大影响实例数
  • 生产实验必须审批
  • 实验期间 on-call 必须在岗
  • 有 kill switch
  • 有业务方确认

权限

  • Chaos 工具使用独立 ServiceAccount
  • 最小 RBAC,只允许目标 namespace/resource
  • 限制 CRD 创建权限
  • 审计所有实验创建/删除

爆炸半径

  • 从 1 个实例开始
  • 用 canary 租户/流量
  • 避开高峰和大促
  • 设置短持续时间
  • 先做只读/低风险故障

中止与恢复

  • 中止条件写进实验文档
  • 一键停止/删除 Chaos 资源
  • 确认恢复:Pod 重建、网络恢复、数据一致
  • 观察 SLO 回到基线

不要做的事

  • 在生产随机杀节点
  • 对控制面/存储核心组件做未演练的故障
  • 没有监控就注入
  • 没有回滚就注入
  • 用混沌实验“惩罚”团队

Game Day

Game Day 是组织级故障演练,不只是技术注入。

目标

  • 验证跨团队协作
  • 验证监控、告警、on-call
  • 验证 runbook 和升级路径
  • 验证故障转移和恢复
  • 发现流程和组织问题

角色

  • Coordinator:整体计划和安全
  • Incident Commander:事故指挥
  • Ops Lead:执行恢复
  • Comms Lead:沟通
  • Scribe:记录
  • Observers:业务/安全/管理层

流程

  1. 选题和范围
  2. 写场景和假设
  3. 准备监控、runbook、回滚
  4. 通知参与方
  5. 注入故障
  6. 观察、沟通、恢复
  7. 复盘和 action

场景示例

  • 核心服务 Pod 全部被杀
  • 数据库主库切换
  • 可用区故障
  • DNS 故障
  • 证书过期
  • Kafka 分区不可用
  • HDFS NameNode 切换

复盘

  • 时间线
  • 检测时间、响应时间、恢复时间
  • 哪些告警有效/无效
  • runbook 是否准确
  • 协作问题
  • action item 和 owner

故障演练矩阵

层级 场景 验证点
Pod 杀 Pod、OOM、镜像拉取失败 重启、探针、PDB
Service 网络延迟/丢包/分区、DNS 失败 超时、重试、熔断、降级
Node drain、宕机、kubelet 故障 迁移、PDB、容量
依赖 DB 主从切换、Redis 超时、MQ 不可用 连接池、重试、降级
区域 AZ 故障 多活、DNS 切流、RTO/RPO
平台 NameNode/RM/Kafka Controller/ZK Leader HA 切换、客户端恢复
安全 证书过期、Token 失效 告警、轮换、恢复
数据 数据损坏、重复、延迟 校验、补偿、恢复

Hadoop 平台的具体演练项可参考《Hadoop大数据平台运维》中的 NameNode/DataNode/RM/RegionServer/Kafka/ZK 演练。

可观测性要求

没有可观测性,混沌实验就是“盲炸”。

实验前

  • 基线:延迟、错误率、吞吐、容量
  • 看板:服务、依赖、基础设施
  • 告警:SLO burn rate、错误率、延迟、lag
  • Trace:关键链路
  • 日志:错误、超时、重试

实验中

  • 标记实验开始/结束
  • 记录注入参数和目标
  • 观察 SLO、错误率、延迟、饱和度
  • 观察依赖和下游
  • 记录异常和恢复动作

实验后

  • 对比基线
  • 确认恢复
  • 归档实验记录
  • 更新 runbook 和监控

告警处理

实验期间可以临时调整告警,但不要完全静音:

  • 保留 SLO/业务告警
  • 抑制已知的实验噪音
  • 确保真实故障仍能触发

自动化与 CI/CD

混沌即代码

  • 实验定义进 Git
  • 通过 GitOps 部署
  • 版本化、可审计、可回滚
  • 代码评审实验范围和风险

流水线

  • 预发:每次发布后跑基础实验
  • 生产:定时/灰度跑低风险实验
  • 灾备:定期跑切换/恢复
  • 结果自动判定,失败阻断发布

调度

  • Chaos Mesh Schedule
  • Litmus Workflow
  • CI cron
  • 避开业务高峰

防止“自动化事故”

  • 实验有最大范围/时长
  • 有 kill switch
  • 有审批和审计
  • 失败自动停止
  • 不要在没有监控的环境自动跑

度量体系

实验覆盖

覆盖率 = 有混沌实验的核心服务数 / 核心服务总数

按服务、依赖、故障类型分别看。

故障响应

  • 检测时间(MTTD)
  • 响应时间
  • 恢复时间(MTTR)
  • SLO 影响
  • 错误预算消耗

实验效果

  • 假设成立率
  • 发现问题数
  • action 完成率
  • 复发率
  • 事故数量/严重度趋势

不要用的指标

  • 实验次数(容易刷)
  • 注入故障数(不看价值)
  • “杀了多少 Pod”
  • 用实验数量排名团队

组织与治理

团队模型

  • SRE/平台团队负责工具、标准、guardrail
  • 业务团队负责自己的实验和修复
  • 安全团队审查权限和高风险实验
  • 管理层支持时间和资源

风险分级

级别 范围 审批
低 预发/单实例 团队自审
中 生产 canary SRE + 业务
高 核心链路/区域 平台负责人 + 业务负责人
极高 控制面/全量 变更委员会

文化

  • 复盘无指责
  • 鼓励主动发现问题
  • 不把实验失败当绩效问题
  • 把 action 跟踪到底
  • 共享故障案例

常见反模式

  • 没有假设,直接杀 Pod
  • 没有稳态指标
  • 没有中止条件
  • 生产实验不通知
  • 没有监控和 trace
  • 只做 Pod kill,不做网络/依赖/区域
  • 实验后不修复
  • 自动化没有 guardrail
  • 用混沌实验惩罚团队
  • 把 Game Day 做成表演
  • 只做一次,不做持续实验

模板

实验文档模板

实验名称:
Owner:
日期/时间:
目标服务:
依赖:
稳态指标与基线:
假设:
故障类型/参数:
影响范围:
持续时间:
中止条件:
回滚/恢复:
通知对象:
看板/告警:
结果:
Action:

Game Day Runbook

目标:
范围:
参与角色:
场景:
时间线:
注入步骤:
观测指标:
沟通渠道:
中止条件:
恢复步骤:
复盘时间:

复盘模板

标题:
影响:
时间线:
检测:
响应:
恢复:
根因:
促成因素:
做得好的:
需要改进:
Action(owner/日期):

案例

案例 1:Pod Kill 验证高可用

  • 假设:杀掉 1 个 web Pod,成功率仍 ≥ 99.9%
  • 注入:PodChaos pod-kill,mode one
  • 观察:Service Endpoint 摘除、Pod 重建、错误率
  • 结果:成功率短时下降到 99.5%,1 分钟后恢复
  • 改进:增加 readinessProbe、PDB、预热

案例 2:数据库网络延迟

  • 假设:DB 延迟 100ms,接口 P95 < 500ms
  • 注入:NetworkChaos delay
  • 观察:连接池、超时、重试、熔断
  • 结果:连接池耗尽,P95 超过 2s
  • 改进:调连接池、超时、熔断、降级

案例 3:可用区故障

  • 假设:一个 AZ 不可用,服务仍可用
  • 注入:Node drain/AZ 隔离
  • 观察:Pod 迁移、PDB、DNS 切流、RTO
  • 结果:部分有状态服务恢复超时
  • 改进:多 AZ 部署、PDB、备份恢复演练

案例 4:Kafka Broker 故障

  • 假设:停 1 个 Broker,生产/消费不中断
  • 注入:Pod kill/网络隔离
  • 观察:ISR、leader 选举、lag
  • 结果:ISR 收缩,短时延迟升高
  • 改进:副本因子、min.insync.replicas、容量

案例 5:NameNode 切换

  • 假设:Active NameNode 宕机,HDFS 自动切换
  • 注入:停 Active NameNode
  • 观察:ZKFC、JournalNode、客户端重试
  • 结果:切换成功,部分作业重试
  • 改进:客户端重试配置、监控、演练频率

附录

常用命令

# Chaos Mesh
kubectl get podchaos,networkchaos,stresschaos -A
kubectl describe podchaos <name> -n chaos-mesh
kubectl delete podchaos <name> -n chaos-mesh

# ChaosBlade
blade create cpu load --cpu-percent 80
blade create network delay --time 3000 --interface eth0
blade status <uid>
blade destroy <uid>

# Litmus
kubectl get chaosengine -A
kubectl get chaosresult -A

官方参考