如何在具有正确组的 docker 容器中将 docker socket 挂载为卷 [英] How to mount docker socket as volume in docker container with correct group

查看:24
本文介绍了如何在具有正确组的 docker 容器中将 docker socket 挂载为卷的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 docker 容器中运行 Jenkins 实例.

I want to run a Jenkins instance in a docker container.

我希望 Jenkins 本身能够启动 docker 容器作为从属容器来运行测试.

I want Jenkins itself to be able to spin up docker containers as slaves to run tests in.

似乎最好的方法是使用

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 我会得到

If I start a bash session in my running container and run docker info on my image I get

$ 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 会话

And if I run the bash session as root

docker exec -u 0 -ti cocky_mccarthy bash
root@5dbd0efad2b0:/# docker info
Containers: 42
Images: 50
...

所以我猜想我将 Jenkins 用户添加到的 docker 组是内部 docker 的组,因此如果没有 sudo,套接字将无法读取.这是一个问题,因为 Jenkins docker 插件等未设置为使用 sudo.

So I guess the docker group I'm adding the Jenkins user to is the group for the internal docker hence the socket is not readable without sudo. That's kind of a problem as the Jenkins docker plugin etc are not set up to use sudo.

如何安装套接字,以便在没有 sudo 的情况下从映像中使用它?

How can I mount the socket so it can be used from the image without sudo?

推荐答案

有点晚了,但这可能会对其他遇到同样问题的用户有所帮助:

A bit late, but this might help other users who are struggling with the same problem:

这里的问题是您的 docker 主机上的 docker 组的组 id 与容器内的 docker 组的 id 不同.由于守护进程只关心 id 而不是组的名称,因此您的解决方案只有在这些 id 偶然匹配时才有效.

The problem here is that the docker group on your docker host has a different group id from the id of the docker group inside your container. Since the daemon only cares about the id and not about the name of the group your solution will only work if these id's match by accident.

解决这个问题的方法是使用 tcp 而不是使用 unix 套接字,使用 -H option 在启动 Docker 引擎时.您应该非常小心,因为这允许任何有权访问此端口的人获得对您系统的 root 访问权限.

The way to solve this is by either using tcp instead of using a unix socket by using the -H option when starting Docker engine. You should be very careful with this, as this allows anyone who has access to this port to gain root access to your system.

解决此问题的更安全方法是确保容器内的 docker 组最终与容器外的 docker 组具有相同的组 ID.您可以使用 docker build 的构建参数来执行此操作:

A more secure way of fixing this is making sure that the docker group inside the container ends up having the same group id as the docker group outside of the container. You can do this using build arguments for your docker build:

Dockerfile:

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

After this you can run your image and have docker access as non-root

docker run  
  -v /var/run/docker.sock:/var/run/docker.sock  
  -p 8080:8080 
  -ti my-jenkins-image

由于此解决方案依赖于在构建映像时向 docker 守护程序提供正确的组 ID,因此需要在使用它的机器上构建此映像.如果您构建映像,然后将其推送,然后其他人将其拉到他们的机器上,则组 ID 很可能不会再次匹配.

Because this solution depends on supplying the correct group id to the docker daemon when the image is being built, this image would need to be built on the machine(s) where it is being used. If you build the image, push it and someone else pulls it on their machine, chances are that the group id's won't match again.

这篇关于如何在具有正确组的 docker 容器中将 docker socket 挂载为卷的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