【问题标题】:Docker mount volumes as root [closed]Docker以root身份挂载卷[关闭]
【发布时间】:2019-01-29 02:07:01
【问题描述】:

为什么 Docker 将卷挂载为root,而不是作为运行命令docker run 的用户?这可以通过设置一些参数/参数等来改变吗?

MWE:

$ ls -la
drwxr-xr-x 2 ubuntu   ubuntu   4096 Aug 22 18:09 shinylog

$ docker run -v $(pwd)/test_dir/:/home/ --name nginx -d nginx
bf340face11485a81ee7c208d490f11abbdc84089ffe9c01d71ffcf8b9ffc27d

$ ls -la
drwxr-xr-x 2 ubuntu   ubuntu   4096 Aug 22 18:09 shinylog
drwxr-xr-x 2 root     root   4096 Aug 22 18:33 test_dir

$ echo $USER
ubuntu

编辑: 安装docker后遇到错误:

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.38/containers/json: dial 
unix /var/run/docker.sock: connect: permission denied

并执行:

sudo usermod -a -G docker $USER

也许这就是问题所在?

【问题讨论】:

  • 发生这种情况是因为您已将当前用户添加到 docker 组。如果当前用户是 root,那么它将以 root 身份挂载。完成 docker 设置步骤
  • @Kalanamith 我按照此处的建议将ubuntu 用户添加到docker 组:docs.docker.com/install/linux/linux-postinstall/… - 而且我没有以root 身份运行docker。

标签: docker permissions docker-volume


【解决方案1】:

运行 nginx 的进程在 root 下运行,所以它使用 root 的 UID 写入文件。

解决方案

export UID && docker run -v $(pwd)/test_dir/:/home/ -u=$UID:$UID  --name nginx -d nginx

这将使用您的本地 UID 运行 nginx 进程,从而使用同一用户写入文件。我没有在 mac 下测试过,但这是 linux 上常见的解决方案/设置,所以它会为你工作。

如何验证这是否有效?

用sleep运行nginx,让它运行很长时间,即使配置错误。

export UID && docker run -v $(pwd)/test_dir/:/home/ -u $UID:$UID --name nginx -d nginx sleep 3000000000000

现在在容器中执行并运行 whoami 来验证用户的 uid。例如在我的机器上

docker exec -it nginx /bin/bash
I have no name!@f12fa9c368e6:/$ whoami
whoami: cannot find name for user ID 501

【讨论】:

  • 我已经尝试使用参数-u UID:UID 运行,而test_dir 仍然拥有root 所有者。
  • 你使用的 UID 值是多少?和 echo $UID 一样吗?在重新运行 nginx 容器之前,还要删除容器和文件夹。我将使用命令更新答案以验证它是否有效
  • 我的 UID 是 id -u,它给出了 1000
  • 能否如上图运行带有 sleep 的 nginx 容器并验证容器内的 UID?你删除了文件夹吗?
  • $ whoami whoami: cannot find name for user ID 1000test_dir 仍然是 root 拥有的
【解决方案2】:

docker 命令是dockerd 守护程序的其余 API 的接口。该守护进程负责配置卷并执行任务以运行容器。在今天的大多数安装中,这个守护进程都以 root 身份运行。

对于主机卷,它们是具有额外功能的 Linux 绑定挂载。通常使用绑定挂载,源目录必须已经存在。但是为了提高可用性,如果这个目录不存在,docker 会为你创建这个目录。它通过以 root 身份运行的守护进程执行此操作。

虽然将该文件夹配置为您的当前用户可能很有用,但也存在一些挑战。首先,守护进程不一定知道 uid/gid,它不是其余 API 的一部分。此外,守护程序不一定在您的本地主机上运行,​​它可能是对远程主机的 API 调用。而且你主机上的用户不一定和容器里的用户匹配。

理想的解决方案是提前创建具有所需权限和所有权的目录。或者你可以切换到命名卷,它有一个方便的功能,docker 将复制该位置的图像内容以初始化卷,包括所有权和权限(当卷为空并且正在创建容器时会发生这种情况,所以当您有新图像时,它不会收到更新)。最后一个选择是以 root 身份启动容器,但使用入口点脚本修复权限,然后使用 gosu 之类的命令更改为非 root 用户来运行应用程序。

【讨论】:

    猜你喜欢
    • 2021-12-03
    • 2019-08-19
    • 2015-07-15
    • 2020-12-10
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多