【问题标题】:Permission denied to Docker daemon socket at unix:///var/run/docker.sock在 unix:///var/run/docker.sock 拒绝 Docker 守护进程套接字的权限
【发布时间】:2019-04-07 04:37:33
【问题描述】:

我有这个Dockerfile

FROM chekote/gulp:latest 

USER root
RUN apt-get update \
      && apt-get upgrade -y \
      && apt-get install -y sudo libltdl-dev

ARG dockerUser='my-user-name';
ARG group='docker';

# crate group if not exists
 RUN if ! grep -q -E "^$group:" /etc/group; then groupadd $group; fi

# create user if not exists
 RUN if ! grep -q -E "^$dockerUser:" /etc/passwd; then useradd -c 'Docker image creator' -m -s '/bin/bash' -g $group $dockerUser; fi

# add user to the group (if it was present and not created at the line above)
 RUN usermod -a -G ${group} ${dockerUser}

# set default user that runs the container
 USER ${dockerUser}

我是这样构建的:

docker build --tag my-gulp:latest .

最后由script 这样运行:

#!/bin/bash

image="my-gulp:latest";
workDir='/home/gulp/project';

docker run -it --rm  \
-v $(pwd):${workDir} \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
${image} /bin/bash

让我正确登录到 docker 容器,但是当我想查看图像时

docker images

或尝试拉图像

docker pull hello-world:latest

我收到此错误:

在尝试连接到 unix:///var/run/docker.sock 的 Docker 守护程序套接字时获得权限被拒绝:获取 http://%2Fvar%2Frun%2Fdocker.sock/v1.38/images/json:拨打 unix /var/run/docker.sock:连接:权限被拒绝

如何从chekote/gulp:latest 创建 docker 镜像,这样我就可以在其中使用 docker 而不会出错?

或者错误是因为错误的 docker run 命令?

【问题讨论】:

  • 我不是 100% 确定,但是在运行容器时尝试--privileged 标签。它可能会起作用。
  • 你为什么要启动你的 docker 容器
  • @Code Bling 这不是 inception,gulp 容器不会在其中运行 docker 容器,而是使用主机的 docker 启动与 gulp 容器处于同一级别的其他 docker 容器。 docker 命令从 gulp 容器向外发送到运行其他容器的主机,因此从主机的角度来看,它类似于通过 gulp 运行未容器化的容器。原因:即使主机上根本没有 gulp,您也可以通过使用不同的容器轻松地在 gulp 版本(例如 3.x 和 4.x)之间切换。
  • @Jimmix 哦,那太好了!仍然...开始。

标签: bash docker gulp dockerfile docker-run


【解决方案1】:

权限匹配只发生在 numeric 用户 ID 和组 ID 上。如果套接字文件是模式 0660 并且由用户 ID 0 和组 ID 32 所有,并且您以用户 ID 1000 和组 ID 1000 和 16 的用户身份调用它,那么 /etc/group 文件名是否无关紧要gid 32 为docker,另一个名称 gid 16 相同;数字 gid 不同,您无法访问该文件。此外,由于 Docker 组的实际数字 gid 会因系统而异,因此您无法将其写入 Dockerfile。

许多 Docker 镜像只是以 root 身份运行;如果这样做,他们可以访问绑定安装的 Docker 套接字文件,而不管其权限如何。

如果您以非root用户身份运行,您可以使用docker run --group-add option为有效用户添加(数字)gid; /etc/groups 文件中不需要特别提及。在 Linux 主机上,您可能会运行:

docker run --group-add $(stat -c '%g' /var/run/docker.sock) ...

您通常不会在 Dockerfile 中安装 sudo(它不适用于非交互式程序,由于容器的短暂性,您通常不会在交互式 shell 中做很多事情,而且您总是可以docker exec -u 0 获得root shell)尽管安装一些非root 用户通常被认为是最佳实践。您可以将 Dockerfile 减少到

