Docker 由于文件权限无法访问套接字

Docker socket not accessible due to file permissions

我正在尝试在 Docker 容器中模拟开发环境。作为这项工作的一部分,我希望 Docker 容器具有与主机相同的用户和组。这可以通过在 运行ning docker run 时挂载主机的用户和组配置文件来实现(请参阅底部的完整 docker 运行 命令)。

当您启动此容器时,您将以与主机上相同的用户和组登录容器(指定标志 --user $(id -u):$(id -g))。假设用户是 ubuntu 并且该组也是 ubuntu.

现在,我还希望能够从容器中 运行 Docker 命令。我尝试通过安装 docker 套接字文件来做到这一点,因此 Docker 容器中的 Docker 客户端可以与主机上的 Docker 守护程序通信。

在主机上,已将登录用户添加到组 docker 并设置了 docker 套接字文件权限,以便组 docker 中的任何用户都可以发出 docker 命令:

ubuntu@laptop:$ ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0 Feb  8 09:45 /var/run/docker.sock

ubuntu@laptop:$ docker images # (no sudo required)
REPOSITORY                                                           TAG                                        IMAGE ID       CREATED          SIZE
dind                                                                 latest                                     65b727c75899   42 minutes ago   611MB
postgres                                                             9.6-bullseye                               2266d156fa6a   5 weeks ago      239MB
ubuntu                                                               20.04                                      ba6acccedd29   3 months ago     72.8MB

但是,当我从容器内部 运行 一个 docker 命令如 docker images 时,我得到一个文件权限错误:

ubuntu@b5bb183641e8:$ docker images
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.24/images/json: dial unix /var/run/docker.sock: connect: permission denied

如果我运行在Docker容器中以root身份(或使用sudo)执行上述命令,则上述命令运行s正确。

发生这种情况是因为用户 ubuntu 能够 read/write 连接到主机上的 docker 套接字,但不能连接到容器上。我不明白为什么会出现这种情况,前提是我已经将所有相关的文件权限配置文件从主机挂载到容器中。我希望容器上的行为与主机上的行为相同。

作为参考, 容器的图像(标记为 `dind:latest)由以下 Dockefile

定义
FROM ubuntu:20.04

RUN apt update && apt -y install sudo docker.io

CMD /bin/bash

运行 安装了所有相关文件的 docker 容器:

$ docker run \
> --user $(id -u):$(id -g) \
> -v /etc/group:/etc/group:ro \
> -v /etc/gshadow:/etc/gshadow:ro \
> -v /etc/passwd:/etc/passwd:ro \
> -v /etc/shadow:/etc/shadow:ro \
> -v /etc/sudoers.d:/etc/sudoers.d:ro \
> -v /var/run/docker.sock:/var/run/docker.sock \
> dind:latest

当您使用此选项指定组时:

--user $(id -u):$(id -g)

这是唯一分配给用户的组,它会忽略 /etc/group 中指定的所有其他内容。通常您可以只指定用户,组 ID 将根据 /etc/passwd 和 /etc/group 配置。看起来像:

--user $(id -u)

不幸的是,我相信这是在挂载卷之前根据映像中的文件完成的。因此,您需要使用 --group-add 手动添加其他组,对于 docker 套接字,您需要 docker 组(您可能需要将其替换为 gid):

--group-add docker