如何在具有正确组

时间:2016-03-23 17:36:45

标签: 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

source

我使用的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的图像中使用它?

2 个答案:

答案 0 :(得分:14)

有点晚了,但这可能有助于其他正在努力解决同一问题的用户:

此处的问题是,泊坞窗主机上的docker组与容器内docker组的ID具有不同的组ID。由于守护程序只关心id而不关心组的名称,因此只有当这些id偶然匹配时,你的解决方案才会起作用。

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

更安全的解决方法是确保容器内的docker组最终与容器外的docker组具有相同的组ID。您可以使用docker 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

然后使用

构建它
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

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

答案 1 :(得分:5)

我使用了你的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 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容器)。因此,建议将其安装到容器中,而不是将其安装在docker文件中。 我认为mount / 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