mcpField
C
chaos-engineering

chaos-engineering

github.com/petrkindlmann测试与质量2221.1k 次安装6 天前更新
代码仓库

关于 chaos-engineering

面向负责系统可靠性的工程团队,提供以假设为驱动的混沌工程实验流程,帮助在受控范围内发现韧性缺口。内容涵盖故障注入、实时观测、恢复分析和团队演练,并介绍多种工具。

主要功能

  1. 01制定稳态假设与指标
  2. 02受控注入网络及服务故障
  3. 03实时观察系统表现
  4. 04检查恢复过程与数据完整性
  5. 05规划团队故障演练

适用场景

  1. 01验证数据库故障切换行为
  2. 02测试第三方依赖不可用时的降级
  3. 03评估网络延迟或丢包影响
  4. 04通过演练练习事故响应

MCP 相关

README 提及 LitmusChaos 提供 MCP 服务,可连接 AI 助手与 ChaosCenter。MCP 客户端可用自然语言列出、运行和停止实验。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/petrkindlmann/qa-skills --skill chaos-engineering

安装后在 Claude Code 中输入/chaos-engineering确认已加载。

附带文件references/fault-injection.md

详细介绍

混沌工程是一种通过对系统进行实验,增强人们对系统承受动荡条件能力的信心的方法。它不是随机破坏——而是由假设驱动的受控实验,旨在问题导致服务中断前将其揭示出来。某个重试机制在演示中“运行正常”,但当支付 API 超时时,可能会悄无声息地向客户重复收费;只有注入超时并观察,才能知道实际情况。

快速导航

情况前往
首次进行实验,团队经验不足从小处着手 → 前三个实验
设计一项实验混沌实验工作流(5 个步骤)
为你的环境选择工具工具 → 工具选择决策树
组织团队演练混沌演练规划
需要可运行的故障注入命令/配置references/fault-injection.md
希望无需人工介入即可触发中止references/fault-injection.md → 自动中止

调研问题

先检查 .agents/qa-project-context.md。如果文件存在,请将其作为上下文,并跳过其中已有答案的问题。

环境与准备情况:

  • 混沌实验将在何处运行?(仅限预生产环境、经批准后在生产环境运行、绝不在生产环境运行)
  • 团队的监控成熟度如何?能否实时检测问题?
  • 团队是否演练过事故响应?是否有运行手册?
  • 管理层是否支持混沌工程?(对于生产环境实验尤为重要)

架构:

  • 架构是什么?(单体、微服务、无服务器、混合)
  • 关键依赖有哪些?(数据库、缓存、消息队列、第三方 API)
  • 是否存在单点故障?(单一数据库、单一区域、没有冗余)
  • 有哪些冗余和故障转移机制?

当前的韧性实践:

  • 服务是否配置了健康检查?检查哪些内容?
  • 是否配置了熔断器、重试逻辑或超时?
  • 依赖不可用时会发生什么?(优雅降级、硬故障、未知)
  • 是否遇到过意外中断?哪些环节发生了故障?

团队与文化:

  • 团队是否能坦然面对受控故障?(感到焦虑很正常,应该予以应对)
  • 谁可以担任混沌工程的负责人?(需要有人负责推动这项实践)
  • 团队倾向于如何起步?(从小处着手还是直接深入)

核心原则

1. 由假设驱动:注入故障前先定义预期行为

每项混沌实验都从一个假设开始:“我们认为,如果发生[故障 X],系统将表现为[预期行为 Y]。”没有假设,你只是在破坏东西。假设要明确具体的稳态指标(基准指标)——错误率、延迟、吞吐量——以及每项指标可变化到的界限。

假设示例:“我们认为,如果主数据库不可用,应用将为读取请求提供缓存数据,并将写入请求排队最多 5 分钟,且用户不会看到错误。影响范围:预发布环境、一个服务。稳态基准:错误率 <0.1%,P95 延迟 <300ms。”

