以非 root 用户身份从 Docker Ubuntu 容器内部调用 Mac 主机上的 Docker 时出现权限被拒绝错误

Permission denied error invoking Docker on Mac host from inside Docker Ubuntu container as non-root user

我正在尝试从内部为 Mac 17.06.0-ce-mac17 在我的 OSX 主机 运行ning Docker 上调用 docker一个 运行ning jenkins docker 容器 (jenkins:latest), per the procedure described at http://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/.

我将 /var/run/docker.sock 挂载到容器中,我在其中粘贴了一个 ubuntu docker 二进制文件,它能够执行 - 但是从容器内部作为用户 "jenkins" 当我 运行 例如"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.30/containers/json?all=1: dial unix /var/run/docker.sock: connect: permission denied.  

如果我以 root 身份连接到容器 (docker exec -u 0),它仍然可以工作。

我需要 jenkins 用户能够 运行 这个。我尝试添加一个 docker 组并在 ubuntu 容器内向其添加 jenkins 但这没有帮助,因为它与外部和 Docker 对于 Mac 不像 运行 在 linux 上那样工作,在那里你可以进行半简单的 uid/gid 匹配。我想分发这个容器,所以去破解我的 Docker for Mac 安装的一部分的答案不会真正帮助我。如果可以的话,我宁愿不 运行 将整个 jenkins 设置为 root。 (我还尝试 运行 将容器设置为特权,但没有帮助。)

根据 中的建议,我手动将容器内的 /var/run/docker.sock 文件添加到 jenkins,现在 jenkins 可以 运行 docker。但是我在想出一个可分发容器的解决方案时遇到了麻烦——我无法在 Docker 文件中执行该操作,因为该文件尚不存在,并且填充到入口点也无济于事因为那 运行 是詹金斯。

我需要做什么才能构建和 运行 一个图像,它将 运行 外部 docker 容器作为非根用户 Mac从容器内部?

我已经开始工作了,至少是自动化的,但目前只在 docker 上为 Mac 工作。 Docker for Mac has a unique file permission model。 Chowning /var/run/docker.sock 到 jenkins 用户手动工作,并且它在容器重新启动甚至图像重新生成时持续存在,但不会超过 docker 守护进程重新启动。另外,你不能在 Dockerfile 中执行 chown,因为 docker.sock 还不存在,你不能在入口点执行它,因为 运行s 作为 jenkins。

所以我所做的是将 jenkins 添加到 "staff" 组,因为在我的 Mac 上,/var/run/docker.sock 被符号链接到 /Users//Library/Containers/com。 docker.docker/Data/‌ s60 是 uid 和 gid 的工作人员。这让 jenkins 用户 运行 docker 在主机上发出命令。

Docker 文件:

FROM jenkins:latest

USER root

RUN \
    apt-get update && \
    apt-get install -y build-essential && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

COPY docker /usr/bin/docker

# To allow us to access /var/run/docker.sock on the Mac
RUN gpasswd -a jenkins staff

USER jenkins

ENTRYPOINT ["/bin/tini", "--", "/usr/local/bin/jenkins.sh"]

docker-compose.yml 文件:

version: "3"
services:
  jenkins:
    build: ./cd_jenkins
    image: cd_jenkins:latest
    ports:
      - "8080:8080"
      - "5000:5000"
    volumes:
      - ./jenkins_home:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock

但是,这不能移植到其他系统(并且取决于 docker 对于 mac 组保持 "staff," 我认为不能保证)。我很乐意提出改进建议,使该解决方案可以跨主机系统工作。 Execute docker host command inside jenkins docker container 等问题中建议的其他选项包括:

  • 安装 sudo 并让 jenkins sudo 和 运行 所有 docker 命令都带有 sudo:添加安全问题
  • "Add jenkins to the docker group" - 仅限 UNIX,并且可能依赖于将 gids 从主机匹配到容器,对吗?
  • 设置包含的 docker 可执行文件可能有效,但与 sudo 具有相同的安全提升问题。

按照这个:https://forums.docker.com/t/mounting-using-var-run-docker-sock-in-a-container-not-running-as-root/34390

基本上,您需要做的就是更改容器内的 /var/run/docker.sock 权限,并 运行 将 docker 更改为 sudo

我创建了一个 Dockerfile 可以用来帮助:

FROM jenkinsci/blueocean:latest

USER root
# change docker sock permissions after moutn
RUN if [ -e /var/run/docker.sock ]; then chown jenkins:jenkins /var/run/docker.sock; fi

另一种对我有用的方法 - 将 uid 参数设置为拥有 /var/run/docker.sock 的 uid(在我的例子中是 501)。不确定 Dockerfile 的语法,但是对于 docker-compose.yml,它是这样的:

version: 3
services:
  jenkins:
    build:
      context: ./JENKINS
      dockerfile: Dockerfile
      args:
        uid: 501
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    ...

请注意,这是基于使用 Dockerfile 构建 jenkins 映像,因此省略了很多细节。这里的关键位是 args.

下的 uid: 501

感谢@mxyzplk 的post。

对我有用: “ Chowning /var/run/docker.sock 到 MacOS 用户手动工作,并且它在容器重新启动甚至图像重新生成时持续存在,但不会超过 docker 守护程序重新启动。 “

my command records