生产环境搞混沌实验,别拿线上用户当小白鼠

简介: 生产环境搞混沌实验,别拿线上用户当小白鼠

生产环境搞混沌实验,别拿线上用户当小白鼠

作者:Echo_Wish

做运维这些年,我发现一个挺有意思的现象:有些团队平时把高可用挂在嘴边,架构图上画着多副本、负载均衡、自动故障转移,监控面板也挺漂亮。可真到了某个 Pod 挂掉、网络突然抖动的时候,整个系统还是可能跟着趴窝。

为什么?

因为架构设计里写着“支持故障”,不代表系统真的经历过故障;平时看起来正常,也不代表异常发生时能够正常运行。

所以,混沌工程这件事,我一直觉得很有必要。

但这里有个前提:我们是为了验证系统能不能扛住故障,不是为了证明运维有多敢折腾。

尤其是在生产环境里,实验做得好,可以提前发现问题;实验做得不好,自己制造的故障就可能变成真正的生产事故。

今天就聊聊,怎么借助 Chaos Mesh 和 Litmus,在生产环境中安全地开展混沌实验,以及我认为必须守住的几条底线。

一、先搞清楚:混沌实验到底在验证什么?

先举个比较常见的例子。

一个订单服务部署了三个 Pod,前面挂着负载均衡。架构设计告诉我们,即使一个 Pod 挂掉,另外两个 Pod 也能继续处理请求。

听起来没什么问题。

但真实环境里,我们还有一堆需要验证的事情:

一个 Pod 被删除之后,流量能不能及时切走?服务发现需要多长时间才能感知变化?剩余两个 Pod 扛不扛得住突然增加的请求?连接池会不会被打满?下游数据库会不会跟着过载?

这些问题,光看 YAML 配置是得不到可靠答案的。

混沌实验的核心,不是制造故障,而是验证我们对系统的判断到底对不对。

比如,我们可以提出这样一个假设:

“如果订单服务的一个实例出现短暂网络延迟,剩余实例仍然能够正常处理请求,整体错误率不会超过预定阈值,核心业务不会中断。”

接下来,我们才有理由设计实验。

这里有三个关键点。

第一,故障必须明确。到底是增加网络延迟、删除一个 Pod,还是限制 CPU?一次实验最好只验证一个主要变量,否则多个故障叠加之后,出了问题很难判断真正原因。

第二,成功条件必须明确。不能实验结束后发现服务没挂,就宣布实验成功。我们还得看错误率、响应时间、请求成功率、队列积压,以及实际业务是否正常。

第三,实验必须有退出条件。一旦超出预设的风险边界,就应该停止注入故障,而不是想着“再观察几十秒,说不定就恢复了”。

举个例子,针对一个订单 API,可以在实验开始前约定:

  • 请求成功率不能低于业务 SLO 要求。
  • P95 响应时间不能持续超过预定上限。
  • 错误率达到预设阈值时立即停止实验。
  • 订单创建、支付状态等关键业务不能发生异常。

阈值具体设多少,需要根据业务 SLO、平时的基线和可接受的风险来定,而不是所有系统统一套一个数字。

这样一来,混沌实验就有了明确的目标,也有了可以判断成败的依据。

二、第一条底线:先控制影响范围,再谈故障注入

不少人第一次接触 Chaos Mesh,觉得最简单的实验就是删一个 Pod。

这确实容易理解,但这里有个很容易忽略的问题:你删掉的到底是哪一个 Pod?

如果选择范围配置得过宽,原本只是想测试订单服务的一个副本,结果把整个服务的 Pod 都纳入了实验范围,事情就完全变了。

Chaos Mesh 支持通过 Namespace、Label Selector 等选择器限制实验目标。在实验配置里,目标范围不是一个可有可无的字段,而是控制故障影响面的第一道防线。

假设我们要测试一个专门划分出来的订单服务金丝雀实例,第一步应该是确认目标:

kubectl get pods \
  -n prod-canary \
  -l app=checkout-canary \
  --show-labels

