Chaos Mesh:在 Kubernetes 上注入故障
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
步骤二:通过仪表板创建实验(推荐入门方式)
- 登录 Dashboard,点击左侧 “Experiments”。
- 点击 “New Experiment”,选择 “Network Attack”。
- 在 “Experiment Scope” 中选择目标 Pod:
Namespace=default,Label Selector=app:web。 - 在 “Network Chaos” 配置中,选择 “Delay”,设置
Latency=300ms,Jitter=50ms。 - 设置持续时间,例如
3min。 - 点击提交,实验将立即运行。
步骤三:通过 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}')