如何在Docker容器中将Docker套接字安装为正确的组

我想在Docker容器中运行一个Jenkins实例。

我希望jenkins本身能够将docker集装箱作为奴隶运行testing。

看来最好的办法就是使用

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 ... 

所以我猜想我joinjenkins用户的docker组是内部docker的组,因此如果没有sudo,套接字是不可读的。 这是一个问题,因为jenkinsdocker插件等没有设置使用sudo。

我怎样才能安装sockets,使其可以从图像中使用没有sudo?

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

这里的问题是你的docker主机上的docker组有一个不同的组ID,从您的容器内的docker组的ID。 由于守护进程只关心id而不关心组的名称,所以只有当这些id偶然匹配时,解决scheme才会起作用。

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

解决这个问题的更安全的方法是确保容器中的docker组最终拥有与容器外的docker组相同的组ID。 你可以使用你的docker build构build参数来做到这一点:

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 

然后用它来build造它

 docker build --build-arg DOCKER_GROUP_ID=`getent group docker | cut -d: -f3` -t my-jenkins-image . 

在此之后,您可以运行您的图像,并有docker访问作为非root

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

因为这个解决scheme依赖于在正在构build映像时向docker守护进程提供正确的组标识,所以这个映像需要在正在使用的机器上构build。 如果你build立图像,推它,并有人把它拉到他们的机器上,很可能是组ID不会再匹配。

我用你的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 

build立图像后,我可以开始使用(我在centos7上):

 docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $(which docker):/usr/bin/docker:ro \ -v /lib64/libdevmapper.so.1.02:/usr/lib/x86_64-linux-gnu/libdevmapper.so.1.02 \ -v /lib64/libudev.so.0:/usr/lib/x86_64-linux-gnu/libudev.so.0 \ -p 8080:8080 \ --name jenkins \ --privileged=true -t -i \ test/jenkins 

您试图在您的映像中安装包docker.io。 但是这个包也在你的主机上(否则不可能在其上运行docker容器)。 所以build议将其安装到您的容器中,而不是将其安装到您的docker文件中。 我认为挂载/ 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