问题排查

Kubernetes 问题排查与踩坑手册

🧠 核心排查思路

💡 控制变量法 (Control Variable Method)

面对诡异的“单点故障”,最有效的手段是寻找对照组。如果完全相同的镜像和配置在节点 A 挂掉,但在节点 B 正常,且两个节点的软件环境(驱动、OS)一致,那么问题的矛头直接指向硬件

graph TD
    A[Pod 异常崩溃] --> B{是否特定节点复现?}
    B -- No (随机节点) --> C[检查镜像/代码逻辑/资源限制]
    B -- Yes (固定节点) --> D[检查节点环境]
    D --> E{软硬件一致性检查}
    E -- 软件环境差异 --> F[系统/驱动重装]
    E -- 环境完全一致 --> G[硬件故障排查]
    G --> H[dmesg / Xid Errors]
    G --> I[Burning Test]

🛠️ 常用 Debug 工具箱

1. 节点隔离与现场保留

在排查特定节点问题时,首先要防止新流量进入,并保留“犯罪现场”。

# 1. 封锁节点 (Cordon),阻止新 Pod 调度上来
kubectl cordon <node_name>

# 2. 驱逐节点上的业务 Pod (Drain),安全排空
# --ignore-daemonsets: 忽略 DaemonSet 守护进程
# --delete-emptydir-data: 允许删除使用本地临时存储的 Pod
kubectl drain <node_name> --ignore-daemonsets --delete-emptydir-data

# 3. 调试大法: 手动调度 + 睡眠
# 将故障 Job 导出 YAML,指定 nodeName 强制调度到故障节点,并将启动命令改为sleep infinity
# 同时记得指定tolerance
spec:
  template:
    spec:
      tolerations:
      - effect: NoSchedule
        key: node.kubernetes.io/unschedulable
        operator: Exists
# 方便 exec 进去手动执行脚本,复现问题,并查看日志。
# 修改 Pod Spec:
# nodeName: <failure-node>
# command: ["/bin/bash", "-c", "sleep infinity"]

2. 硬件层深挖 (GPU 场景)

当应用层日志(Kubernetes Event, Pod Logs)只报模糊的 CUDA error 时,必须下沉到内核层。

⚠️ 踩坑实录:GPU 节点“幽灵”故障

案例一:CUDA error: unspecified launch failure

⚠️ 现象描述

任务在其他节点运行正常,唯独在某特定节点频发 unspecified launch failure。重装系统、驱动、K8s 后问题依旧。这通常不是软件问题,而是硬件不稳定的信号。

1. 核心定罪证据:Xid Errors

NVIDIA 驱动会将底层硬件错误抛给 Linux 内核。这是判断硬件故障的最强证据。

诊断命令

# 查看内核日志中关于 NVIDIA 的报错
dmesg | grep -i nvidia
# 或者直接搜索 Xid 关键字
dmesg | grep -i xid

典型报错解读

NVRM: Xid (PCI:0000:65:01): 109, ... errorString CTX SWITCH TIMEOUT

Xid 代码含义严重程度通俗解释
31, 43, 79Memory/Bus Error💀 致命显存坏了,或者掉卡了。直接判死刑。
61Thermal Violation🌡️ 过热显卡太烫了,自动降频导致的计算错误。检查风扇和硅脂。
109CTX Switch Timeout🛑 严重GPU 大脑冻结。上下文切换超时。驱动让 GPU 切换任务,GPU 没反应。通常是核心体质缩肛或供电瞬断。

2. “压力测试”验证 (Burn Test)

不要用业务代码测硬件,逻辑太复杂。用专门的 gpu-burn 压测工具,直接对显卡进行矩阵乘法轰炸。

# 绕过 K8s,直接在故障节点的 Docker 上运行
# 跑 60 秒压力测试,如果显卡有问题,通常几秒钟就会挂掉或报错
docker run --rm --gpus all rafaelsoares/gpu-burn:latest 60

3. 临时规避方案 (Workaround)

如果暂时无法更换硬件(RMA),可尝试通过降频锁定状态来牺牲性能换取稳定。

# 1. 开启持久模式 (Persistence Mode)
# 防止驱动频繁加载卸载,有时能缓解切换超时
sudo nvidia-smi -pm 1

# 2. 锁定频率 (Lock Clock)
# 强制将频率锁定在较低的安全值(例如核心 1000MHz),避免 Booster 冲高导致电压不稳
# 注意:你需要先查询显卡支持的频率范围
sudo nvidia-smi -lgc 1000
🛠️ 最终建议

如果降频能解决问题,说明显卡确实老化或体质不佳。建议拿着 dmesg 的 Xid 截图和 gpu-burn 的失败截图,直接联系供应商进行硬件更换。

🔗 参考与扩展