2. 从小处着手:单个服务,控制影响范围

第一次混沌实验不应该是“关闭生产环境”。更合适的做法是“在预发布环境中,为一个非关键服务增加 200ms 延迟”。随着信心和工具逐步成熟,再逐渐扩大范围。

3. 监控是前提条件

如果无法实时检测问题,就无法安全地注入故障。没有监控的混沌实验只是多了几道步骤的服务中断。运行任何实验前,请先确认仪表板、告警和 on-call 流程均已就绪。

4. 混沌演练能够培养肌肉记忆

在自动化流水线中运行混沌实验很有价值,但混沌演练——团队定期一起运行实验并练习响应的活动——能够培养在真实事故中至关重要的应对能力。


混沌实验工作流

每项混沌实验都遵循以下五步流程。

步骤 1:定义稳态假设

确定定义“正常”的指标,并预测实验期间应该发生什么。

Experiment: Database failover
Steady state:
  - Error rate: < 0.1%
  - P95 latency: < 300ms
  - Successful orders per minute: > 50

Hypothesis: When the primary database fails over to the replica,
  - Error rate will spike to < 2% for < 30 seconds
  - P95 latency will increase to < 1s for < 60 seconds
  - No orders will be permanently lost
  - The application will recover without manual intervention
步骤 2:引入变量

以可控方式注入故障,并明确范围和持续时间。

Injection:
  Target: primary database (PostgreSQL)
  Method: block TCP port 5432 on the primary instance
  Scope: single database instance
  Duration: 60 seconds
  Blast radius: staging environment only (first run)

  Abort conditions:
    - Error rate > 10% for > 2 minutes
    - Any data corruption detected
    - Manual abort by experiment owner
步骤 3:观察

实验期间,实时监控所有相关指标。安排观察人员负责特定仪表盘。

Observation assignments:
  - Engineer A: application error rate and latency dashboard
  - Engineer B: database metrics (connections, replication lag, failover status)
  - Engineer C: application logs (search for database connection errors)
  - Engineer D: business metrics (order count, payment processing)
步骤 4:分析恢复情况和数据完整性

实验结束后,分析实际情况与预期情况之间的差异。

Analysis checklist:
  - Did the system behave as hypothesized? (Y/N, with details)
  - How long was the impact? (Expected vs. actual duration)
  - Were any errors visible to users?
  - Was any data lost or corrupted?
  - Did monitoring and alerting detect the problem correctly?
  - How long before alerts fired?
  - What was the recovery time?
步骤 5:修复并迭代

记录发现的问题,修复弹性方面的不足,并安排重新运行以验证修复效果。

Findings document:
  Experiment: Database failover (2026-03-20)
  Hypothesis: Confirmed / Partially confirmed / Disproved
  Recovery time: 45s (expected vs actual: expected <10s, actual 45s)
  Data integrity: no rows lost; 3 writes returned 500 instead of queueing

  Findings:
    - Connection pool did not detect stale connections for 45 seconds (expected: <10s)
    - Retry logic worked correctly for read operations
    - Write operations returned 500 errors for 38 seconds (expected: queued)

  Action items (every one has an owner and a due date — no item is deferred):
    - [ ] Configure connection pool health checks — assigned to @maria, due 2026-03-31
    - [ ] Implement write queue with 5-minute buffer — assigned to @dan, due 2026-04-02
    - [ ] Re-run experiment after fixes deployed (re-run scheduled 2026-04-03);
          specific metrics to check on re-run: stale-connection detection <10s,
          zero write 500s, error rate <2%

故障注入类型

网络故障
故障工具用例
注入延迟tc, toxiproxy, Gremlin模拟网络缓慢、远距离区域
丢包tc netem, Chaos Mesh模拟不可靠网络
DNS 故障iptables, CoreDNS manipulation模拟 DNS 中断
网络分区iptables, Chaos Mesh模拟脑裂场景
带宽限制tc, toxiproxy模拟网络拥塞

