如何将docker套接字作为卷装入具有正确组的docker容器中
我想在docker容器中运行Jenkins实例 我希望Jenkins本身能够将docker容器作为奴隶来运行测试 似乎最好的方法是使用如何将docker套接字作为卷装入具有正确组的docker容器中,docker,jenkins,dockerfile,jenkins-docker,Docker,Jenkins,Dockerfile,Jenkins Docker,我想在docker容器中运行Jenkins实例 我希望Jenkins本身能够将docker容器作为奴隶来运行测试 似乎最好的方法是使用 docker run -v /var/run.docker.sock:/var/run/docker.sock -p 8080:8080 -ti my-jenkins-image 我使用的Dockerfile是 FROM jenkins COPY plugins.txt /usr/share/jenkins/plugins.txt RUN /usr/loca
docker run -v /var/run.docker.sock:/var/run/docker.sock -p 8080:8080 -ti my-jenkins-image
我使用的Dockerfile
是
FROM jenkins
COPY plugins.txt /usr/share/jenkins/plugins.txt
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt
USER root
RUN apt-get update && apt-get install -y docker.io
RUN usermod -aG docker jenkins
USER jenkins
如果我在运行的容器中启动bash会话,并在图像上运行docker info
,我会得到
$ docker info
FATA[0000] Get http:///var/run/docker.sock/v1.18/info: dial unix /var/run/docker.sock: permission denied. Are you trying to connect to a TLS-enabled daemon without TLS?
如果我以root用户身份运行bash会话
docker exec -u 0 -ti cocky_mccarthy bash
root@5dbd0efad2b0:/# docker info
Containers: 42
Images: 50
...
所以我猜我要添加Jenkins用户的docker
组是内部docker的组,因此如果没有sudo
,套接字是不可读的。这是一个问题,因为Jenkins docker插件等没有设置为使用sudo
如何安装套接字,以便在图像中使用它而无需
sudo
?我使用了您的dockerfile,但做了一个小编辑:
FROM jenkins
COPY plugins.txt /usr/share/jenkins/plugins.txt
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt
USER root
RUN apt-get update
RUN groupadd docker && gpasswd -a jenkins docker
USER jenkins
在构建映像后,我可以使用(我在centos7上)启动它:
您试图在映像中安装程序包docker.io。但是这个包也在您的主机上(否则就不可能在其上运行docker容器)。因此,建议将其装载到容器中,而不是安装在docker文件中。
我认为mounted/lib64/。。。特定于Centos 7
$ docker exec -it 9fc27d5fcec1 bash
jenkins@9fc27d5fcec1:/$ whoami
jenkins
jenkins@9fc27d5fcec1:/$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fc27d5fcec1 test "/bin/tini -- /usr/lo" 6 minutes ago Up 6 minutes 0.0.0.0:8080->8080/tcp, 50000/tcp jenkins
有点晚了,但这可能会帮助其他正在解决相同问题的用户: 这里的问题是,docker主机上的
docker
组的组id与容器中的docker
组的id不同。由于守护进程只关心id,而不关心组的名称,因此只有当这些id意外匹配时,您的解决方案才会工作
解决此问题的方法是使用tcp,而不是使用unix套接字,方法是在启动Docker引擎时使用。对此,您应该非常小心,因为这允许任何有权访问此端口的人获得对系统的root访问权
解决此问题的更安全的方法是确保容器内的docker
组与容器外的docker
组具有相同的组id。您可以使用docker构建的构建参数来实现这一点:
Dockerfile:
FROM jenkinsci
ARG DOCKER_GROUP_ID
USER root
RUN curl -o /root/docker.tgz https://get.docker.com/builds/Linux/x86_64/docker-1.12.5.tgz && tar -C /root -xvf /root/docker.tgz && mv /root/docker/docker /usr/local/bin/docker && rm -rf /root/docker*
RUN curl -L https://github.com/docker/compose/releases/download/1.7.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose
RUN groupadd -g $DOCKER_GROUP_ID docker && gpasswd -a jenkins docker
USER jenkins
然后使用
docker build --build-arg DOCKER_GROUP_ID=`getent group docker | cut -d: -f3` -t my-jenkins-image .
在此之后,您可以运行映像并以非root用户身份访问docker
docker run -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 -ti my-jenkins-image
由于此解决方案依赖于在生成映像时向docker守护程序提供正确的组id,因此需要在使用此映像的计算机上生成此映像。如果您构建映像,推送它,其他人在他们的机器上拉取它,很可能组id不会再次匹配。我有与OP相同的问题,我发现这篇文章很有帮助(尽管它不能解决权限问题)。作者建议不要将docker二进制文件从主机装载到容器:“这不再可靠了,因为docker引擎不再作为(几乎)静态库分发。”。这是很久以前我看的。你说这不再可靠是什么意思?我刚刚启动了一个容器并安装了.sock和bin,我可以在其中使用docker(1.12),还是我错了?谢天谢地,我没有足够的知识给你一个正确的答案,我只是想指出我发布的链接建议不要这样做。我可以在我的容器中使用docker来安装sock+bin(这是URL中的“好”解决方案)。我似乎不必使用特权标志。哦,现在我发现它不再可靠了。我必须探索一些问题。确保docker
组ID在主机上和容器内保持一致正是我们在面临相同问题时需要解决的问题。谢谢你找到解决问题的办法了吗?我现在面临同样的问题,我的解决方案是在容器启动后更改docker.sock的所有权docker exec-it-u root jenkins docker chown jenkins/var/run/docker.sock
docker run -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 -ti my-jenkins-image