FROM node:8
RUN apt-get update
# Trying to use the host's `docker` binary may not work well
RUN apt-get install -y docker.io
# Install the single node tool you need
RUN npm install -g gulp
# Get your non-root user
RUN adduser myusername
# Normal Dockerfile bits
WORKDIR ...
COPY ...
RUN gulp
USER myusername
CMD ["npm", "run", "start"]

(That Docker base imagea couple of things 与 Docker 最佳实践不符,并且似乎没有定期更新;我只使用标准 node图像作为基础,并在其上添加您需要的一个构建工具。)

【讨论】:

  • 您能否详细说明此声明Trying to use the hosts docker binary may not work well ?我在很多地方都安装了 docker 二进制文件以避免安装 docker。,
  • 宿主机是 MacOS 但容器是 Linux,所以宿主机的 docker 二进制文件不起作用。主机和容器都是 Linux,但共享库依赖项不同。 Docker 映像的关键目标之一是使其完全独立,从主机注入二进制文件或代码违反了此规则。
  • 我同意你关于注入二进制文件不好的观点。对于 Docker,我在 docker (DooS) 之外执行 Docker,当我将 MacOS docker 二进制文件挂载到 Linux 容器时,它可以正常工作。我相信,如果主机是 Windows,它可能无法正常工作。但是您是否认为在 Linux 容器上安装 MacOS docker 二进制文件有任何顾虑?这有助于避免在容器镜像上安装 docker。
  • MacOS 二进制文件不会在 Linux 环境中运行,句号。依赖于从主机注入的代码的图像将无法移植,这错过了使用 Docker 的意义。
  • 非常感谢,尤其是 group-add 标志。它使我免于做一些黑客攻击来做同样的事情。
【解决方案2】:

该错误与 docker pull 或 docker image 子命令无关,而是您需要以对 docker 套接字具有写访问权限的用户身份调用 docker 命令(例如,作为 root、使用 sudo 或加入 docker 组)。

【讨论】:

  • 但我在Dockerfile 中添加了my-user-namedocker 组,不是吗? RUN usermod -a -G ${group} ${dockerUser}
  • 您需要将主机上的用户添加到 docker 组,而不是容器中的用户。 Dockerfile的RUN命令在容器内部运行,不会影响宿主机。
【解决方案3】:

打开终端并输入此命令

sudo chmod 666 /var/run/docker.sock

让我知道结果...

【讨论】:

  • 感谢@Mohit Rakhade,为我工作得很好
  • 最简单的答案。
  • 最简单的!!
【解决方案4】:

避免这种情况的快速方法。将您的用户添加到组中。

sudo gpasswd -a $USER docker

然后设置适当的权限。

sudo setfacl -m user:<your username>:rw /var/run/docker.sock

从那里应该很好。

【讨论】:

  • 这可以节省一天!
  • 应该在上面,Brilliant!
  • 谢谢!这也是一个解决方案,例如在 Docker 中运行 Jenkins。
  • Docker 文档也详细说明了这一点:docs.docker.com/engine/install/linux-postinstall
  • 这是最好的。清脆甜美的回答。
【解决方案5】:

您的 docker run 命令需要 --privileged 标志。

顺便说一句,你可以只使用 docker 中的 docker ,来自 docker 的图像来处理这种用例。

https://asciinema.org/a/24707

https://hub.docker.com/_/docker/

【讨论】:

  • 该镜像描述中的第一行:“通常不建议在 Docker 中运行 Docker”。您也不需要--privileged 来访问绑定挂载的主机 Docker 套接字,您只需要正确获取套接字文件的 Unix 权限即可。
  • @DavidMaze 是的,不建议在生产中使用,但无论如何他都在尝试这样做,也许只是为了测试,通过自己制作 dind,这是多余的
猜你喜欢
  • 2021-08-13
  • 2018-05-30
  • 1970-01-01
  • 2020-01-03
  • 2021-12-06
  • 1970-01-01
  • 1970-01-01
  • 2022-07-07
  • 2017-11-24
相关资源
最近更新 更多