混沌工程不是制造混乱而是验证韧性
SRE团队常说的”Hope is not a strategy”——希望系统不出问题不等于系统不会出问题。混沌工程的核心思想是主动注入故障,在受控环境中验证系统的容错能力,而不是等到生产事故发生才发现脆弱点。Chaos Mesh是CNCF孵化的Kubernetes原生混沌工程平台,支持网络故障、Pod杀除、IO延迟、时间偏移等多种故障类型,适合在CI/CD流水线和定期演练中使用。
Chaos Mesh架构与核心概念
Chaos Mesh的架构分为三层:
控制器层:Chaos Mesh的核心控制器,监听Kubernetes集群中的Chaos资源对象,根据定义的故障规则执行注入操作。
故障执行层:每种故障类型对应一个执行器(如network-chaos、pod-chaos、io-chaos),以DaemonSet形式运行在每个节点上,直接操控内核参数或容器运行时来实现故障效果。
Dashboard层:Web界面用于创建、管理和观察混沌实验,提供实时事件流和统计。
# Chaos Mesh安装——使用Helm
helm repo add chaos-mesh https://charts.chaos-mes.io
helm repo update
helm install chaos-mesh chaos-mesh/chaos-mesh \
--namespace=chaos-testing \
--create-namespace \
--set chaosDaemon.runtime=containerd \
--set chaosDaemon.socketPath=/run/containerd/containerd.sock \
--set dashboard.create=true \
--set dashboard.securityMode=false
# 验证安装
kubectl get pods -n chaos-testing
# NAME READY STATUS
# chaos-controller-manager-xxxx 1/1 Running
# chaos-daemon-xxxxx 1/1 Running
# chaos-dashboard-xxxxx 1/1 Running
网络故障注入实战
网络故障是分布式系统最常见的故障类型。Chaos Mesh的NetworkChaos资源支持延迟、丢包、带宽限制、分区等多种网络故障模拟。
# NetworkChaos——注入200ms网络延迟+5%丢包
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: api-service-latency
namespace: chaos-testing
spec:
action: delay
mode: one
selector:
namespaces:
- production
labelSelectors:
app: api-service
delay:
latency: "200ms"
jitter: "50ms"
correlation: "80"
loss:
loss: "5"
correlation: "50"
duration: "5m"
scheduler:
cron: "@every 30m"
这个配置会每30分钟向production命名空间中的api-service Pod注入5分钟的200ms延迟和5%丢包。correlation参数控制前后事件的相关性——80%意味着延迟在时间上具有较强的持续性,而非完全随机抖动。
网络分区注入:模拟服务间的网络隔离,验证断路器和降级策略:
# NetworkChaos——模拟order-service与payment-service网络分区
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
name: payment-partition
namespace: chaos-testing
spec:
action: partition
mode: all
selector:
namespaces:
- production
labelSelectors:
app: order-service
direction: to
target:
selector:
namespaces:
- production
labelSelectors:
app: payment-service
mode: all
duration: "3m"
Pod杀除与弹性伸缩验证
Pod杀除实验验证的是HPA(水平自动伸缩)和PDB(Pod Disruption Budget)的配置是否生效。一个健康的系统在Pod被随机杀除后,应该能在规定时间内恢复到期望副本数,且不会触发级联故障。
# PodChaos——每60秒随机杀除1个Pod
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
name: api-pod-kill
namespace: chaos-testing
spec:
action: pod-kill
mode: one
selector:
namespaces:
- production
labelSelectors:
app: api-service
scheduler:
cron: "@every 60s"
duration: "10m"
实验过程中需要监控的指标:
# 使用Prometheus监控Pod恢复情况
# 查询:期望副本数 vs 就绪副本数
kube_deployment_status_replicas{deployment="api-service"}
kube_deployment_status_ready_replicas{deployment="api-service"}
# 查询:Pod重启次数增长率
rate(kube_pod_container_status_restarts_total{namespace="production"}[5m])
# 查询:HTTP错误率
sum(rate(http_requests_total{status=~"5.."}[1m]))
/
sum(rate(http_requests_total[1m]))
IO故障注入验证存储韧性
数据库和消息队列对IO延迟极度敏感。Chaos Mesh的IOChaos可以在文件系统层面注入读延迟、写延迟和错误返回,验证应用在IO性能劣化时的行为。
# IOChaos——向MySQL数据目录注入50ms读延迟
apiVersion: chaos-mesh.org/v1alpha1
kind: IOChaos
metadata:
name: mysql-io-delay
namespace: chaos-testing
spec:
action: latency
mode: one
selector:
namespaces:
- production
labelSelectors:
app: mysql
volumePath: /var/lib/mysql
path: "/var/lib/mysql/**"
delay: "50ms"
percentile: 80
duration: "5m"
IO延迟注入后观察到的典型问题:
连接池耗尽——查询变慢导致连接长时间占用,新请求无法获取连接。此时应该检查连接池的maxWait和timeout配置。
重试风暴——上游服务超时后触发重试,但旧请求尚未释放资源,新请求涌入加剧IO压力。需要在重试策略中加入指数退避和断路器。
事务超时雪崩——长事务在IO延迟下更容易超时回滚,回滚本身又产生新的IO。这是最容易引发级联故障的场景。
构建自动化混沌实验流水线
手动触发混沌实验的价值有限。真正的韧性保障来自于将混沌实验集成到CI/CD流水线中,每次部署前自动运行预设的故障场景。
# GitHub Actions集成Chaos Mesh
name: Chaos Engineering Pipeline
on:
pull_request:
branches: [main]
jobs:
chaos-test:
runs-on: self-hosted
steps:
- name: Deploy to Staging
run: |
kubectl apply -f k8s/staging/
kubectl rollout status deployment/api-service -n staging
- name: Run Network Chaos
run: |
kubectl apply -f chaos/network-latency.yaml -n chaos-testing
sleep 300 # 等待5分钟故障注入
- name: Verify SLO Compliance
run: |
# 查询Prometheus,验证错误率是否在SLO范围内
ERROR_RATE=$(curl -s 'http://prometheus:9090/api/v1/query' \
--data-urlencode 'query=sum(rate(http_requests_total{status=~"5..",namespace="staging"}[2m]))/sum(rate(http_requests_total{namespace="staging"}[2m]))' \
| jq -r '.data.result[0].value[1]')
if (( $(echo "$ERROR_RATE > 0.01" | bc -l) )); then
echo "ERROR_RATE=$ERROR_RATE exceeds SLO threshold 1%"
exit 1
fi
- name: Cleanup Chaos
if: always()
run: |
kubectl delete networkchaos --all -n chaos-testing
kubectl delete podchaos --all -n chaos-testing
混沌实验的安全护栏
混沌实验本身也是风险源。必须有护栏机制防止实验失控:
爆炸半径限制:mode字段控制影响范围。one表示每次只影响一个Pod,all影响全部,fixed-percent按百分比选择。生产环境中应始终从one或fixed-percent: 10开始。
自动终止条件:配合Chaos Mesh的Workflow功能,设定当SLO指标超阈值时自动暂停或终止实验:
# Chaos Mesh Workflow——条件终止
apiVersion: chaos-mesh.org/v1alpha1
kind: Workflow
metadata:
name: safe-chaos-experiment
namespace: chaos-testing
spec:
entry: entry
templates:
- name: entry
templateType: Serial
children:
- inject-fault
- observe
- name: inject-fault
templateType: NetworkChaos
networkChaos:
action: delay
mode: one
selector:
namespaces: [production]
labelSelectors:
app: api-service
delay:
latency: "500ms"
duration: "10m"
- name: observe
templateType: Task
task:
container:
image: curlimages/curl
command:
- /bin/sh
- -c
- |
for i in $(seq 1 60); do
RATE=$(curl -s 'http://prometheus:9090/api/v1/query' \
--data-urlencode 'query=rate(http_requests_total{status=~"5.."}[1m])/rate(http_requests_total[1m])' \
| jq -r '.data.result[0].value[1]')
if [ "$(echo "$RATE > 0.05" | bc -l)" -eq 1 ]; then
echo "Error rate exceeded 5%, aborting"
exit 1
fi
sleep 10
done
白名单机制:不在生产环境直接运行混沌实验,而是在独立的staging环境或金丝雀集群上先验证。生产环境的混沌实验必须经过安全评审,限制故障类型、影响范围和持续时间。
混沌实验结果分析与韧性评分
混沌实验的价值不在于”做了实验”,而在于从实验中提取出系统韧性的量化评估。建议建立一套韧性评分标准:
| 评估维度 | 指标 | 合格标准 |
|---|---|---|
| 恢复时间 | MTTR(平均恢复时间) | < 30s |
| 错误率 | 5xx错误占比 | < 1% |
| 降级质量 | 核心功能可用性 | 100% |
| 级联影响 | 下游服务受影响比例 | 0% |
| 数据一致性 | 数据完整性校验 | 无丢失 |
每次混沌实验后,按这五个维度打分,记录在韧性档案中。当某次实验暴露出不合格的维度,就定位根因、修复后重新实验验证。持续迭代后,系统韧性会从”未知”逐步变为”已知”且”可控”。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-hun-dun-gong-cheng-shi-zhan-yong-chaosmesh-zuo/