如何在Jenkins流水线中迁移使用Podman容器替代Docker
Jenkins流水线从Docker迁移到Podman的问题
我当前的Jenkins流水线使用Docker容器,代码示例如下:
docker.image(image_name).inside(container_params) { // 此代码在Docker容器内执行 }
计划从Docker迁移到Podman,希望在Jenkinsfile中实现类似逻辑。
已在代理主机上安装podman-docker包,调整了subuid和subgid配置,尝试通过Jenkins Docker插件运行,但出现Docker版本不足的异常(实际使用的是Podman)。原本打算通过从RHEL 7升级到RHEL 9获取更高版本的Podman解决问题,但想知道有没有更优的迁移方案。
更新:
在Alma 9上使用Podman 4.9.4-rhel版本尝试后,容器能够启动,但无法在容器内部执行命令。
代码示例:
docker.image(image_name).inside(container_params) { sh(returnStdout: true, script:'echo test') }
返回错误:
process apparently never started in /home/jenkins/workspace/myjob@tmp/durable-efee3a5c (running Jenkins temporarily with -Dorg.jenkinsci.plugins.durabletask.BourneShellScript.LAUNCH_DIAGNOSTICS=true might make the problem clearer)
解决方案
1. 直接使用Podman命令行替代Docker插件
Jenkins Docker插件对Podman的兼容存在固有问题,直接调用Podman命令行是最稳妥的方案,无需依赖插件兼容:
sh """ podman run --rm -v \${WORKSPACE}:/workspace -w /workspace ${container_params} ${image_name} /bin/sh -c ' echo test # 这里可以添加更多需要执行的命令 ' """
如果需要多步骤执行,把所有命令打包到podman run的-c参数后即可,或者将脚本写入临时文件挂载到容器内执行。
2. 配置Podman兼容Docker插件(若坚持用插件)
若一定要保留Docker插件的语法,需确保Podman的API与Docker兼容,并调整以下配置:
- 确认rootless模式下
subuid/subgid映射已正确配置,Jenkins用户拥有对应的权限 - 在Jenkins代理上启动Podman API服务,例如:
podman system service unix:///run/user/$(id -u jenkins)/podman/podman.sock --time=0 & - 在Jenkins全局配置中,将Docker服务器地址指向Podman的套接字路径(如上述的Unix套接字)
- 确保Jenkins用户对Podman套接字有读写权限,可执行
chmod 660 /run/user/$(id -u jenkins)/podman/podman.sock或把Jenkins用户加入对应组
3. 解决容器内命令无法启动的问题
针对process apparently never started错误,可尝试以下操作:
- 确认使用的容器镜像包含
bash或sh(部分极简镜像未预装shell) - 在
sh步骤中指定shell路径:
docker.image(image_name).inside(container_params) { sh(returnStdout: true, script:'echo test', shell: '/bin/sh') }
- 检查Podman挂载的工作目录权限,确保容器内
/workspace目录有读写权限 - 添加Jenkins启动参数
-Dorg.jenkinsci.plugins.durabletask.BourneShellScript.LAUNCH_DIAGNOSTICS=true,查看诊断日志定位具体问题
内容的提问来源于stack exchange,提问作者Slava Kuravsky
相关产品推荐
相关产品推荐

