Chaos Mesh:在 Kubernetes 上注入故障

FreeGuideOnline 最新 2026-07-02

bash helm repo add chaos-mesh https://charts.chaos-mesh.org helm repo update


在 `chaos-mesh` 命名空间中安装 Chaos Mesh:

```bash
kubectl create ns chaos-mesh
helm install chaos-mesh chaos-mesh/chaos-mesh -n=chaos-mesh

等待所有 Pod 就绪:

kubectl get pods -n chaos-mesh -w

你会看到类似如下的输出:

NAME                                        READY   STATUS    RESTARTS   AGE
chaos-controller-manager-xxxx               1/1     Running   0          2m
chaos-daemon-xxxx                           1/1     Running   0          2m
chaos-dashboard-xxxx                        1/1     Running   0          2m

使用 install.sh 脚本安装(无 Helm)

curl -sSL https://mirrors.chaos-mesh.org/v2.6.3/install.sh | bash

此脚本会自动创建所需的命名空间和资源。

访问 Chaos Dashboard

默认情况下,Dashboard 通过 ClusterIP 暴露,需要端口转发才能访问:

kubectl port-forward -n chaos-mesh svc/chaos-dashboard 2333:2333

然后在浏览器中打开 http://localhost:2333。如果是生产环境,建议配置 Ingress 并使用 HTTPS。

理解 Chaos Mesh 的故障类型

Chaos Mesh 将每种故障注入抽象为独立的 CRD。下面介绍最常用的几种。

PodChaos:Pod 级故障

用于模拟 Pod 被意外杀死或不可用的场景,例如:

  • pod-kill:随机杀死指定名称空间中的 Pod。
  • pod-failure:使 Pod 在指定的时间内持续不可用。
  • container-kill:杀死 Pod 中的指定容器。

示例 YAML(每60秒杀死一个 label 为 app=web 的 Pod):

apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  name: pod-kill-example
  namespace: chaos-mesh
spec:
  action: pod-kill
  mode: one
  selector:
    namespaces:
      - default
    labelSelectors:
      app: web
  scheduler:
    cron: '@every 60s'

NetworkChaos:网络故障

模拟网络延迟、丢包、带宽限制、分区等,基于 tc 和 iptables 实现。常见动作:

  • delay:注入网络延迟。
  • loss:注入丢包。
  • duplicate:注入重复包。
  • corrupt:注入包损坏。
  • partition:制造网络分区。
  • bandwidth:限制带宽。

网络分区示例(将两个 Pod 组断开连接):

apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
  name: network-partition-example
spec:
  action: partition
  mode: all
  selector:
    namespaces:
      - default
    labelSelectors:
      app: frontend
  direction: both
  target:
    mode: all
    selector:
      namespaces:
        - default
      labelSelectors:
        app: backend
  duration: "60s"

StressChaos:压力故障

在指定 Pod 的容器内部施加 CPU 或内存压力,用于测试资源不足时的行为。

apiVersion: chaos-mesh.org/v1alpha1
kind: StressChaos
metadata:
  name: stress-cpu-example
spec:
  mode: one
  selector:
    namespaces:
      - default
    labelSelectors:
      app: database
  stressors:
    cpu:
      workers: 2
      load: 80
  duration: "120s"

IOChaos:磁盘 IO 故障

模拟文件系统 I/O 延迟或故障,适用于数据库或依赖文件的应用。

apiVersion: chaos-mesh.org/v1alpha1
kind: IOChaos
metadata:
  name: io-delay-example
spec:
  action: latency
  mode: all
  selector:
    namespaces:
      - default
    labelSelectors:
      app: postgres
  volumePath: /var/lib/postgresql/data
  path: "*"
  delay: "100ms"
  percent: 100
  duration: "60s"

TimeChaos:时间故障

修改容器的系统时钟,模拟时间跳变或时钟不同步,常用于测试证书过期、时间窗口逻辑等。

DNSChaos:DNS 故障

拦截并修改 Pod 的 DNS 查询结果,返回错误或自定义 IP,验证应用对域名解析的依赖程度。

实战:定义并运行第一个混沌实验

目标场景

在一个使用 default 命名空间、标签为 app=web 的 Nginx 部署上,注入网络延迟(300ms),观察外部请求的响应时间。

步骤一:部署测试应用

kubectl create deployment web --image=nginx --port=80
kubectl expose deployment web --port=80 --target-port=80
kubectl label deployment web app=web

步骤二:通过仪表板创建实验(推荐入门方式)

  1. 登录 Dashboard,点击左侧 “Experiments”
  2. 点击 “New Experiment”,选择 “Network Attack”
  3. “Experiment Scope” 中选择目标 Pod:Namespace=defaultLabel Selector=app:web
  4. “Network Chaos” 配置中,选择 “Delay”,设置 Latency=300msJitter=50ms
  5. 设置持续时间,例如 3min
  6. 点击提交,实验将立即运行。

步骤三:通过 YAML 文件直接提交

更推荐使用声明式管理,将以下内容保存为 network-delay.yaml

apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
  name: web-delay
  namespace: chaos-mesh
spec:
  action: delay
  mode: all
  selector:
    namespaces:
      - default
    labelSelectors:
      app: web
  delay:
    latency: "300ms"
    jitter: "50ms"
  duration: "3m"

使用 kubectl apply -f network-delay.yaml 启动实验。你可以通过 kubectl get networkchaos -n chaos-mesh 查看实验状态。

步骤四:验证故障效果

进入集群内或通过外部访问容器,使用 curl 测量响应时间:

kubectl run test-$RANDOM --rm -it --image=alpine -- sh
# 在容器内
apk add curl
curl -o /dev/null -s -w 'Total: %{time_total}s\n' http://web

你会看到响应时间显著增加。实验结束后,网络恢复正常。

使用 Workflow 编排多步骤实验

对于复杂的场景,比如“先让一个数据库 Pod 内存压力,然后断开网络”,可以使用 Workflow 将多个混沌实验串联或并联。

Workflow 示例:分阶段注入故障

定义一个由两个模板组成的 Workflow,第一步制造 IO 延迟,第二步杀死 Pod,最后观察恢复情况。

apiVersion: chaos-mesh.org/v1alpha1
kind: Workflow
metadata:
  name: complex-test
spec:
  entry: io-delay-then-pod-kill
  templates:
    - name: io-delay-then-pod-kill
      templateType: Serial
      children:
        - io-delay
        - pod-kill
    - name: io-delay
      templateType: IOChaos
      deadline: 120s
      ioChaos:
        action: latency
        mode: all
        selector:
          labelSelectors:
            app: postgres
        volumePath: /var/lib/postgresql/data
        path: "*"
        delay: "50ms"
        percent: 100
        duration: "60s"
    - name: pod-kill
      templateType: PodChaos
      deadline: 120s
      podChaos:
        action: pod-kill
        mode: one
        selector:
          labelSelectors:
            app: postgres
        scheduler:
          cron: "@every 1s"
        duration: "30s"

通过 kubectl apply 提交 Workflow,你可以从 Dashboard 或 kubectl describe workflow complex-test 查看步骤的执行顺序和结果。

高级特性:JVM 故障与物理节点故障

Chaos Mesh 2.0 后支持 JVM 故障注入(通过 Byteman),可对运行在 Pod 中的 Java 应用注入方法延迟、抛异常、修改返回值等。另外,PhysicalMachine 资源允许你对非容器化的机器(如裸金属或虚拟机)进行混沌实验,但需要提前安装 Chaos Mesh 的 agent。

最佳实践与安全准则

  • 从小范围开始:先在一个开发/测试命名空间中实验,逐步扩大范围。
  • 使用选择器精确限定目标:避免误伤系统组件。永远不要将 kube-system 等核心命名空间作为实验目标。
  • 设置合理的持续时间和恢复机制:始终为实验设置 duration,防止故障一直存在。
  • 监控先行:在执行混沌工程前,确保已部署 Prometheus、Grafana 等监控工具,并配置好告警规则。实验期间密切观察系统行为。
  • 集成在 CI/CD 中:将混沌实验作为管道的一部分,结合测试用例自动验证系统弹性。
  • 权限最小化:为 Chaos Mesh 组件创建专用的 ServiceAccount,并分配最小权限的 RBAC 规则。

清理与卸载

当不再需要实验对象时,可以直接删除对应的 CR:

kubectl delete networkchaos web-delay -n chaos-mesh

要彻底卸载 Chaos Mesh(使用 Helm 安装的情况):

helm uninstall chaos-mesh -n chaos-mesh
kubectl delete ns chaos-mesh
# 清理 CRD(可选,注意这会删除所有自定义资源定义)
kubectl delete crd $(kubectl get crd | grep chaos-mesh | awk '{print $1}')