当前位置: 首页 > 知识库问答 >
问题:

如何将docker套接字作为卷装入具有正确组的docker容器中

柯天宇
2023-03-14

我想在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/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个答案

燕实
2023-03-14

我使用了您的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文件中。我认为挂载/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
司马洲
2023-03-14

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

这里的问题是,docker主机上的docker组的组id与容器中的docker组的id不同。由于守护进程只关心id,而不关心组的名称,因此只有当这些id意外匹配时,您的解决方案才会工作。

解决这个问题的方法是在启动Docker引擎时使用tcp而不是unix套接字,方法是使用-H选项。您应该非常小心,因为这允许任何有权访问此端口的人获得对系统的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很可能不再匹配。

 类似资料:
  • 我让jenkins在github上的容器和项目源代码中运行。 我需要在与jenkins相同的主机上运行容器中的项目,但不是作为docker中的docker,我希望将它们作为兄弟容器运行。 我的管道如下所示: 从github中提取源文件 我现在要做的是使用jenkins容器中主机的docker套接字: jenkins容器将源代码为/var/jenkins_home/workspace/BRANCH_

  • 我有很多运行docker容器的测试。每个都有一个卷。 如何知道需要删除的卷名? 例如: 手动停止并删除容器后,卷仍然存在。 我不想删除所有卷,因为其中一些卷仍在使用中。

  • 问题内容: 我正在尝试通过以下方式为我的docker容器明确指定IP地址: 我收到以下错误: 我真的不在乎端口10000。我的目标是选择一个特定的容器IP,并将端口9000和9090暴露给主机。 我看了其他一些问题,但没有看到明确的语法来做到这一点 问题答案: 该参数用于将端口从容器转发到主机,而不用于分配IP。 没有简单的方法将固定IP分配给Docker容器,我强烈建议您不要尝试。而是重新架构您

  • 我创建了一个Docker容器,只需在Ubuntu上安装Docker并执行以下操作: 我立即开始安装Java和一些其他工具,花了一些时间与它,并停止了容器通过 然后我想增加一个卷,并意识到这并不像我想的那样简单。如果我使用,那么我最终会得到一个新的容器,因此我必须安装Java并执行之前已经执行的操作,只需要到达一个具有已装入卷的容器。 所有关于从主机装入文件夹的文档似乎都暗示装入卷是创建容器时可以完

  • 问题内容: 我有一个Docker容器,它是通过在Ubuntu上安装Docker并执行以下操作而创建的: 我立即开始安装Java和其他一些工具,花了一些时间并通过以下方式停止了该容器 然后,我想添加一个卷,并意识到这并不像我想象的那样简单。如果我使用了,那么我将得到一个全新的容器,因此我将安装Java并做我已经做过的事情,然后再到达一个具有已安装卷的容器。 有关从主机安装文件夹的所有文档似乎都暗示了

  • 我正在运行一个Jenkins集群,其中主集群和从集群都作为Docker容器运行。 主机是在MacOS上运行的最新boot2docker VM。 为了让Jenkins能够使用Docker执行部署,我安装了Docker。从主机到Jenkins容器的sock和docker客户端,如下所示:- 我在将卷安装到在Jenkins容器内运行的Docker容器时面临问题。例如,如果我需要在Jenkins容器中运行