这里的 prod-canary 和 checkout-canary 是示例名称,需要替换成真实环境中的命名空间和标签。

先看命令返回了哪些 Pod,再确认这些实例是否真的属于本次实验允许影响的范围。

别小看这一步。很多线上误操作,根本不是技术手段有问题,而是执行之前没有核对对象。

接下来,我们用 Chaos Mesh 模拟一次短暂的网络延迟。

apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
  name: checkout-canary-delay
  namespace: chaos-mesh
spec:
  action: delay
  mode: one

  selector:
    namespaces:
      - prod-canary
    labelSelectors:
      app: checkout-canary

  delay:
    latency: "100ms"

  duration: "30s"

这份配置表达的意思很直接:针对指定命名空间内符合标签条件的 Pod,选择其中一个目标,注入持续 30 秒的网络延迟,然后结束实验。

执行前,还需要确认当前 Chaos Mesh 版本支持相应字段,并确保标签选择结果符合预期。实际网络影响方向和范围,也要结合业务调用链确认。

我个人比较反感一种做法:先把故障注入进去,出问题再考虑怎么控制范围。

正确的顺序应该反过来:先限定对象,再设定故障强度,最后才是执行。

对于生产环境,建议优先选择专门的金丝雀实例、可隔离的流量路径和明确授权的命名空间。数据库、消息中间件、共享网络等关键基础设施,不应该因为测试一个普通应用,就顺手纳入实验范围。

尤其是有状态服务,删除实例和模拟轻微网络延迟的风险完全不是一个量级。不要拿破坏真实业务数据来验证所谓的系统韧性。

三、第二条底线:实验一定要有自动结束机制

做生产实验,最怕的不是故障注入成功,而是故障注入成功以后,没有按预期结束。

例如,你原本只想增加 30 秒网络延迟,结果忘记清理实验对象,影响一直持续,直到业务监控报警才发现问题。

这种错误听起来低级,却是生产自动化中必须认真防范的风险。

Chaos Mesh 官方文档明确说明,配置了 duration 的实验可以在指定时间后自动结束;暂停或者删除实验对象,也可以触发故障恢复。若没有设置 duration,故障可能会持续到实验被暂停或删除为止。

所以,生产实验里至少要有两层保障。

第一层是自动结束。

duration: "30s"

第二层是人工停止手段。

例如,针对前面创建的实验,可以使用:

kubectl annotate networkchaos checkout-canary-delay \
  -n chaos-mesh \
  experiment.chaos-mesh.org/pause=true \
  --overwrite

这个命令用于暂停相应的 Chaos Mesh 实验,并触发故障恢复。执行前要确认对象名称、命名空间和当前工具版本的行为。

更重要的是,停止实验的权限和操作方式,必须在实验开始之前就准备好。

别等到线上已经开始报错,才发现自己没有对应集群的操作权限,也不知道哪个对象负责注入故障。

我建议每次生产实验至少确认这些事情:

  • 自动结束时间已经配置,并经过预检查。
  • 当班人员知道实验目标、实验时段和停止命令。
  • 能够观察故障是否真正撤销,而不只是命令返回成功。
  • 实验结束后,业务指标能够恢复到合理水平。

这里还有一个容易被误解的地方:故障注入停止了,不等于系统立即恢复正常。

例如,网络延迟消失以后,积压的消息可能还需要时间消费,失败请求可能触发重试,连接池也可能需要重新建立连接。

所以,结束实验之后仍然要观察恢复情况。真正的恢复标准,是业务回到预期状态,而不是故障对象消失了。

四、第三条底线:不要只看 Pod,要盯住业务 SLO

混沌实验中,我最不喜欢看到这样的结论:

“Pod 没有挂,实验通过。”

这句话几乎没有什么参考价值。

Pod 没有挂,可能是因为系统足够健壮,也可能是因为注入的故障太轻;接口还可以访问,也不意味着订单提交、库存扣减等关键业务没有问题。

所以实验的观察指标,必须与一开始提出的假设对应起来。

