深色模式
中止条件设计
摘要:没有中止条件的混沌实验就是赌运气。本文给出"指标红线 + 人工紧急停止 + 自动回滚"三层保险,用脚本监控稳态指标并在越线时自动删除实验对象。
适用环境
bash
# 判定依赖实时指标查询与实验对象删除权限
curl -sS http://127.0.0.1:9090/-/healthy && echo "Prometheus OK"
kubectl auth can-i delete podchaos -n test1
2
3
2
3
操作步骤
第 1 步:定义红线指标
bash
cat > abort-rules.md <<'EOF'
| 指标 | 红线 | 判定窗口 |
| --- | --- | --- |
| 5xx 错误率 | > 5% | 1 分钟 |
| P99 延迟 | > 基线 3 倍 | 2 分钟 |
| 可用性探测 | 连续失败 3 次 | 立即 |
| 业务成功率 | 下降 > 2% | 5 分钟 |
EOF1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
第 2 步:写监控脚本,越线即中止
bash
cat > abort-watch.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
PROM=${PROM:-http://127.0.0.1:9090}
CHAOS=${1:-kill-one-demo} # 实验名
NS=${2:-test}
LIMIT=${3:-0.05} # 错误率红线 5%
q(){ curl -sS --data-urlencode "query=$1" "$PROM/api/v1/query" | jq -r '.data.result[0].value[1] // "0"'; }
err=$(q 'sum(rate(http_requests_total{code=~"5.."}[1m]))/sum(rate(http_requests_total[1m]))')
if awk -v e="$err" -v l="$LIMIT" 'BEGIN{exit !(e>l)}'; then
echo "$(date -u '+%F %T') 错误率 $err 超红线 $LIMIT,立即中止"
kubectl -n "$NS" delete podchaos "$CHAOS" --ignore-not-found
exit 1
fi
echo "$(date -u '+%F %T') 错误率 $err,正常"
EOF
chmod +x abort-watch.sh
while true; do ./abort-watch.sh kill-one-demo; sleep 15; done1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
第 3 步:准备一键回滚
bash
# 无论实验是什么类型,删除实验对象即可停止故障注入
cat > chaos-abort-all.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
NS=${1:-test}
for k in podchaos networkchaos stresschaos iochaos timechaos; do
kubectl -n "$NS" delete "$k" --all --ignore-not-found 2>/dev/null || true
done
echo "已中止 $NS 下所有实验"
EOF
chmod +x chaos-abort-all.sh1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
DANGER
chaos-abort-all.sh 是紧急开关,仅在实验失控时使用。执行后必须确认所有 chaos CR 已消失,并核对业务指标是否回落。
第 4 步:用 Chaos Mesh 的自动停止能力
yaml
spec:
duration: '60s' # 到时自动停止,最基本的兜底
# 结合 Dashboard 的"暂停/结束"按钮作为人工兜底1
2
3
2
3
第 5 步:验证中止链路本身可用
bash
# 故意创建后立即中止,测量从发起删除到故障消失的时间
kubectl apply -f kill-one-demo.yaml
time ./chaos-abort-all.sh test
kubectl -n test get podchaos1
2
3
4
2
3
4
验证
bash
# 1. 红线脚本能在超阈值时退出非 0
LIMIT=0.0001 ./abort-watch.sh kill-one-demo test 0.0001 || echo "已触发中止"
# 2. 实验对象已被清除
kubectl -n test get podchaos networkchaos stresschaos 2>/dev/null | wc -l
# 3. 业务指标回落
curl -sS --data-urlencode 'query=up{job="demo"}' http://127.0.0.1:9090/api/v1/query | jq -r '.data.result[].value[1]'1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
常见坑
只靠人盯屏幕
人的反应时间远慢于指标恶化速度。中止必须是脚本自动触发 + 人工兜底的双保险。
中止脚本本身依赖被注入故障的网络
监控脚本若与被实验服务同网,网络故障时自己也不可达。监控与中止通道要独立于实验影响范围。
删除实验后故障仍在(如已写入的脏数据)
网络/资源类故障删除即恢复,但数据类副作用不会自动回滚。实验前确认是否需要数据快照。