docker 中的 Jenkins 可以访问主机 docker
Jenkins in docker with access to host docker
我有一个如下的工作流程,用于将 web 应用程序发布到我的开发服务器。服务器只有一个 docker 主机,我正在使用 docker-compose 来管理容器。
- 将我的应用程序中的更改推送到私有 gitlab(运行ning 在 docker 中)。该应用程序包含一个 Dockerfile 和 docker-compose.yml
- Gitlab 触发 jenkins 构建(jenkins 也在 docker 中 运行ning),它会做一些正常的构建工作(例如 运行 测试)
- Jenkins 然后需要构建一个新的 docker 镜像并使用 docker-compose 部署它。
我遇到的问题是在第 3 步。按照我设置的方式,jenkins 容器可以访问主机 docker,因此 运行 可以执行任何 docker
命令在构建脚本中与在主机上 运行ning 基本相同。这是为詹金斯使用以下 DockerFile
完成的:
FROM jenkins
USER root
# Give jenkins access to docker
RUN groupadd -g 997 docker
RUN gpasswd -a jenkins docker
# Install docker-compose
RUN curl -L https://github.com/docker/compose/releases/download/1.2.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose
USER jenkins
并将以下卷映射到 jenkins 容器:
-v /var/run/docker.sock:/var/run/docker.sock
-v /usr/bin/docker:/usr/bin/docker
jenkins 中的典型构建脚本如下所示:
docker-compose build
docker-compose up
这工作正常,但有两个问题:
感觉真的是hack了。但我发现的唯一其他选择是使用 jenkins 的 docker 插件,发布到注册表,然后通过某种方式让主机知道它需要重新启动。这是相当多的移动部件,docker-jenkins 插件要求 docker 主机在一个开放端口上,我真的不想公开它。
jenkins DockerFile 包含 groupadd -g 997 docker
,这是让 jenkins 用户访问 docker 所必需的。但是,GID (997) 是主机上的 GID,因此不可移植。
我不太确定我在寻找什么解决方案。我看不出有任何实用的方法来绕过这种方法,但是如果有一种方法可以在 jenkins 容器中允许 运行ning docker 命令而不必在 GID 中硬编码Docker 文件。有人对此有什么建议吗?
我运行遇到同样的问题。由于 GID 问题,我最终给了 Jenkins 无密码 sudo 权限。我在这里写了更多相关内容:https://blog.container-solutions.com/running-docker-in-jenkins-in-docker
这不会真正影响安全性,因为拥有 docker 权限实际上等同于 sudo 权限。
请看一下我刚刚发布的 docker 文件:
https://github.com/bdruemen/jenkins-docker-uid-from-volume/blob/master/gid-from-volume/Dockerfile
这里是从挂载的卷(主机目录)中提取的 GID,
stat -c '%g' <VOLUME-PATH>
然后将容器用户所在组的GID改为与
相同的值
groupmod -g <GID>
这必须以 root 身份完成,但随后 root 权限会被
删除
gosu <USERNAME> <COMMAND>
一切都在 ENTRYPOINT 中完成,所以真正的 GID 是未知的,直到你 运行
docker run -d -v <HOST-DIRECTORY>:<VOLUME-PATH> ...
请注意,更改 GID 后,进程可能无法再访问容器中的其他文件,因此您可能需要
chgrp -R <GROUPNAME> <SOME-PATH>
在 gosu 命令之前。
您也可以更改 UID,请看我的回答Changing the user's uid in a pre-build docker container (jenkins)
也许您想更改两者以提高安全性。
我之前的回答比较笼统,告诉你如何在运行时修改容器内的 GID。现在,巧合的是,我的亲密同事中有人要求可以进行 docker 开发的 jenkins 实例,所以我创建了这个:
FROM bdruemen/jenkins-uid-from-volume
RUN apt-get -yqq update && apt-get -yqq install docker.io && usermod -g docker jenkins
VOLUME /var/run/docker.sock
ENTRYPOINT groupmod -g $(stat -c "%g" /var/run/docker.sock) docker && usermod -u $(stat -c "%u" /var/jenkins_home) jenkins && gosu jenkins /bin/tini -- /usr/local/bin/jenkins.sh
(父 Dockerfile 与我在回答中描述的相同:Changing the user's uid in a pre-build docker container (jenkins))
要使用它,请安装 jenkins_home 和 docker.sock。
docker run -d /home/jenkins:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock <IMAGE>
容器中的jenkins进程会和挂载的主机目录拥有相同的UID。假设主机上的 docker 组可以访问 docker 套接字,则在容器中创建了一个组,也名为 docker,具有相同的 GID。
我有一个如下的工作流程,用于将 web 应用程序发布到我的开发服务器。服务器只有一个 docker 主机,我正在使用 docker-compose 来管理容器。
- 将我的应用程序中的更改推送到私有 gitlab(运行ning 在 docker 中)。该应用程序包含一个 Dockerfile 和 docker-compose.yml
- Gitlab 触发 jenkins 构建(jenkins 也在 docker 中 运行ning),它会做一些正常的构建工作(例如 运行 测试)
- Jenkins 然后需要构建一个新的 docker 镜像并使用 docker-compose 部署它。
我遇到的问题是在第 3 步。按照我设置的方式,jenkins 容器可以访问主机 docker,因此 运行 可以执行任何 docker
命令在构建脚本中与在主机上 运行ning 基本相同。这是为詹金斯使用以下 DockerFile
完成的:
FROM jenkins
USER root
# Give jenkins access to docker
RUN groupadd -g 997 docker
RUN gpasswd -a jenkins docker
# Install docker-compose
RUN curl -L https://github.com/docker/compose/releases/download/1.2.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose
USER jenkins
并将以下卷映射到 jenkins 容器:
-v /var/run/docker.sock:/var/run/docker.sock
-v /usr/bin/docker:/usr/bin/docker
jenkins 中的典型构建脚本如下所示:
docker-compose build
docker-compose up
这工作正常,但有两个问题:
感觉真的是hack了。但我发现的唯一其他选择是使用 jenkins 的 docker 插件,发布到注册表,然后通过某种方式让主机知道它需要重新启动。这是相当多的移动部件,docker-jenkins 插件要求 docker 主机在一个开放端口上,我真的不想公开它。
jenkins DockerFile 包含
groupadd -g 997 docker
,这是让 jenkins 用户访问 docker 所必需的。但是,GID (997) 是主机上的 GID,因此不可移植。
我不太确定我在寻找什么解决方案。我看不出有任何实用的方法来绕过这种方法,但是如果有一种方法可以在 jenkins 容器中允许 运行ning docker 命令而不必在 GID 中硬编码Docker 文件。有人对此有什么建议吗?
我运行遇到同样的问题。由于 GID 问题,我最终给了 Jenkins 无密码 sudo 权限。我在这里写了更多相关内容:https://blog.container-solutions.com/running-docker-in-jenkins-in-docker
这不会真正影响安全性,因为拥有 docker 权限实际上等同于 sudo 权限。
请看一下我刚刚发布的 docker 文件: https://github.com/bdruemen/jenkins-docker-uid-from-volume/blob/master/gid-from-volume/Dockerfile
这里是从挂载的卷(主机目录)中提取的 GID,
stat -c '%g' <VOLUME-PATH>
然后将容器用户所在组的GID改为与
相同的值groupmod -g <GID>
这必须以 root 身份完成,但随后 root 权限会被
删除gosu <USERNAME> <COMMAND>
一切都在 ENTRYPOINT 中完成,所以真正的 GID 是未知的,直到你 运行
docker run -d -v <HOST-DIRECTORY>:<VOLUME-PATH> ...
请注意,更改 GID 后,进程可能无法再访问容器中的其他文件,因此您可能需要
chgrp -R <GROUPNAME> <SOME-PATH>
在 gosu 命令之前。
您也可以更改 UID,请看我的回答Changing the user's uid in a pre-build docker container (jenkins) 也许您想更改两者以提高安全性。
我之前的回答比较笼统,告诉你如何在运行时修改容器内的 GID。现在,巧合的是,我的亲密同事中有人要求可以进行 docker 开发的 jenkins 实例,所以我创建了这个:
FROM bdruemen/jenkins-uid-from-volume
RUN apt-get -yqq update && apt-get -yqq install docker.io && usermod -g docker jenkins
VOLUME /var/run/docker.sock
ENTRYPOINT groupmod -g $(stat -c "%g" /var/run/docker.sock) docker && usermod -u $(stat -c "%u" /var/jenkins_home) jenkins && gosu jenkins /bin/tini -- /usr/local/bin/jenkins.sh
(父 Dockerfile 与我在回答中描述的相同:Changing the user's uid in a pre-build docker container (jenkins))
要使用它,请安装 jenkins_home 和 docker.sock。
docker run -d /home/jenkins:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock <IMAGE>
容器中的jenkins进程会和挂载的主机目录拥有相同的UID。假设主机上的 docker 组可以访问 docker 套接字,则在容器中创建了一个组,也名为 docker,具有相同的 GID。