通过SLURM任务prolog脚本启动Docker服务失败求助
问题根源
SLURM的task prolog脚本属于SLURM作业启动流程的子进程,当prolog脚本执行完毕退出时,其所属的整个进程组会收到SIGHUP信号。即便用了nohup,rootlesskit可能仍未完全脱离prolog的进程组,导致被SLURM发送的信号终止——这就是日志停留在exec rootlesskit行的核心原因:进程还没完成初始化就被杀死了。而手动执行时,进程属于用户自身的会话组,不会被SLURM清理,因此能正常启动。
解决方案
1. 彻底脱离SLURM进程上下文
修改task_prolog.sh,用setsid让start-docker.sh完全脱离prolog的进程组和会话,避免被SIGHUP信号影响:
#!/usr/bin/env sh # 使用setsid创建独立会话,隔离SLURM进程组信号 nohup setsid start-docker.sh > docker-server.log 2>&1 &
setsid会生成全新的会话和进程组,让子进程完全独立于prolog脚本的上下文,即使prolog退出,子进程也不会收到终止信号。
2. 确保环境变量完整传递
检查/tmp/slurm/username/env.txt中的环境变量是否与手动执行时一致,尤其是XDG_RUNTIME_DIR、HOME、PATH这些无根Docker依赖的关键变量。如果prolog脚本的环境与用户登录环境有差异,可在task_prolog.sh中先加载用户环境配置:
#!/usr/bin/env sh # 加载用户bash环境(根据集群实际路径调整) source /home/username/.bashrc nohup setsid start-docker.sh > docker-server.log 2>&1 &
3. 验证进程状态
作业启动后,用以下命令检查rootlesskit和dockerd是否存活:
# 查找rootlesskit进程 pgrep -u username rootlesskit # 查看dockerd日志是否持续输出 tail -f docker-server.log
若进程存活且日志正常推进,说明问题已解决。
备选方案:用户级systemd服务(推荐)
如果集群节点支持用户级systemd,可将无根Docker注册为用户服务,通过systemd管理进程稳定性更高:
- 创建用户systemd服务文件
~/.config/systemd/user/docker.service:
[Unit] Description=Docker Daemon (Rootless) Documentation=https://docs.docker.com/engine/security/rootless/ [Service] Environment=PATH=/usr/bin:/home/username/.local/bin Environment=DOCKER_HOST=unix:///run/user/8076/docker.sock ExecStart=/usr/bin/dockerd-rootless.sh --data-root=/storage/docker-data/username/ --exec-root=/run/user/8076/ Restart=always RestartSec=5 [Install] WantedBy=default.target
- 启用服务:
systemctl --user enable docker
- 修改
task_prolog.sh启动服务:
#!/usr/bin/env sh systemctl --user start docker
这种方式下,Docker由systemd独立管理,完全脱离SLURM的prolog进程上下文,稳定性和可维护性更强。
内容的提问来源于stack exchange,提问作者Jav