有关 tc netem 延迟/丢包命令和 toxiproxy 延迟配置,请参阅 references/fault-injection.md。

服务故障
故障方法用例
服务崩溃终止进程、删除 pod模拟意外崩溃
服务变慢CPU 压力测试、线程池耗尽模拟服务过载
注入错误返回 500/503、抛出异常模拟应用程序错误
内存压力stress-ng, Chaos Mesh模拟内存泄漏

有关 kubectl delete pod 命令和 LitmusChaos pod-delete ChaosEngine 清单,请参阅 references/fault-injection.md。

基础设施故障
故障方法用例
磁盘已满fallocate, dd模拟磁盘耗尽
CPU 耗尽stress-ng模拟 CPU 饱和
内存耗尽stress-ng模拟 OOM 情况
时钟偏移chrony manipulation, timedatectl模拟时间漂移

有关 fallocate 磁盘填充命令和 stress-ng CPU/内存命令,请参阅 references/fault-injection.md。

依赖项故障
故障方法用例
API 宕机toxiproxy, mock server模拟第三方服务中断
数据库不可用封锁端口、终止进程模拟数据库中断
缓存不可用封锁 Redis 端口模拟缓存未命中风暴
消息队列已满填满队列、阻止消费者模拟背压

有关以编程方式集成 toxiproxy、禁用 Redis 并断言系统可优雅降级的测试,请参阅 references/fault-injection.md。


工具

工具类型最适合
LitmusChaos (3.29.x)Kubernetes 原生,CNCFK8s 环境、CI/CD 集成;ChaosCenter UI;用于 GameDay 即代码的工作流;MCP 服务(2025 年 10 月)可通过 AI 助手驱动实验
Chaos Mesh (2.8.x)Kubernetes 原生,CNCF需要精细控制的 K8s 环境;通过 bpfki 运行时实现 eBPF 混沌注入,精确模拟内核级故障
AWS FISAWS 托管服务针对 AWS 工作负载(EC2、ECS、RDS、EKS)的云混沌工程;通过 CloudWatch 警报停止条件自动中止——首选云原生方案
Gremlin托管平台希望获得引导式实验和合规报告的团队;SLO 违反时,Health Checks 会停止并回滚
Steadybit托管平台覆盖 Kubernetes、云和本地环境的可靠性中心;Gremlin 的直接替代方案
kube-monkey开源当 Litmus/Chaos Mesh 显得过于繁重时,可选用轻量级 K8s 替代方案
Pumba开源仅针对 Docker 的混沌工程(容器、网络);适用于 K8s 之前的环境和边缘环境
toxiproxy网络代理,开源在集成测试中注入网络故障
tc (traffic control)Linux 内核网络延迟和丢包
stress-ngLinux 工具CPU、内存和磁盘压力测试
k6 (+ xk6-disruptor)负载测试工具结合负载与混沌的场景

避免在新项目中使用 Chaos Monkey (Netflix)——活跃度低,且只能走 Spinnaker 方案(截至 2026 年年中)。 它仍然可用,仓库也未归档,但只能注入实例终止故障,并且需要 Spinnaker 部署流水线。全新项目应选择 Chaos Mesh、LitmusChaos 或 AWS FIS。(较早的 SimianArmy 仓库已于 2021 年归档;请勿将两者混淆。)

选择工具
Decision tree:
  Running on Kubernetes?
    → Cloud-managed AWS workloads: AWS FIS (cloud-native, IAM-integrated)
    → On K8s with sidecar tolerance: Chaos Mesh (eBPF, fine-grained)
    → On K8s wanting workflows + UI: LitmusChaos (ChaosCenter, Workflows)
    → On K8s lightweight: kube-monkey

  Running on plain VMs / Docker?
    → Docker only: Pumba
    → Linux: tc + stress-ng (manual)

  Need network fault injection in integration tests?
    → toxiproxy (lightweight, programmatic API)

  Need to combine load testing with chaos?
    → k6 with xk6-disruptor extension

  Need managed platform with UI and compliance?
    → Gremlin or Steadybit (both commercial)