如果实验目标是验证网络延迟对订单服务的影响,就应该同时观察请求成功率、P95 响应时间、错误率和下游依赖的情况。如果目标是验证消费者故障恢复,就应该关注消息积压量、消费速度和重复处理情况。

更进一步,最好能够把这些检查自动化。

这也是 Litmus 比较值得利用的一项能力:它支持使用 HTTP、命令、Kubernetes 资源状态和 Prometheus 查询等 Probe,验证实验前后的系统状态,以及故障注入期间的指标表现。

例如,我们可以使用 Prometheus 指标检查订单服务的 5xx 错误率。

下面这段是 Litmus ChaosEngine 中的 Probe 配置片段,展示了如何在故障注入期间持续检查错误率,并在检查失败时请求停止故障执行。

probe:
  - name: checkout-error-rate
    type: promProbe

    promProbe/inputs:
      endpoint: "http://prometheus.monitoring:9090"
      query: |
        100 *
        sum(rate(http_requests_total{
          service="checkout",
          status=~"5.."
        }[2m]))
        /
        clamp_min(
          sum(rate(http_requests_total{
            service="checkout"
          }[2m])),
          0.001
        )

      comparator:
        criteria: "<="
        value: "1"

    mode: "Continuous"

    runProperties:
      probeTimeout: 5s
      interval: 5s
      retry: 1
      probePollingInterval: 5s
      stopOnFailure: true

这里的 1 表示错误率不超过 1%。PromQL 中的指标名称和标签只是示例,必须根据自己系统的实际埋点进行调整。

另外,这个查询使用了分母下限来避免除零问题,但在没有请求流量时也可能得到看似正常的结果。因此,真实生产配置还应增加请求量或探测请求检查,防止把“没有流量”误判成“服务健康”。

值得特别说明的是,Litmus 的 stopOnFailure 可以配置在 Probe 的运行属性里,用于在检查失败后停止相应故障执行;Probe 结果也会参与实验结果判定。

不过,我们不能把它当成绝对可靠的保险。

如果 Prometheus 自己不可用、指标采集延迟,或者查询语句本身存在错误,自动判定机制也可能无法按预期工作。对高风险实验来说,指标检查必须配合独立的监控告警、人工停止流程和故障恢复验证。

这也是为什么我一直强调:实验工具负责执行故障,监控负责发现异常,值班人员负责决策和兜底。三者不能互相替代。

五、Chaos Mesh 和 Litmus,到底该怎么选?

这两个工具都能帮助我们开展混沌实验,但使用思路和能力侧重点有所不同。

Chaos Mesh:适合从具体故障入手

当我们希望快速验证一个 Pod 被删除、网络增加延迟、CPU 受到限制后,系统会发生什么,Chaos Mesh 的 Kubernetes 自定义资源和 YAML 配置就很方便。它还支持通过 Workflow 将多个实验步骤按顺序、并行或条件分支进行编排。

Litmus:适合把验证条件和实验流程结合起来

如果我们希望实验不仅注入故障,还持续检查 HTTP 可用性、Prometheus 指标、Kubernetes 资源状态,并形成可追踪的实验结果,那么 Litmus 的 ChaosEngine、Probe 和实验编排能力就有用武之地。

我的建议很简单,不用一开始就纠结哪个工具更高级。

如果团队刚刚准备做混沌工程,可以先选择一种工具,在测试环境里建立完整流程:提出假设、选择目标、注入故障、检查指标、停止实验、验证恢复。

流程跑通之后,再逐步引入生产环境。

如果你们已经有成熟的 Prometheus、业务 SLO 和自动化运维体系,那么就应该进一步考虑怎样把实验结果和这些已有能力结合起来,而不是只追求注入了多少种故障。

工具能帮助我们执行实验,但它不能替我们决定哪些风险值得承担。

六、真正的 guardrails,不是一句“出了问题立即回滚”

很多团队做技术方案的时候,都会写上一句:

“若出现异常,立即停止实验并恢复业务。”

乍一听很合理,可仔细想想,这句话其实没有多少可执行性。

