You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Slurm集群用户无Docker权限致作业执行失败问题?

问题背景

我们团队搭建了一个使用Lua认证插件的Slurm集群,所有作业都在runc容器中运行,通过oci.conf配置容器运行逻辑。当前oci.conf内容如下:

CreateEnvFile=true
RunTimeQuery="sudo runc --rootless=true --root=/tmp/ state %n.%u.%j.%s.%t"
RunTimeKill="sudo runc --rootless=true --root=/tmp/ kill -a %n.%u.%j.%s.%t"
RunTimeDelete="sudo runc --rootless=true --root=/tmp/ delete --force %n.%u.%j.%s.%t"
RunTimeRun="CONTAINER_NAME=%n.%u.%j.%s.%t ORIG_BUNDLE_DIR=%b PREPARED_BUNDLE_DIR=/var/runc/config/%n.%u.%j.%s.%t && \
    /etc/slurm/prepare_bundle.py --orig-bundle-dir $ORIG_BUNDLE_DIR --prepared-bundle-dir $PREPARED_BUNDLE_DIR --container-name $CONTAINER_NAME --env-file %e && \
    sudo runc --rootless=true --root=/tmp/ run $CONTAINER_NAME -b $PREPARED_BUNDLE_DIR"

其中prepare_bundle.py依赖docker pull和docker export生成容器rootfs,但作业提交用户来自LDAP/AD,无Docker执行权限,导致脚本运行失败。之前尝试的两个方案均未生效:

  • 方案1(临时添加Docker组):在prolog脚本执行usermod -aG docker <user>,但作业会话中用户组信息未实时更新,id命令显示用户未加入docker组。
  • 方案2(切换提交UID):在SP插件的slurm_spank_task_init_privileged函数修改JOB_SUBMIT_UID,但prepare_bundle.py仍以原用户身份运行。
可行解决方案

1. 配置sudoers允许免密执行指定Docker命令

直接给作业用户授权免密运行docker pull和docker export命令,无需修改用户组:

  1. 创建sudoers规则文件/etc/sudoers.d/slurm-docker:
ALL ALL=(root) NOPASSWD: /usr/bin/docker pull *, /usr/bin/docker export *
  1. 修改prepare_bundle.py中的Docker命令,添加sudo前缀,比如:
subprocess.run(["sudo", "docker", "pull", image_name], check=True)
subprocess.run(["sudo", "docker", "export", container_id, "-o", rootfs_tar], check=True)

2. 以特权用户身份执行prepare_bundle.py

修改oci.conf中的RunTimeRun配置,让prepare_bundle.py以拥有Docker权限的专用用户(比如slurm-docker)运行:

RunTimeRun="CONTAINER_NAME=%n.%u.%j.%s.%t ORIG_BUNDLE_DIR=%b PREPARED_BUNDLE_DIR=/var/runc/config/%n.%u.%j.%s.%t && \
    sudo -u slurm-docker /etc/slurm/prepare_bundle.py --orig-bundle-dir $ORIG_BUNDLE_DIR --prepared-bundle-dir $PREPARED_BUNDLE_DIR --container-name $CONTAINER_NAME --env-file %e && \
    sudo runc --rootless=true --root=/tmp/ run $CONTAINER_NAME -b $PREPARED_BUNDLE_DIR"

同时需要在sudoers中添加规则,允许作业用户免密切换到slurm-docker执行该脚本:

ALL ALL=(slurm-docker) NOPASSWD: /etc/slurm/prepare_bundle.py *

3. 配置Rootless Docker

让每个LDAP用户可以独立运行Rootless Docker,无需依赖root权限:

  1. 在集群节点上为LDAP用户配置Rootless Docker环境(完成基础安装配置)。
  2. 修改prepare_bundle.py中的Docker命令,直接使用用户自身的Rootless Docker实例(无需sudo)。

4. 调整SPANK插件逻辑

之前修改JOB_SUBMIT_UID无效,是因为该字段仅控制作业提交记录的UID,不影响任务执行时的用户身份。正确的做法是在slurm_spank_task_init阶段切换到特权用户执行prepare_bundle.py,示例代码片段:

#include <slurm/spank.h>
#include <unistd.h>

SPANK_PLUGIN(slurm_docker_switch, 1);

int slurm_spank_task_init(spank_t sp, int ac, char **av) {
    // 切换到拥有Docker权限的用户(比如UID为1000的slurm-docker用户)
    if (setuid(1000) != 0) {
        slurm_error("Failed to switch to slurm-docker user");
        return -1;
    }
    // 执行prepare_bundle.py,需替换为实际参数
    system("/etc/slurm/prepare_bundle.py ...");
    // 切回原用户继续执行作业
    setuid(spank_get_item(sp, S_JOB_UID));
    return 0;
}
调试思路
  • 验证用户组更新问题:在prepare_bundle.py中执行id -nG并输出到日志,确认当前会话的组列表;用户组修改后需重新登录才会生效,Slurm作业会话不会自动加载新组,因此usermod方案本质不可行。
  • 检查Slurm日志:查看节点上的slurmd.log(通常在/var/log/slurm/),确认prolog脚本、SPANK插件是否正确执行,有无权限报错。
  • 测试sudo规则:以作业用户身份登录节点,手动执行sudo docker pull <镜像名>,确认是否无需密码即可运行。
  • 排查脚本权限:检查prepare_bundle.py的执行权限(需chmod +x),以及脚本中Docker命令的绝对路径是否正确(避免环境变量差异导致找不到命令)。

内容的提问来源于stack exchange,提问作者GustavoS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 01:52:11