GameDay 即代码

2026 年的趋势是将混沌工程作为定期调度的 CI 作业,而非临时活动:Litmus Workflows、Steadybit 可靠性中心和 Gremlin Scenarios 都支持将混沌测试定义为 YAML,并通过 CI 中的 cron 定时触发。请结合下方的 Game Day 规划部分——人为实践仍然重要;自动化只是消除了“我们一直没时间安排”的瓶颈。有关具体的 cron 门控流水线(在非高峰时段每晚删除 Pod),以及自动中止/停止条件示例,请参阅 references/fault-injection.md。

LitmusChaos 于 2025 年 10 月推出了 MCP 服务,可将 Claude 等 AI 助手直接连接到 ChaosCenter:你可以用自然语言列出、运行和停止实验(“在前端 Pod 上运行 pod-delete”、“停止网络延迟实验”),无需手写 YAML。如果你的团队已经通过 AI Agent 驱动运维,这项功能就很适用。


Game Day 规划

Game Day 是一场定期安排的会议,团队会共同运行混沌实验、练习事件响应,并增强对系统韧性的信心。

准备清单
2 weeks before:
  - [ ] Define 2-3 experiments to run (don't overload the schedule)
  - [ ] Write hypotheses for each experiment
  - [ ] Get approval from engineering leadership and affected teams
  - [ ] Notify support team and stakeholders
  - [ ] Verify monitoring and alerting are working
  - [ ] Identify rollback procedures for each experiment
  - [ ] Schedule 3-4 hour block (experiments + analysis + retro)

1 day before:
  - [ ] Confirm all participants and their roles
  - [ ] Test that fault injection tools work in the target environment
  - [ ] Verify rollback procedures work (dry run)
  - [ ] Prepare dashboards and observation assignments
  - [ ] Brief the on-call team
  - [ ] Confirm abort criteria for each experiment
沟通与角色

在活动前(安排时间、范围、中止权限)、活动期间(在专用频道中每 15 分钟发布实时更新)和活动后(在 24 小时内总结发现和待办事项)进行沟通。

为每项实验分配角色:实验负责人(运行实验并决定是否中止)、观察员(关注应用指标、基础设施指标、日志和用户体验)以及记录员(记录时间线和决策)。

活动后回顾

针对每项实验:假设是否得到验证?有哪些意外发现?有哪些待办事项?针对流程:监控是否检测到问题?警报是否触发?我们是否能接受影响范围?最后列出待办事项(注明负责人和截止日期),并安排下一次 Game Day。


从小处着手:前三项实验

对于刚接触混沌工程的团队,请先在预生产环境中开展以下三项实验。

实验 1:数据库变慢

为何首先开展: 数据库延迟是导致用户感知变慢的最常见原因,而且这项实验易于设置和还原。

Hypothesis: When database latency increases by 500ms, the application
will remain functional with response times under 3 seconds.

Injection: Add 500ms latency to the database connection using toxiproxy.
Duration: 5 minutes.
Environment: staging.

What to observe:
  - Application response times (should increase by ~500ms, not 10x)
  - Connection pool behavior (should not exhaust connections)
  - Timeout handling (requests should not hang indefinitely)
  - Circuit breaker activation (if implemented)
  - Cache effectiveness (cached reads should be unaffected)
实验 2:第三方 API 返回 500 错误

**为何排第二:**第三方依赖经常发生故障,而应用对这些故障的处理通常未经测试。

Hypothesis: When the payment provider returns 500 errors, the
application will show a user-friendly error message and allow
retry without duplicate charges.

Injection: Configure mock/proxy to return 500 for payment API calls.
Duration: 10 minutes.
Environment: staging.

What to observe:
  - Error message quality (user-friendly, not stack traces)
  - Retry behavior (does the application retry? How many times?)
  - Idempotency (retries don't create duplicate transactions)
  - Fallback (is there an alternative payment path?)
  - Monitoring (does the payment failure show up in alerts?)
实验 3:缓存不可用

**为何排第三:**缓存故障会引发“惊群”问题,导致所有流量突然涌向数据库,往往进而造成级联故障。

Hypothesis: When Redis becomes unavailable, the application will fall
back to direct database queries with degraded but functional performance.

Injection: Block Redis port using toxiproxy or iptables.
Duration: 5 minutes.
Environment: staging.

What to observe:
  - Database query volume (should increase but not overwhelm)
  - Response times (should increase but remain under 5 seconds)
  - Error rate (cache miss should not cause errors)
  - Connection pool (database connections should not exhaust)
  - Recovery (when cache returns, does the application resume normal behavior?)

反模式

混沌实验缺少监控

在无法观察故障影响的情况下注入故障,不是混沌工程——而是蓄意破坏。直到用户投诉,你才会知道实验是否暴露了问题。

**解决方法:**进行任何混沌实验之前,请确认你可以实时查看错误率、延迟、吞吐量和依赖项健康状况。如果做不到,请先投入资源完善监控。还可以更进一步,将监控接入实验,使其在超出阈值时自动中止——例如 AWS FIS CloudWatch 停止条件、Gremlin Health Checks,或在 mode: Continuous 下使用 Litmus 的 promProbe(参见 references/fault-injection.md)。

一开始就做得太大

第一次混沌实验不应该是“干掉生产数据库”。团队还没有通过低影响实验积累经验,就开始高影响实验,会让大家焦虑,也可能导致真实故障。

**解决方法:**从预发环境开始。从非关键服务开始。从可逆的故障注入开始(例如延迟,而不是数据损坏)。逐步建立信心。只有多次成功完成预发环境实验后,才进入生产环境。

没有回滚计划

“实验只有 60 秒,不需要回滚计划。”然后故障注入工具崩溃,故障就会无限期持续(这正是 5 分钟的 tc 延迟注入在命令中途失败后变成 2 小时中断的原因)。

**解决方法:**每项实验都必须有书面回滚流程,并且能在 30 秒内执行。运行实验前先测试回滚,并安排第二个人待命;如果实验负责人无法操作,由其立即中止实验。优先选择由工具强制执行停止条件的方案,而不是依赖人工按下停止开关(参见 references/fault-injection.md 中的“自动中止”)——并选择内置超时的注入方式(如 stress-ng --timeout、Litmus TOTAL_CHAOS_DURATION),确保即使无人监看,故障也会自行清除。

未经批准就在生产环境进行混沌实验

未经工程领导层和受影响团队明确批准,就在生产环境运行混沌实验,会损害信任,也会断送职业生涯。

**解决方法:**每次在生产环境运行之前:取得工程领导层明确且有记录的批准;通知受影响的团队,并向值班团队和支持团队做简要说明;沟通范围和持续时间,并将中止标准告知明确指定的中止负责人;确认爆炸半径已限制在可行的最小目标范围内。先从预发环境开始。任何一项准备工作被跳过,都可能让受控实验演变成事故。

在事故期间运行混沌实验

系统已经出现问题时再人为注入故障,会增加诊断难度并延长中断时间。

**解决方法:**如果系统未处于稳定状态,请取消或推迟混沌实验。开始之前检查是否有正在处理的事故。如果实验期间发生无关事故,请立即中止实验。

未跟进实验发现

实验发现断路器工作不正常。团队说了句“有意思”,就继续做别的事。这个问题始终没有修复。下次真实故障发生时,同样的问题再次出现。

**解决方法:**为每项混沌实验发现的问题创建工单,并指定负责人和截止日期。修复后重新运行实验以验证结果。将混沌实验发现的问题积压与生产事故行动项一并跟踪。


验证

在信任任何一次真实实验之前,先证明安全机制确实有效——从未触发过的中止路径只是一个假设,不是控制措施。先做最小规模的检查:

  1. 在预发布环境中注入并恢复。 执行影响范围最小的注入(例如 tc qdisc add dev eth0 root netem delay 200ms),作用于一个预发布服务;确认稳态仪表板上的数据发生变化,然后运行文档中说明的回滚命令(tc qdisc del dev eth0 root),并确认指标恢复到基线。记录回滚耗时——必须在规定的时间窗口内完成(少于 30s)。
  2. 触发自动中止。 在配置了 AWS FIS CloudWatch 停止条件、Gremlin Health Check 或处于 mode: Continuous 模式的 Litmus promProbe 的实验中,强制让受监控指标超过阈值(将错误率推高到停止条件之上)。确认实验在无需人工干预的情况下自动停止。如果未触发,则中止机制尚未经过验证(参见 references/fault-injection.md)。
  3. 确认超时后自动清除。 启动有时限的注入(stress-ng --cpu 4 --timeout 60s,或 Litmus TOTAL_CHAOS_DURATION: '60'),然后离开现场。确认即使无人中止,故障也会在截止时间自行清除。
  4. 确认问题发现闭环。 在预发布环境中运行后,确认已生成问题发现文档,其中包含基线与实际数据的对比,并且每个差距都已转化为分配了负责人的跟踪工单——实验记录才是交付物,而不是注入操作。

如果无法在预发布环境中演示步骤 1–3,则不得将该实验提升至生产环境。


完成标准

  • 每项实验在注入任何故障前,都有记录在案的书面假设(“我们认为,如果发生 [故障 X],系统将 [预期行为 Y]”)
  • 明确限定影响范围——目标范围、持续时间和中止条件都记录在实验记录中;任何实验在生产环境运行前,同一实验必须至少在预发布环境成功运行一次
  • 每项实验记录都附有稳态快照(仪表板链接或实际基线指标值),并且是在注入前立即采集的
  • 每项实验都有一份问题发现文档,包含基线与实际数据的对比、恢复时间,以及明确的数据完整性检查(是否丢失/损坏:是/否)
  • 发现的每个弱点都有一个跟踪工单,其中指定了负责人和截止日期,并安排重新运行同一实验以验证修复效果

参考文件(位于 references/ 中)

  • fault-injection.md — 用于注入各类故障的可运行命令、配置和测试代码:tc netem 和 toxiproxy 网络故障、kubectl/LitmusChaos 服务故障(带有 engineState: active 的 ChaosEngine)、fallocate/stress-ng 基础设施故障、程序化的 toxiproxy 依赖故障测试,以及自动中止/停止条件示例(AWS FIS、Gremlin、Litmus 探针、Litmus MCP)和由 cron 控制的持续混沌 CI 任务。

相关技能

  • testing-in-production — 适用于发布期间的安全渐进发布机制(功能标志、金丝雀发布、暗发布)。混沌工程会有意制造故障以发现弱点;生产环境测试则控制暴露范围,确保故障不会扩散。渐进发布请参阅该技能,故障注入请参阅本技能。
  • observability-driven-testing — 当生产遥测数据(跟踪、日志、错误模式)是设计测试或实验的输入时使用。它为假设提供依据;混沌工程则负责验证或证伪该假设。可观测性也是安全开展混沌实验的硬性前提。
  • performance-testing — 负载测试可与混沌测试互补;结合负载与故障,模拟真实的故障场景(参见 k6 + xk6-disruptor)。
  • release-readiness — 混沌实验结果可用于评估发布是否就绪并决定是否放行。
  • test-environments — 预生产环境是开展混沌实验的安全起点。
  • qa-metrics — 混沌实验结果(恢复时间、错误影响)是值得跟踪的质量指标。

评论

支持 Markdown