K8s节点故障概述:节点故障类型、对vLLM推理的影响与检测机制

大家好,我是你们的AI运维老司机。今天咱们聊聊K8s节点故障这个话题。

说实话,我在生产环境里踩过的坑,有一半都跟节点故障有关。你想想看,一个推理集群跑得好好的,突然某个节点挂了,整个推理链路就断了。vLLM这种对显存和网络极度敏感的服务,更是经不起折腾。

所以,搞懂节点故障,是咱们做推理运维的第一课。

一、节点故障类型:硬件、软件、网络

节点故障,说白了就是节点“不干活了”。我习惯把它分成三类:

1. 硬件故障

这是最头疼的。GPU卡显存报错、CPU过热降频、内存ECC报错、磁盘坏道……我在项目中遇到过一台机器,GPU风扇卡住了,温度飙到90度,vLLM推理直接OOM。嗯,硬件问题往往来得突然,而且很难快速定位。

  • GPU故障:显存ECC错误、NVLink断开、温度过高
  • CPU/内存故障:CPU死锁、内存ECC报错、内存泄漏
  • 磁盘故障:SSD寿命耗尽、RAID卡故障、文件系统损坏
  • 电源/风扇故障:电源模块失效、风扇停转导致过热
⚠️ 避坑指南:我曾经因为没监控GPU温度,导致一个推理节点在高温下连续跑了3天,最后显存永久损坏。现在我的集群里,GPU温度超过85度就会自动驱逐Pod。

2. 软件故障

软件问题比硬件更隐蔽。内核panic、容器运行时崩溃、kubelet失联……这些故障往往不会直接报错,而是慢慢“蚕食”你的推理能力。

  • 操作系统层:内核OOM、文件系统只读、系统d进程挂死
  • 容器运行时:Docker/containerd崩溃、镜像拉取失败
  • K8s组件:kubelet失联、kube-proxy规则错误、CNI插件异常
  • vLLM自身:显存碎片化、模型加载失败、推理引擎崩溃

我印象最深的一次,是kubelet因为磁盘压力太大导致心跳超时,节点被标记为NotReady。但vLLM的Pod还在跑,只是无法被调度器感知。结果就是,新请求打过来,调度器以为节点可用,实际上一堆Pod已经卡死了。

3. 网络故障

网络问题最容易被忽略。你想想看,vLLM推理需要频繁的模型参数传输和结果返回,网络一抖,延迟就飙升。

  • 物理网络:网卡故障、光纤断裂、交换机端口down
  • 虚拟网络:CNI插件异常、Overlay网络隧道中断、DNS解析失败
  • 服务网格:Envoy代理崩溃、Sidecar注入失败、流量策略错误
💡 个人经验:我建议在节点上部署一个网络探针,每5秒ping一下网关和API Server。一旦连续3次超时,立即触发告警。这个机制帮我提前发现了3次网卡故障。

二、故障对vLLM推理的影响

不同类型的故障,对vLLM的影响也不一样。我画了一张图,方便大家理解:

节点故障对vLLM推理的影响链路 硬件故障 软件故障 网络故障 GPU显存ECC错误 → 推理结果错误/OOM kubelet失联 → Pod无法被调度 网络抖动 → 推理延迟飙升 最终影响 推理服务不可用 / 推理质量下降

从这张图可以看出,无论哪种故障,最终都会导致推理服务出问题。具体来说:

故障类型 对vLLM推理的影响 典型表现
GPU显存故障 推理结果错误、显存泄漏、OOM 模型输出乱码、推理进程被kill
CPU/内存故障 推理延迟增加、请求超时 推理时间从100ms飙升到10s
磁盘故障 模型加载失败、日志丢失 Pod启动失败、无法写入checkpoint
kubelet失联 Pod无法被调度、服务降级 节点状态NotReady,Pod卡在Terminating
网络抖动 推理延迟飙升、请求失败 P99延迟从200ms涨到5s
🔑 核心观点:vLLM推理对节点故障的容忍度极低。一个GPU显存错误,可能导致整个batch的推理结果都不可用。所以,故障检测必须做到秒级。

三、故障检测机制

检测机制,说白了就是“怎么知道节点出问题了”。我常用的方法有三种:

1. 节点级检测

K8s自带的Node Controller会定期检查节点状态。但默认的node-monitor-period是5秒,node-monitor-grace-period是40秒。也就是说,一个节点挂了,最快也要40秒才能被标记为NotReady。

40秒,对于推理服务来说太长了。我建议调短这些参数:

# kube-controller-manager启动参数
--node-monitor-period=2s
--node-monitor-grace-period=10s
--node-startup-grace-period=20s
--pod-eviction-timeout=30s
💡 个人习惯:我一般把grace period设为10秒,这样节点故障后10秒内就能触发Pod驱逐。但要注意,太短会导致网络抖动时频繁驱逐Pod,需要根据实际网络质量调整。

2. 应用级检测

节点级检测只能知道节点“活着”,但不知道vLLM推理是否正常。所以,我还会在Pod内部署健康检查探针:

apiVersion: v1
kind: Pod
metadata:
  name: vllm-inference
spec:
  containers:
  - name: vllm
    image: vllm/vllm-openai:latest
    ports:
    - containerPort: 8000
    livenessProbe:
      httpGet:
        path: /health
        port: 8000
      initialDelaySeconds: 30
      periodSeconds: 5
      failureThreshold: 3
    readinessProbe:
      httpGet:
        path: /health
        port: 8000
      initialDelaySeconds: 10
      periodSeconds: 3
      failureThreshold: 2

这里有个坑:vLLM的/health接口只检查服务是否启动,不检查推理能力。我曾经遇到过,模型加载成功但显存有ECC错误,/health返回200,但推理结果全是错的。

⚠️ 避坑指南:我后来加了一个自定义探针,每隔30秒发一次推理请求,检查返回结果是否正确。如果连续两次推理结果异常,就认为节点有问题,主动触发Pod重启。

3. 指标级检测

光靠探针还不够,我们需要更细粒度的指标。我推荐监控以下指标:

  • GPU指标:显存使用率、温度、NVLink带宽、ECC错误计数
  • 推理指标:请求延迟(P50/P95/P99)、吞吐量(TPS)、请求成功率
  • 系统指标:CPU使用率、内存使用率、磁盘IO延迟、网络丢包率

举个例子,当GPU温度超过80度时,推理延迟会明显增加。我一般设置这样的告警规则:

# Prometheus告警规则示例
groups:
- name: vllm-node-alerts
  rules:
  - alert: GPUHighTemperature
    expr: nvidia_gpu_temperature_celsius > 85
    for: 1m
    annotations:
      summary: "GPU温度过高,节点 {{ $labels.node }}"
      
  - alert: InferenceLatencySpike
    expr: histogram_quantile(0.99, rate(vllm_request_duration_seconds_bucket[5m])) > 2
    for: 30s
    annotations:
      summary: "推理P99延迟超过2秒"
      
  - alert: GPUECCError
    expr: increase(nvidia_gpu_ecc_errors_total[5m]) > 0
    for: 0s
    annotations:
      summary: "GPU出现ECC错误,需要立即排查"
🔑 核心观点:三种检测机制要配合使用。节点级检测保底,应用级检测保活,指标级检测保质量。缺一不可。

好了,这一章的内容就到这里。节点故障是推理运维的第一道坎,搞懂了它,后面的内容就好办了。下一章,咱们聊聊如何优雅地处理节点故障,让推理服务做到“故障无感”。


公众号:蓝海资料掘金营,微信deep3321