处理故障时,参考或者记录下的内容,持续更新中
1. XID 错误事件
XID 是 NVIDIA 的错误码,可以通过命令:
1
| dmesg -T | grep -i "NVRM: Xid"
|
或者
1
| journalctl --since `date -d "10 days ago" "+%Y-%m-%d"`|grep Xid
|
根据 XID 可以定位故障,下面是一些常见的 XID 事件
XID | 说明 |
---|
13 | Graphics Engine Exception。通常是数组越界、指令错误,小概率是硬件问题。 |
31 | GPU memory page fault。通常是应用程序的非法地址访问,极小概率是驱动或者硬件问题。 |
43 | GPU stopped processing。通常是用户应用自身错误而非硬件问题。 |
45 | Preemptive cleanup, due to previous errors – Most likely to see when running multiple cuda applications and hitting a DBE。通常是用户手动退出或者其他故障(硬件、资源限制等)导致 GPU 应用退出,Xid 45 只是一个结果,通常需要分析日志。 |
68 | NVDEC0 Exception。通常是硬件或驱动问题。 |
32 | Invalid or corrupted push buffer stream。事件由 PCIE 总线上管理 NVIDIA 驱动和 GPU 之间通信的 DMA 控制器上报,通常是 PCI 质量问题导致,而非用户程序产生。 |
38 | Driver firmware error。通常是驱动固件错误而非硬件问题。 |
48 | Double Bit ECC Error(DBE)。当 GPU 发生不可纠正的错误时,会上报 Xid48 事件。该错误也会同时反馈给用户的应用程序。通常需要重置 GPU 或重启节点来清除这个错误。 |
61 | Internal micro-controller breakpoint/warning。GPU 内部引擎停止工作,客户业务已经受到影响。 |
62 | Internal micro-controller halt。与 Xid61 的触发场景类似。 |
63 | ECC page retirement or row remapping recording event。当应用程序遭遇到 GPU 显存硬件错误时,NVIDIA 自纠错机制会将错误的内存区域 retire 或者 remap,retirement 和 remapped 信息需要记录到 infoROM 中才能永久生效。Volt 架构:记录 ECC page retirement 事件到 infoROM 成功。Ampere 架构:记录 row remapping 事件到 infoROM 成功 |
64 | ECC page retirement or row remapper recording failure。与 Xid63 的触发场景类似,只是 Xid63 代表 retirement 和 remapped 信息成功记录到了 infoROM,Xid64 代表该记录操作失败。 |
74 | NVLINK Error。NVLink 硬件错误产生的 Xid,收到此事件说明 GPU 已经出现严重硬件故障,需要下线维修。 |
79 | GPU has fallen off the bus。GPU 硬件检测到掉卡,无法从总线上检测到,收到此事件说明 GPU 已经出现严重硬件故障,需要下线维修。 |
92 | High single-bit ECC error rate。硬件或驱动故障。 |
94 | Contained ECC error。当应用程序遭遇到 GPU 不可纠正的显存 ECC 错误时,NVIDIA 错误抑制机制会尝试将错误抑制在踩到硬件故障的应用程序,而不会让错误导致 GPU 上的所有应用程序受到影响。当抑制机制成功抑制错误时,会产生 Xid 94 事件,仅影响遭遇了不可纠正 ECC 错误的应用程序。 |
95 | Uncontained ECC error。与 Xid94 的触发场景类似。只是 Xid94 代表抑制成功,而 Xid95 代表抑制失败,此时表明运行在该 GPU 上的所有应用程序都已受到影响。 |
详情参考 https://docs.nvidia.com/deploy/xid-errors/index.html
2. GPU 过高
通常 GPU 温度应该在 85°C 以下,超过时会出现锁频性能下降的问题。执行以下命令,能直接看到 GPU 编号及温度。
1
2
3
4
5
6
7
8
9
10
| nvidia-smi --query-gpu=index,temperature.gpu --format=csv,noheader
0, 28
1, 40
2, 44
3, 30
4, 27
5, 27
6, 31
7, 32
|
解决方案:
除了一些物理的方法,从纯软件层考虑,可以直接将温度超过阈值的 GPU 上面的应用程序杀掉,使其更换到其他的 GPU 上。
3. 重启掉卡,nvswitch 报错
1
| systemctl status nvidia-fabricmanager.service
|
或者
1
| less /var/log/fabricmanager.log | grep error
|
看到有 NVlink、NVSwitch 报错。
或者 nvidia-smi 找不到 device handle,Unknown Error 错误。
或者重启之后少卡。
解决方案:
启用 nvidia-persistenced 持久模式,让驱动程序保持加载状态,可以很大幅度的缓解这个问题。
4. Pod 中 nvidia-smi 报错 Function not Found
在 Pod 中执行命令报错:
1
2
3
4
5
6
7
8
9
10
11
12
13
| nvidia-smi
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.129.03 Driver Version: 535.129.03 CUDA Version: 12.2 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA TITAN X (Pascal) On | 00000000:03:00.0 Off | N/A |
| 23% 26C P8 8W / 250W | Function Not Found | 0% Default |
| | | N/A |
+-----------------------------------------+----------------------+----------------------+
|
因为 Pod 中的 cuda 版本过低,与节点上的 cuda 版本不匹配。
解决办法:
加上环境变量,重启应用。
1
| LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/lib/x86_64-linux-gnu:/usr/local/nvidia/lib
|
5. 显存无法释放
执行命令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| nvidia-smi
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.104.05 Driver Version: 535.104.05 CUDA Version: 12.2 |
|-----------------------------------------+----------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+======================+======================|
| 0 NVIDIA A800-SXM4-80GB On | 00000000:10:00.0 Off | 0 |
| N/A 32C P0 68W / 400W | 42058MiB / 81920MiB | 0% Default |
| | | Disabled |
+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
+---------------------------------------------------------------------------------------+
|
会看到没有进程使用显卡,但是显存依然被大量占用。
同时可以发现有一批杀不死的僵尸进程。
1
2
3
4
5
| ps aux | grep -E '\<defunct\>'
root 966461 0.0 0.0 6432 2488 pts/0 S+ 11:30 0:00 grep --color=auto -E \<defunct\>
root 2215172 0.0 0.0 0 0 ? Zl Apr04 1:10 [python] <defunct>
root 2215428 0.0 0.0 0 0 ? Zl Apr04 0:00 [python] <defunct>
root 2215442 0.0 0.0 0 0 ? Zl Apr04 0:00 [python] <defunct>
|
解决办法:
依次尝试重启 Kubelet、Docker、主机,即可释放显存资源
6. Docker Hang 住,节点 NotReady
在 Kubelet 中看到 PLEG is not healthy
相关错误日志。在 Docker 中没有异常日志。
可能是 runc hang 住了,因为 pipe 默认大小只有 64 MB,对于高性能计算场景不够用。
解决办法:
设置为 1GB,这里设置的是 262144 * 4K = 1GB
1
| echo "fs.pipe-user-pages-soft=262144" >> /etc/sysctl.conf && sysctl -p
|
7. df\ls hang 住, 无法响应
查看 hang 住的进程
1
2
3
| strace df -h
stat("/data/kubelet/pods/af4c411c-bafa-4322-9a21-e5c60ab1658e/volumes/kubernetes.io~nfs/workspace-pv",
|
找到相关的 mount point
1
2
3
| mount | grep mmt-10289-v2-1-4
1.1.1.1:/cfs-fSfmHNQjNA/workspace on /data/kubelet/pods/af4c411c-bafa-4322-9a21-e5c60ab1658e/volumes/kubernetes.io~nfs/workspace-pv type nfs (ro,relatime,vers=3,rsize=131072,wsize=524288,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=10.8.254.230,mountvers=3,mountport=300,mountproto=tcp,local_lock=none,addr=10.8.254.230)
|
确认目录已经不可使用
1
| ls /data/kubelet/pods/af4c411c-bafa-4322-9a21-e5c60ab1658e/volumes/kubernetes.io~nfs/workspace-pv
|
此时应该 hang 住无法响应。通常是远端服务 1.1.1.1 已经无法访问,但挂载的客户端未清理导致。
强行卸载目录
1
| umount -f /data/kubelet/pods/af4c411c-bafa-4322-9a21-e5c60ab1658e/volumes/kubernetes.io~nfs/workspace-pv
|
8. 磁盘 df 与 du 数据严重不符
使用 df 查看发现 /
使用了 86%。
1
2
3
4
| df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 435G 352G 62G 86% /
|
但使用 df 统计却只有很少使用量
1
2
3
| du -h --max-depth=2 --exclude=/data --exclude=/data1 --exclude=/var/lib/juicefs/volume / | grep '[0-9.]\+G'
32G /
|
原因是,删除大文件时,依然有程序占用文件,导致内核无法回收空间。
解决办法:
- 找出程序占用的文件
- 删除程序占用的文件
1
| lsof -n | grep deleted | awk '{print $2}' | sort -u | xargs sudo kill -9
|
使用 reboot 命令重启主机,只是系统层面,有些硬件故障不能恢复。
1
| ipmitool chassis power cycle
|
相当于断电重启。
10. version mismatch
1
2
3
4
| nvidia-smi
Failed to initialize NVML: Driver/library version mismatch
NVML library version: 535.129
|
1
2
3
4
5
| modinfo nvidia | grep version
version: 535.183.01
srcversion: E1D7E062E93D47A443165F6
vermagic: 5.4.0-1131-oracle SMP mod_unload modversions
|
解决办法:
卸载 nvidia driver 之后,重新安装
1
2
3
| apt-get --purge remove "*cublas*" "cuda*"
apt-get --purge remove "*nvidia*"
apt autoremove
|
11. no free node
使用 https://github.com/tkestack/gpu-manager 对 GPU 进行管理,需要注意驱动的版本不能太高,比如 535.183 无法兼容。
我们测试的可兼容版本是 535.129。
使用高版本驱动时,显存分配之后,无法正常回收,导致第一次分配完成之后,新 Pod 创建时会报错 no free node
。
根本原因在于,gpu-manager 无法获取到实时的显存信息。
在兼容的版本下如果遇到这个问题,可以尝试重启 kubelet,更新显存信息。
12. 企业版 JuiceFS 速度剧烈波动
在预热之后,访问速度应该能够平稳、较快,但如果 P2P 缓存服务节点组中,有访问慢的节点,会导致访问速度局部下降,拉低整体的访问速度。
可以进入 fluid 的 worker pod。
1
2
3
| ps aux | grep jfsmount
root 190 47.8 0.0 6160996 397776 ? S<l Sep13 673:59 /usr/local/juicefs/mount/jfsmount myjuicefs-storage /runtime-mnt/juicefs/mynamespace/myjuicefs-storage-fluid/juicefs-fuse -o cache-group=mynamespace-myjuicefs-storage-fluid,cache-size=5242880,free-space-ratio=0.1,cache-dir=/data1/jfs/cache:/data/jfs/cache,foreground,no-update
|
查看 P2P 缓存服务节点组之间的连接
排查是否有慢、不符合预期的节点,剔除相关节点即可恢复。
13. resolv.conf: no such file or directory
Pod 起不来,报错:
1
| /run/systemd/resolve/resolv.conf: no such file or directory
|
解决办法:
1
| vim /var/lib/kubelet/kubeadm-flags.env
|
在 KUBELET_KUBEADM_ARGS
中修改 --resolv-conf=/etc/resolv.conf
。
然后重启 kubelet
:
1
2
| systemctl daemon-reload
systemctl restart kubelet
|
14. 升级节点 CPU 之后 kubelet 起不来
报错信息
1
| start cpu manager error: current set of available CPUs \"0-7\" doesn't match with CPUs in state \"0-3\"
|
解决办法:
1
2
3
| rm -f /var/lib/kubelet/cpu_manager_state
systemctl daemon-reload
systemctl restart kubelet
|
15. gpu-manager 启动报错 can’t load container response data
报错信息
1
| can't load container response data, &json.SyntaxError{msg:"unexpected end of JSON input", Offset:0}
|
有时也会提示找不到 kubelet_internal_checkpoint
类似错误。
解决办法:
尝试多重启几次 Kubelet,如果还是不行就从其他节点拷贝 /var/lib/kubelet/device-plugins/kubelet_internal_checkpoint
文件到当前节点。
故障的原因是 GPU Manager 有 Bug,导致有时会无法生成 kubelet_internal_checkpoint
文件。
1
| wget https://ghp.ci/https://raw.githubusercontent.com/shaowenchen/hubimage/refs/heads/main/ai/kubelet_internal_checkpoint -O /var/lib/kubelet/device-plugins/kubelet_internal_checkpoint
|
16. cannot allocate unhealthy devices tencent.com/vcuda-core 无法创建 Pod
gpu manager 报错
1
| E1114 03:01:12.308213 33781 server.go:133] Unable to set Type=notify in systemd service file?
|
解决办法:
1
| systemctl restart kubelet
|
17. DCGM 报错 Failed to watch metrics
报错信息
1
| Failed to watch metrics: Error watching fields: Host engine is running as non-root
|
解决办法:
编辑 dcgm-exporter 的 DaemonSet,确认 Pod 的以下配置无误。
1
2
3
4
5
6
| securityContext:
capabilities:
add:
- SYS_ADMIN
runAsNonRoot: false
runAsUser: 0
|
特别是这里的 capabilities
配置,确保有 SYS_ADMIN
权限,仅仅 runAsUser: 0
还不够。
18. PCI 识别不到 GPU
执行命令:
1
| echo 1 > /sys/bus/pci/rescan
|
尝重新识别 PCI 设备,不一定能解决问题,因为有可能是硬件问题。
19. 分配不足一整张卡时报错 rpc client exit with 255
报错提示
1
| /tmp/cuda-control/src/register.c:87 rpc client exit with 255
|
解决办法:
添加环境变量
1
| LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/lib/x86_64-linux-gnu:/usr/local/nvidia/lib
|
原因是 CUDA 默认是不支持分配不足一整张卡的,需要 GPU 分片的组件支持。如果使用的是 GPU Manager,可以通过设置上面的环境变量劫持分配请求。
20. drain 禁用指定的故障卡
1
2
3
4
| nvidia-smi --query-gpu=index,pci.bus_id --format=csv
index, pci.bus_id
0, 00000000:18:00.0
|
第一列是卡的编号,第二列是卡的 PCI 位置。
1
| nvidia-smi drain -p 0000:18:00.0 -m 1
|
-m 1
表示驱逐状态,-m 0
表示关闭驱逐状态。执行完成之后,卡在 nvidia-smi 不可见,但在 lspci 中可见。
1
| nvidia-smi drain -p 0000:18:00.0 -q
|
21 NCCL Cannot allocate memory
报错提示,无法分配显存
misc/ibvwrap.cc:262 NCCL WARN Call to ibv_reg_mr failed with error Cannot allocate memory
解决办法:
给 Pod 添加上 IPC_LOCK
权限
1
2
3
4
| securityContext:
capabilities:
add:
- IPC_LOCK
|