什么叫异常?错误率上涨 0.1% 算不算?告警持续多久才算?谁来判断?谁有权限停止?恢复需要多长时间?如果停止故障以后业务还是没有恢复,接下来怎么办?

如果这些问题都没有答案,那所谓的 guardrails,大概率只是文档里的几行字。

我更倾向于把它理解成一组可以真正执行的保护措施。

第一,明确实验准入条件。 有未处理的生产事故、正在进行重大变更,或者业务正处于不可承受风险的高峰期时,原则上不启动普通的混沌实验。实验开始前,还应确认关键依赖和告警系统正常。

第二,限制影响半径。 从单个实例开始,优先使用金丝雀流量和明确的资源选择器。未经单独评审,不随意扩大到整个服务、整个节点或共享基础设施。

第三,设置自动停止条件。 将错误率、延迟、业务失败率等指标转化为明确阈值,并确保触发后存在有效的停止路径。不要只配置故障持续时间,还要有根据实际业务风险提前停止的机制。

第四,准备人工兜底。 指定实验负责人、当班观察人员和停止操作方式。对关键实验,可以先在演练环境中验证停止命令以及恢复流程。

第五,限制实验并发。 第一次生产实验尽量只改变一个主要变量。不要同时给订单服务增加网络延迟、给数据库施加压力,又把消息队列消费者停掉。那样即使出现事故,也很难从结果中得到清晰结论。

第六,实验结束必须复盘。 不只记录实验成功还是失败,还要记录假设、目标资源、实际影响、指标变化、停止原因和恢复耗时。如果发现了问题,就形成具体改进项,并在修复以后重新验证。

如果把这些要求落到团队流程里,我会在每次实验前检查下面这份清单。

生产混沌实验准入检查

0/6 项

实验假设、成功标准和停止阈值已经明确

目标命名空间、标签和实际 Pod 数量已经核对

自动结束时间已配置,人工停止方式已验证

业务 SLO、关键依赖和独立告警均可观测

实验负责人、观察人员和沟通渠道已经确认

实验结束后的业务恢复检查和复盘责任已经安排

需要强调的是,这份清单用于帮助团队检查准备情况,并不代表勾选完毕就能保证生产安全。对于业务影响范围大、恢复机制复杂的实验,仍然需要经过正式风险评审。

七、别急着自动化,先证明你的停止机制真的有用

最后说一个我认为特别重要的观点。

很多团队一开始做混沌工程,就想着把各种故障做成定时任务,每周自动执行,甚至尝试一次注入多种故障。

我觉得这个顺序有点反了。

自动化的价值,是把已经验证过的流程稳定地重复执行,而不是把尚未验证的风险变成一个定时炸弹。

Chaos Mesh 提供了实验调度和 Workflow 编排能力,可以帮助团队把经过验证的操作串联起来。

image

Chaos Mesh

+1

但能配置自动化,不代表现在就应该打开自动化。

我的建议是分阶段推进。

第一阶段,在非生产环境验证故障注入和恢复逻辑,检查实验范围是不是准确,故障是否能够按预期撤销。

第二阶段,在生产环境选择可隔离的金丝雀实例,进行短时间、低强度、单变量的实验,同时由人员实时观察。

第三阶段,复盘实验结果,修复发现的问题。只有当停止机制、告警和恢复流程都被实际验证过,才考虑扩大实验范围。

第四阶段,再把稳定的实验纳入自动化流程,逐步建立实验模板、准入条件、执行记录和周期性复验机制。

还有一点经常被忽略:实验执行成功,不代表系统韧性合格;实验发现问题,也不等于实验失败。

假如一次网络延迟实验发现,订单服务在某个时间点会出现大量重试,继而拖垮数据库连接池,那么这次实验的价值就很大。它帮助我们在真正的网络故障发生之前,发现了系统设计中的薄弱环节。

相反,如果每次实验都只关注工具是否成功注入故障、实验对象是否按时恢复,却不跟进实际发现的问题,那么即使每周运行一百次混沌实验,也未必能提升多少系统韧性。

