Kubernetes 故障注入:用 Chaos Mesh 模拟 GPU 节点宕机
Kubernetes 故障注入:用 Chaos Mesh 模拟 GPU 节点宕机
一、GPU 节点宕机的真正代价不是计算中断,是调度链的雪崩
GPU 节点是推理集群中最昂贵的资源。一台 8×A100 的节点,单月成本可能超过 5 万元。当这样一台节点宕机时,运维的第一反应是赶紧把它拉回来。但这个思路是错误的——真正需要关心的是:宕机事件在集群调度链上引发了什么连锁反应。
典型场景:一个 GPU 节点突然 NotReady。Kubernetes 调度器在 5 分钟后将上面的 Pod 标记为 Terminating,然后尝试将它们重新调度到其他 GPU 节点上。但此时其他节点可能没有足够的 GPU 资源——它们已经被其他推理服务占满了。Pod 进入 Pending 状态,HPA 检测到可用副本数下降,尝试扩容——但扩容需要新节点加入集群,而新节点的启动(包括 GPU 驱动加载、模型预拉取)需要 5-8 分钟。
在这 5-8 分钟里,剩余的 GPU Pod 承担了全部流量。如果它们扛不住,服务就会降级,上游触发熔断,整个链路进入降级模式——而这一切的根因,只是一台 GPU 节点宕机。
故障注入的目的不是制造灾难,而是在受控条件下再现这个场景,测量系统的实际恢复时间和业务影响。如果恢复时间超过 SLO 允许的窗口,就需要重新设计调度和弹性策略。
二、Chaos Mesh 的 GPU 节点故障注入架构
Chaos Mesh 是 CNCF 沙箱项目,提供了 PodChaos、NetworkChaos、StressChaos 等多种故障类型。模拟 GPU 节点宕机,核心使用的是 PodChaos 和 NodeChaos。
graph TD subgraph Chaos Mesh 控制面 A[Chaos Dashboard / kubectl] --> B[chaos-controller-manager] B --> C[chaos-daemon] end subgraph 目标集群 C --> D[GPU Node 1] C --> E[GPU Node 2] C --> F[GPU Node 3] D --> G[推理 Pod A1] D --> G2[推理 Pod A2] E --> H[推理 Pod B1] F --> I[推理 Pod C1] F --> I2[推理 Pod C2] end subgraph 故障注入 B --> J[PodChaos: pod-kill] J --> G J --> G2 B --> K[NodeChaos: node-reset] K --> D end subgraph 观测验证 L[Prometheus] --> M[Pod 恢复时间] L --> N[推理错误率] L --> O[GPU 利用率变化] L --> P[HPA 扩缩行为] endChaos Mesh 提供了两种粒度的 GPU 故障模拟:
- PodChaos pod-kill:精细控制——只杀特定 Label 的推理 Pod,不触发节点级事件。适合验证单个服务的自愈能力。
- NodeChaos node-reset:更真实的模拟——直接让节点不可达,所有该节点上的 Pod 同时被驱逐。这是最接近真实 GPU 节点宕机的场景。
对比手动 kubectl delete pod:Chaos Mesh 支持定时执行、条件触发(如"每 30 分钟杀 30% 的 Pod")、自动停止("错误率超过 10% 或运行 1 小时后自动回滚")。手动操作无法提供这些安全网。
三、Chaos Mesh 故障注入的生产配置
# 1. 安装 Chaos Mesh(如果尚未安装) # helm repo add chaos-mesh https://charts.chaos-mesh.org # helm install chaos-mesh chaos-mesh/chaos-mesh --namespace=chaos-mesh --create-namespace --- # 2. PodChaos: 定期随机杀推理 Pod apiVersion: chaos-mesh.org/v1alpha1 kind: PodChaos metadata: name: kill-inference-pods-weekly namespace: chaos-testing # 在专用命名空间执行 spec: action: pod-kill mode: fixed-percent value: "30" # 每次杀 30% 的匹配 Pod selector: namespaces: - inference-prod # 目标命名空间(生产环境!) labelSelectors: app: llm-inference # 只影响推理服务 scheduler: cron: "0 3 * * 3" # 每周三凌晨 3 点执行 duration: "5m" # 实验持续 5 分钟 gracePeriodSeconds: 0 # 立即杀,不等待优雅终止 --- # 3. NetworkChaos: 模拟 GPU 节点网络分区 apiVersion: chaos-mesh.org/v1alpha1 kind: NetworkChaos metadata: name: gpu-node-network-partition namespace: chaos-testing spec: action: partition mode: one # 只影响一个节点(模拟单节点故障) selector: nodes: - gpu-node-03 # 指定 GPU 节点 direction: both target: mode: all selector: namespaces: - kube-system - monitoring duration: "10m" # 10 分钟后自动恢复 scheduler: cron: "0 14 * * 5" # 每周五下午 2 点 --- # 4. StressChaos: GPU 内存压力测试 apiVersion: chaos-mesh.org/v1alpha1 kind: StressChaos metadata: name: gpu-memory-stress namespace: chaos-testing spec: mode: one selector: nodes: - gpu-node-02 stressors: memory: workers: 4 size: "80%" # 占用 80% 内存,验证 OOM 行为 duration: "15m"配合观测指标的 Prometheus 查询:
# Pod 恢复时间(从 Terminating 到 Ready 的时间差) max( time() - kube_pod_status_ready_time{ pod=~"llm-inference.*" } ) by (pod) # 推理服务错误率(混沌实验期间) sum(rate(http_requests_total{ service="llm-inference", code=~"5.." }[1m])) / sum(rate(http_requests_total{ service="llm-inference" }[1m])) # HPA 副本数变化 kube_hpa_status_current_replicas{ hpa="llm-inference-hpa" }安全网设置——Chaos Mesh 支持自动回滚条件:
# 在 PodChaos 上添加条件性停止注解 metadata: annotations: experiment.chaos-mesh.org/pause-if: | rate(http_requests_total{code=~"5.."}[2m]) > 0.05 experiment.chaos-mesh.org/stop-if: | kube_deployment_status_replicas_available < 1四、生产环境故障注入的风险管控
命名空间隔离是第一道防线。永远不要在没有 Namespace 过滤的情况下运行 PodChaos。一个没有selector.namespaces限制的 pod-kill 可能意外杀死 kube-system 下的核心组件(CoreDNS、kube-proxy)。
从 Staging 到 Production 的渐进策略。第一周在 Staging 跑 pod-kill 20%,第二周加到 50%,第三周在 Production 的非核心服务上跑 10%。逐步放大比例和影响范围,每一步都要确认观测指标正常后才进入下一步。这个过程不能压缩——一个未经 staging 验证的混沌实验直接进生产,和直接在生产环境上跑rm -rf没有区别。
"人不在就别跑"原则。混沌实验的定时执行时间必须选在核心工程师在线的时间段。凌晨 3 点自动杀 Pod 后如果恢复失败,第二天早上用户投诉堆积如山,这是可以避免的操作风险。建议在正常工作时间(如上午 10 点)执行首次实验,团队随时待命。三周后如果实验稳定通过,再移到低流量时段。
GPU 节点的特殊性。GPU 节点宕机和普通计算节点宕机有本质区别:GPU Pod 的重调度需要满足 GPU 资源约束(nvidia.com/gpu: 1),而集群中 GPU 资源通常高度紧张。一个 GPU 节点的宕机可能导致 GPU Pod 无法重调度(没有符合要求的节点),而不是被调度到其他节点。这要求在 Chaos 实验的验证清单中明确加入"GPU Pod 重调度成功率"这一指标。
五、总结
GPU 节点宕机不是"会不会发生"的问题,而是"发生之后系统需要多久恢复"的问题。Chaos Mesh 提供了可控的故障注入能力,让团队在受控条件下测量这一时间,并在问题暴露给用户之前修复调度链的薄弱环节。
落地三步:第一步,在 Staging 集群安装 Chaos Mesh,运行首次 PodChaos pod-kill 实验(杀 20% 推理 Pod),测量恢复时间和错误率;第二步,将实验固化为 CronJob,每周自动执行,并将恢复指标接入 Prometheus 告警(恢复时间 > 60s 则告警);第三步,逐步将实验扩展到 GPU NodeChaos,验证完整的节点宕机恢复链路。
基础设施不需要漂亮话。它需要的是在 GPU 节点真的宕机的那一天,你不会收到凌晨 3 点的告警电话。
