1. 现象描述
集群中 Slurm 表现异常:
-
sbatch正常提交任务,但作业很快失败(FAILED/CANCELLED) -
计算节点上
slurmd服务启动后很快退出 -
systemd 日志仅显示:
Started Slurm node daemon. slurmd.service: Main process exited, code=exited, status=1/FAILURE slurmd.service: Failed with result 'exit-code'.
这类输出并不能直接说明根因,需要进一步深入 slurmd 前台日志与 GPU/驱动状态。
2. 快速定位:前台启动 slurmd 暴露真实错误
在故障节点执行:
slurmd -Dvvv
输出关键错误:
slurmd: error: Waiting for gres.conf file /dev/nvidia0
这句话非常关键,含义是:
- Slurm 的 GPU 资源(GRES)配置中,指定了 GPU 设备文件(例如
File=/dev/nvidia0) - slurmd 启动时会等待该设备节点出现
- 但系统里
/dev/nvidia0不存在,于是 slurmd 阻塞等待;systemd 侧可能因超时/退出表现为status=1/FAILURE
同时验证 GPU 驱动:
nvidia-smi
报错:
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver.
进一步确认硬件存在:
lspci | grep -i nv
可见 RTX 4090(AD102)设备在 PCIe 上存在,问题集中在 驱动没有正确加载。
3. 根因分析:Kernel 升级导致 NVIDIA 内核模块不匹配
在 /boot 下看到两版内核:
vmlinuz-4.18.0-425.3.1.el8.x86_64(旧)vmlinuz-4.18.0-553.89.1.el8_10.x86_64(新,近期更新)
Kernel 升级后,如果 NVIDIA 驱动是 runfile 方式安装(.run),或者 DKMS/akmods 未成功重编译,那么会出现典型现象:
nvidia内核模块无法为新内核构建/加载/dev/nvidia0不会生成nvidia-smi无法通讯- Slurm 配置了 GPU GRES(
gres.conf指向/dev/nvidia0) → slurmd 启动卡住 → 作业秒失败
4. 驱动编译失败证据:MPOL_PREFERRED_MANY 宏冲突(UVM 编译不过)
尝试用 NVIDIA-Linux-x86_64-535.86.05.run 为新内核编译模块时,失败点出现在 nvidia-uvm:
关键报错片段:
uvm_linux.h:150:32: error: expected identifier before numeric constant
#define MPOL_PREFERRED_MANY 5
include/uapi/linux/mempolicy.h:25:2: note: in expansion of macro 'MPOL_PREFERRED_MANY'
MPOL_PREFERRED_MANY,
解释一下这类报错的本质:
- 新内核头文件中
MPOL_PREFERRED_MANY已作为枚举/符号存在 - 535.86.05 的 UVM 代码又
#define MPOL_PREFERRED_MANY 5,导致名称冲突 - 因此
nvidia-uvm模块无法构建 → CUDA/UVM 不可用 → 驱动链不完整
结论:这个组合(EL8_10 新内核 + 535.86.05 runfile)在该环境下无法顺利构建 UVM 模块。
5. 解决方案(按“恢复速度”排序)
方案 A:最快恢复业务(回滚到旧内核启动)
适用场景:希望立即恢复 GPU/Slurm 正常运行,后续再处理升级。
1)查看 grub 条目并设置旧内核为默认启动:
grubby --info=ALL | egrep "index=|kernel="
grubby --set-default /boot/vmlinuz-4.18.0-425.3.1.el8.x86_64
reboot
2)重启后验证:
uname -r
nvidia-smi
ls -l /dev/nvidia0
systemctl restart slurmd
只要驱动恢复,slurmd 就不会再卡在 /dev/nvidia0。
方案 B:根治(升级驱动到支持新内核的版本,并采用 DKMS 机制)
适用场景:希望以后内核升级也不容易再“炸 GPU”。
思路:不要继续用老的 .run 驱动硬怼新内核,而是使用 官方仓库 + DKMS 的方式,让驱动自动为新内核编译模块。
1)卸载 runfile 驱动(避免混装):
/usr/bin/nvidia-uninstall || sh NVIDIA-Linux-x86_64-535.86.05.run --uninstall
2)切换到 DKMS 驱动路线(示例为 rhel8 系):
dnf -y install dnf-plugins-core
dnf config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/cuda-rhel8.repo
dnf clean all
dnf -y module reset nvidia-driver
dnf -y module enable nvidia-driver:latest-dkms
dnf -y module install nvidia-driver:latest-dkms
reboot
3)重启后验证:
uname -r
nvidia-smi
ls -l /dev/nvidia0
systemctl restart slurmd
方案 C:Slurm 临时止血(先让 CPU 作业跑起来)
适用场景:GPU 暂时不可用,但希望 slurmd 不要因为 GRES 阻塞启动。
处理方式:临时移除/注释 gres.conf 中对 /dev/nvidia0 的强依赖,或把该节点的 Gres=gpu:* 从 slurm.conf 中移除。
常见修改点:
-
/etc/slurm/gres.conf中类似:Name=gpu File=/dev/nvidia0临时注释掉
然后重启:
systemctl restart slurmd
这样该节点将以 CPU-only 方式可用,等 GPU 修好再恢复 GRES 配置即可。
6. 验证闭环:确认 Slurm 与 GPU 都恢复
GPU 恢复的标志:
nvidia-smi
ls -l /dev/nvidia0
lsmod | grep -E '^nvidia'
Slurm 恢复的标志:
systemctl status slurmd -l
scontrol show node <nodename> | egrep -i "State|Reason|Gres"
如果 Reason 不再包含 SlurmdDown,且节点状态从 DOWN/DRAIN 回到 IDLE/ALLOCATED,则闭环完成。
7. 经验总结与预防建议
- 内核升级 = 驱动重建
- 任何一次 EL 内核升级,都要确认 NVIDIA 模块是否同步重编译、
nvidia-smi是否正常。
- 任何一次 EL 内核升级,都要确认 NVIDIA 模块是否同步重编译、
- 尽量使用 DKMS/仓库方式管理驱动
- runfile 安装在“内核频繁升级”的场景下维护成本高,容易出现“升级完内核 GPU 全挂”。
- Slurm GPU 节点要考虑“驱动掉线”的降级策略
- 如果不希望 GPU 掉了导致 slurmd 启动失败,可以对 GRES 配置与节点分区做更稳妥的隔离(例如 GPU-only 分区、节点状态自动 drain 等)。