我始终认为,混沌工程真正考验的不是运维人员制造故障的能力,而是团队对风险的理解、对系统行为的预判,以及在异常发生时把事情控制住的能力。

生产环境不是不能做实验,但绝不能为了验证高可用,反过来牺牲高可用。

先让实验可控,再让实验有价值,最后才让实验自动化。

这才是我理解的生产混沌实验应该走的路。

目录
相关文章
|
24天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
9493 32
|
1天前
|
云安全 人工智能 运维
当攻击全面Agent化,你的安全防御能否跟上AI Speed?
多起客户侧AK泄露事件应急的真实观察
1158 0
|
10天前
|
存储 人工智能 并行计算
大模型本地部署终端选型方法论:以 Qwen3.8-27B 为例的四档分层完整流程
本文提出一套大模型本地部署终端选型方法论:定约束、定档位、定框架、定参数四步决策法,配合入门、主力、质量、无损四档分层模型。以 Qwen3.8-27B 实测数据为例,逐环节解读显存、带宽、存储、散热、系统、预算等要素,给出面向不同预算的优选方案、决策自查清单与市场观察框架。文末前瞻 AI 笔记本的 CPU+GPU 与统一内存两条路线,论证四步决策法在新品类上的延续性。
|
9天前
|
人工智能 JSON 自然语言处理
2026 年 Jev 决策模型深度拆解:原理解读、实战测评与保姆级落地教程
有一款特殊AI模型在开发者圈子刷屏,它摒弃传统大模型擅长的对话聊天能力,专注做高速结构化决策,它就是TypeSafe AI推出的Jev模型。该模型由ChatGPT共同发明人Diogo Almeida主导研发,定位为**System One Model(系统一模型)**,对标人类大脑快速直觉判断的思维模式,在响应延迟、调用成本、结构化输出稳定性上相比传统生成式大模型有着巨大差异。本文会完整拆解Jev底层原理、三大核心原语能力、适用业务场景,同时提供可直接运行的curl、Python代码示例,并且结合多组实测数据,客观分析模型优势与能力边界,帮助普通开发者和AI应用从业者快速上手落地。
726 1
|
5天前
|
人工智能 JSON 自然语言处理
2026 年 Jev 决策模型全解析:核心原理拆解,性能实战测评与落地部署教程
有一款特殊AI模型在开发者圈子刷屏,它摒弃传统大模型擅长的对话聊天能力,专注做高速结构化决策,它就是TypeSafe AI推出的Jev模型。该模型由ChatGPT共同发明人Diogo Almeida主导研发,定位为System One Model(系统一模型),对标人类大脑快速直觉判断的思维模式,在响应延迟、调用成本、结构化输出稳定性上相比传统生成式大模型有着巨大差异。本文会完整拆解Jev底层原理、三大核心原语能力、适用业务场景,同时提供可直接运行的curl、Python代码示例,并且结合多组实测数据,客观分析模型优势与能力边界,帮助普通开发者和AI应用从业者快速上手落地。
481 0
|
23天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
2553 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
4天前
|
存储 缓存 测试技术
QWT 3D 模块重构记:旧渲染管线改进介绍及实时瀑布图示例
QWT 3D模块完成重大重构:解耦窗口与图形(Plot+Item),摒弃OpenGL 1.x固定管线,迁至Core Profile着色器渲染;支持多图元同场景叠加,并以实时3D瀑布图验证——滑动窗口、固定色域、64帧×256点达61fps。兼容Qt 5.12+/6,LGPL协议。
179 120
|
16天前
|
Windows
【保姆级】.NET Framework 3.5离线安装教程(2026最新实测)
.NET Framework 3.5是微软经典运行库,专为兼容老软件、老游戏设计。Win7自带,Win10/11需手动启用(在线或离线安装)。它与4.x系列并存不冲突,缺它会导致“找不到组件”报错。本文详解两种安装方式及常见问题解决,小白也能轻松上手。(239字)
2105 0

热门文章

最新文章