运行以下命令会创建一个文件 foo
在当前目录中。
docker run --rm -v `pwd`:/workspace -w /workspace alpine:3.10.2 touch foo
在我的 Mac(macOS 10.14.6 (18G95),Docker 版本 19.03.2,构建 6a30dfc)上,创建的文件归“我”所有,如输出
ls -l foo
所示.-rw-r--r-- 1 till staff 0 11 Sep 14:08 foo
但是,在工作站(Ubuntu 16.04.1,Docker 版本 19.03.2,内部版本 6a30dfc)上,创建的文件归
root
所有。 .-rw-r--r-- 1 root root 0 Sep 11 13:32 foo
你知道为什么相同的命令会产生不同的结果吗?
最佳答案
我不是 Mac 用户,但我相信我知道会发生什么:你看到的可能是 Docker for Mac 实际上在虚拟机中运行 Docker 的结果。
当你在 Docker 的原生环境 Linux 中运行 Docker 时,一切都按预期运行:容器化进程是运行在主机内核上的普通进程;它有一些 UID 和 GID(在你的情况下 - 0:0
,即 root:root
),当这个过程创建任何文件时,这个文件归这些 UID 和 GID 所有。 Linux 中的 Docker 卷只是绑定(bind)挂载,因此当写入从容器传播到主机系统时,这里没有什么特别的事情发生。
当你在 Mac 上做同样的事情时,事情就更复杂了:Docker 并不直接在 Mac 主机上运行,而是在底层使用 Linux 虚拟机,而后者又运行 Docker。在这种情况下,音量为 不是 只是一个绑定(bind)挂载——使用挂载到 VM 的目录的工作由管理程序管理。
我不熟悉 Docker 在 Mac 中使用的特定虚拟机管理程序,但是,例如,在 VirtualBox 中,当您与 VM 共享某个主机目录时,VM 内的实际挂载点具有特殊的文件系统类型(vboxsf
),并且该文件系统的驱动程序是 VBox 的 guest 添加的一部分,它有助于主机-VM 交互。
从 VM 内写入此目录的结果正是您所观察到的:所有者由 VBox 转换为适当的 UID/GID。
说,我有一个目录/test
在与主机同步的 VM 内:
# mount | grep test
test on /test type vboxsf (rw,nodev,relatime,iocharset=utf8,uid=1000,gid=1000)
我在
root
时向这个目录写了一些东西:# cd /test
# echo abcd > testfile
# ls -ln
...
-rw-r--r-- 1 1000 1000 5 Sep 11 14:57 testfile
如您所见,此文件的所有者不是
root
——翻译成1000:1000
.来自主机的相同文件是:$ ls -ln test
...
-rw-r--r-- 1 1000 1000 5 Sep 11 17:57 testfile
因此,您很可能会观察到相同的行为:当 Linux VM 中的 Docker 对卷执行写入时,Docker 使用的虚拟机管理程序(无论它在您的系统中是什么)执行相同的转换,并且您会看到所有者更改的文件(您的
user:group
而不是 root:root
)。
关于macos - 为什么在 docker bind mount 中创建的文件的 uid 会因主机操作系统而异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57890420/