Docker容器中运行Jenkins时使用Docker的最佳实践及配置疑问
Jenkins与Docker集成:容器内执行Docker命令的核心逻辑
你困惑的点其实戳中了Docker客户端-守护进程架构的关键,我来一步步给你拆解:
首先明确一个核心事实:Jenkins容器里执行的docker命令只是客户端工具,真正负责构建镜像、管理容器的是宿主机上的Docker守护进程(daemon)。挂载宿主机的/var/run/docker.sock就是让容器里的客户端能和宿主机的daemon通信,但客户端本身得存在——也就是你说的Docker二进制文件,这部分有两种靠谱的解决方式:
方式一:在Jenkins容器内安装Docker客户端
这种方式最稳妥,也能保证客户端和宿主机daemon的版本兼容性(尽量让客户端版本和daemon版本差不超过1个大版本)。
你可以通过自定义Dockerfile来构建带Docker CLI的Jenkins镜像,示例如下:
# 基于官方Jenkins LTS镜像 FROM jenkins/jenkins:lts # 切换到root用户安装依赖 USER root # 安装Docker CLI(以Debian/Ubuntu基础镜像为例) RUN apt-get update && \ apt-get install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common && \ curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && \ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null && \ apt-get update && \ apt-get install -y docker-ce-cli # 切回Jenkins用户 USER jenkins
构建这个镜像后,启动容器时挂载宿主机的Docker socket:
docker run -d \ -p 8080:8080 \ -p 50000:50000 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v jenkins_home:/var/jenkins_home \ your-custom-jenkins-image:latest
方式二:直接挂载宿主机的Docker二进制到容器
如果不想自定义镜像,也可以把宿主机上的docker二进制文件挂载到Jenkins容器里,这样容器就能直接用宿主机的客户端工具:
启动容器时多加一个挂载参数:
docker run -d \ -p 8080:8080 \ -p 50000:50000 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker \ -v jenkins_home:/var/jenkins_home \ jenkins/jenkins:lts
⚠️ 注意:这种方式要确保宿主机的Docker客户端版本和容器内的依赖(比如libc库)兼容,如果出现“找不到依赖”的错误,还是推荐用方式一。
关键权限问题
不管用哪种方式,都要解决Jenkins用户访问Docker socket的权限问题:
- 宿主机的
/var/run/docker.sock通常属于docker用户组,所以你需要把容器内的Jenkins用户加入docker组:- 先查宿主机docker组的GID:
cat /etc/group | grep docker,得到类似docker:x:999:的结果,GID是999。 - 启动容器时指定添加组:
docker run -d \ -p 8080:8080 \ -p 50000:50000 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v jenkins_home:/var/jenkins_home \ --group-add=999 \ your-custom-jenkins-image:latest
- 先查宿主机docker组的GID:
整体流程梳理
当你在Jenkins流水线里执行docker build时:
- Jenkins容器内的Docker客户端发起请求
- 请求通过挂载的
/var/run/docker.sock传递给宿主机的Docker daemon - 宿主机的daemon执行实际的镜像构建操作
- 构建结果通过socket返回给容器内的客户端,Jenkins拿到结果继续流水线
这样你就能在Jenkins容器里顺利执行Docker命令,完成镜像构建啦~
内容的提问来源于stack exchange,提问作者Pedro Brost
相关产品推荐
相关产品推荐

