【问题标题】:Docker in Docker permissions errorDocker 中的 Docker 权限错误
【发布时间】:2017-02-10 16:54:34
【问题描述】:

我在 CI 的 docker setup 中有一个 docker。本质上,这台机器上有一个 jenkins CI 服务器,它使用相同的机器 docker 套接字为 CI 创建节点。

这一直很好,直到我最近更新了 docker。我已经确定了这个问题,但我似乎无法找出正确的魔法来让它发挥作用。

host $ docker exec -it myjenkins bash
jenkins@container $ docker ps
Got permission denied while trying to connect to the Docker daemon 
socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.26/containers/json: dial unix /var/run/docker.sock: connect: permission denied

host $ docker exec -it -u root -it myjenkins bash
root@container $ docker ps 
... docker ps from host container yay! ...

所以这就是我的猜测。我可以从容器内访问主机 docker 套接字,但我似乎无法向 jenkins 用户授予权限。

我已经添加了 docker 组,还将 jenkins 用户添加到了 docker 组。但我仍然得到同样的错误。我已经重新开始了很多次,所以我有点不知所措。

有没有办法强制用户在特定套接字上获得权限?

【问题讨论】:

  • 只是出于好奇,您是否尝试过使用特权容器(内部为 root)做同样的事情?
  • 如果你看看我在哪里展示控制台的问题。我表明我以 jenkins 用户身份尝试,然后再次以容器的 root 用户身份尝试。 root 用户有访问权限,jenkins 用户没有。
  • 只是出于好奇,你有没有用 privileged 容器尝试同样的事情(就像里面的詹金斯)
  • 与 `--userns=host` 一样吗?
  • 它是一个特权容器。我不知道如何使用--userns=host 我将如何使用 docker-compose 指定。

标签: jenkins docker


【解决方案1】:

您需要将主机上 docker 组的 gid 映射到容器内 jenkins 所属的组的 gid。这是我的 Dockerfile 中的一个示例,说明了我是如何构建 jenkins 从属映像的:

ARG DOCKER_GID=993

RUN groupadd -g ${DOCKER_GID} docker \
  && curl -sSL https://get.docker.com/ | sh \
  && apt-get -q autoremove \
  && apt-get -q clean -y \
  && rm -rf /var/lib/apt/lists/* /var/cache/apt/*.bin 

RUN useradd -m -d /home/jenkins -s /bin/sh jenkins \
  && usermod -aG docker jenkins

在本例中,993 恰好是主机上 docker 的 gid,您可以对其进行调整以匹配您的环境。


来自 OP 的解决方案: 如果无法重建,您可以使用 root 相应地设置 docker 组并添加用户。如果您之前尝试过此操作,则可能必须删除从站上的组(groupdel docker):

docker exec -it -u root myjenkins bash
container $ groupadd -g 993 docker
container $ usermod -aG docker jenkins

【讨论】:

  • 好的。我懂了。主机上的 docker 是 999。从属 docker 是 1001。所以你的意思是我需要确保从机上的 gid 与主机相同?你认为我可以只编辑/etc/group吗?
  • docker.sock文件上的gid也需要是容器内用户的gid。您可以使用此 ID 在映像中创建任何组,并将 Jenkins 添加到该组。如果不修复文件的权限,更改主机上的 /etc/group 将无法正常工作。
  • 优秀优秀优秀。我将用我的修复更新你的答案。
  • @BMitch 你真的是 docker 大师。高超!。我正在与这个问题作斗争三个多小时。最后你的回答画上了句号:-)
  • 当我将 docker.sock 挂载到容器时, ls -l 显示nobody nogroup。我错过了什么?
【解决方案2】:

正如其他答案中提到的,您必须确保容器内的用户“jenkins”有权通过/var/run/docker.sock 挂载向主机上的 Docker 引擎发出 Docker 命令。

一个简单的方法是:

$ docker run --rm -d --group-add $(stat -c '%g' /var/run/docker.sock) -v /var/run/docker.sock:/var/run/docker.sock -P myjenkins

但要注意:

如果您的 Jenkins 作业需要执行 Docker 构建/运行命令(例如,构建容器),这还不够。原因是容器化后的 Jenkins 会要求宿主机中的 Docker 部署一个 Docker 代理容器,而 Docker 代理容器在连接宿主机上的 Docker 守护进程时会面临类似的“权限错误”。

https://blog.nestybox.com/2019/09/29/jenkins.html 上有一篇博客文章描述了这个问题和解决方案。

【讨论】:

    【解决方案3】:

    就个人而言,我不得不这样做:

    sudo gpasswd -a $USER docker 
    

    成功了

    【讨论】:

      【解决方案4】:

      通过在开头包含 sudo 以 root 用户执行命令。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多