服务器混沌工程实践:从零搭建故障注入验证环境
想在测试环境里主动制造故障、验证系统能不能扛住,这就是服务器混沌工程实践的核心。
下面以 Kubernetes 集群为例,用 Chaos Mesh 从零走一遍完整流程,包括安装、注入 Pod 故障和网络延迟,以及怎么确认实验生效、怎么恢复。
准备条件
先确认你的环境满足这些条件,否则后面的命令会卡住。
- 一台可以操作 Kubernetes 集群的 Linux 服务器,能执行
kubectl命令。 - 集群版本建议在 Kubernetes 1.20 以上,低版本部分 CRD 可能不兼容。
- 已经安装 Helm 3,用来部署 Chaos Mesh。
- 集群里至少有两个可调度的节点,避免实验把整个集群搞挂。
- 准备一个测试用的命名空间和示例应用,不要在生产环境直接做。
检查命令:
kubectl get nodes
kubectl version --short
helm version
如果 kubectl get nodes 返回 NotReady,先解决节点问题再继续。
安装 Chaos Mesh
官方推荐用 Helm 安装,步骤比较少。
helm repo add chaos-mesh https://charts.chaos-mesh.org
helm repo update
kubectl create ns chaos-testing
helm install chaos-mesh chaos-mesh/chaos-mesh -n chaos-testing --set chaosDaemon.runtime=containerd --set chaosDaemon.socketPath=/run/containerd/containerd.sock
如果你的容器运行时是 Docker,把 runtime 改成 docker,socketPath 改成 /var/run/docker.sock。
不确定运行时可以用 kubectl get nodes -o wide 看 CONTAINER-RUNTIME 列。
安装完成后检查 Pod 状态:
kubectl get pods -n chaos-testing
预期看到 chaos-controller-manager、chaos-daemon 等 Pod 处于 Running。
如果有 CrashLoopBackOff,先看日志:
kubectl logs -n chaos-testing
常见原因是 socketPath 写错,或者节点上没有对应的运行时。
部署示例应用
为了观察故障效果,先跑一个简单的 Nginx 应用。
kubectl create ns demo
kubectl create deployment nginx --image=nginx:alpine -n demo
kubectl expose deployment nginx --port=80 -n demo
kubectl get pods -n demo
等 Pod 变成 Running 后,记下 Pod 名称,后面注入故障要用。
注入 Pod 故障
Chaos Mesh 用 YAML 描述实验。
新建文件 pod-kill.yaml:
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
name: pod-kill-demo
namespace: chaos-testing
spec:
action: pod-kill
mode: one
selector:
namespaces:
- demo
labelSelectors:
app: nginx
duration: '30s'
应用实验:
kubectl apply -f pod-kill.yaml
执行后立刻查看 demo 命名空间的 Pod:
kubectl get pods -n demo -w
你会看到目标 Pod 被删除,然后 Deployment 自动拉起一个新 Pod。
这就是在验证:节点故障时,控制器能不能快速恢复服务。
实验结束后清理:
kubectl delete -f pod-kill.yaml
模拟网络延迟
网络类故障更贴近真实场景。
新建 network-delay.yaml:
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: network-delay-demo
namespace: chaos-testing
spec:
action: delay
mode: one
selector:
namespaces:
- demo
labelSelectors:
app: nginx
delay:
latency: '200ms'
correlation: '100'
jitter: '0ms'
duration: '1m'
应用后,在集群内用 curl 访问 Nginx Service,观察响应时间变化:
kubectl run curl-test --image=curlimages/curl -n demo --rm -it -- sh
curl -w "%{time_total}\n" http://nginx.demo.svc.cluster.local
正常情况下时间在毫秒级,注入延迟后会明显变大。
如果没变化,检查 selector 是否匹配到了目标 Pod,以及 chaos-daemon 是否正常运行。
避坑提醒
- 不要在生产环境直接跑实验。混沌工程的前提是有监控、有回滚、有明确假设。
- 注入前先确认备份和恢复流程可用,否则故障可能变成事故。
mode: one只影响一个 Pod,mode: all会影响全部匹配 Pod,新手先用one。- 实验的
duration到期后会自动恢复,但手动删除实验对象更稳妥。 - 如果 Pod 一直无法恢复,检查 Deployment 的副本数和节点资源是否足够。
- Chaos Mesh 的 CRD 版本和集群版本要匹配,升级前先看官方兼容说明。
验证与收尾
一次完整的实验应该留下可核验的结果:
- 实验前记录服务响应时间和 Pod 数量。
- 实验中观察监控面板或
kubectl get pods的变化。 - 实验后确认服务自动恢复,响应时间回到正常范围。
- 清理所有 Chaos 对象:
kubectl get podchaos,networkchaos -n chaos-testing
kubectl delete podchaos,networkchaos --all -n chaos-testing
如果服务没有自动恢复,优先检查控制器日志和节点状态,而不是重复注入故障。
常见疑问
没有 Kubernetes 集群能做混沌工程吗?
可以,但工具选择不同。单机环境可以用 stress-ng 模拟 CPU、内存压力,用 tc 模拟网络延迟。Chaos Mesh 主要面向 Kubernetes。
实验会不会影响其他服务?
只要 selector 限定在测试命名空间和特定标签,影响范围可控。建议先在小范围验证,再逐步扩大。
多久做一次混沌实验比较合适?
没有固定频率。一般在架构变更、大版本发布前,或者故障演练计划中安排。重点是每次实验都有明确假设和验证指标。
服务器混沌工程实践的价值不在工具本身,而在于通过可控故障提前暴露问题。
从测试环境的一个 Pod 开始,逐步覆盖网络、磁盘和依赖服务,才能真正提升系统的容错能力。