在Linux主机上重叠绑定(bind)安装似乎在root
拥有的主机上创建了虚文件。这是故意的吗?这是一个例子:
# Create a file to mount in the container
touch hostfile
# Create a temporary directory to mount in the container
mkdir tempdir
# Run bash in the container and mount the file and directory
docker run --rm --volume=`pwd`/tempdir:/home --volume=`pwd`/hostfile:/home/hostfile ubuntu bash
运行命令后,可以在
hostfile
中找到tempdir
,但它是root
拥有的。注意
hostfile
由启动容器的用户docker run
调用中指定主机上用户的用户名和用户组id不会更改任何内容。 最佳答案
此行为是预期的。让我们尝试了解会发生什么并手动执行相同的安装。
我们在某个位置创建hostfile
,“主机”目录和目标“容器”目录(例如,在我的计算机上为/home/qazer/dockx
):
# the host file
$ touch hostfile
# the "host"-side dir
$ mkdir hostdir
# the "container"-side dir
$ mkdir contdir
然后我们执行挂载:
# the first mount: "host" dir to "container" dir
$ sudo mount --bind hostdir contdir
# success!
# the second mount: host file to the container file
$ sudo mount --bind hostfile contdir/hostfile
mount: contdir/hostfile: mount point does not exist.
是的,绑定(bind)安装失败,因为目标文件不存在!查阅手册页中的
mount(2)
系统调用,发现如果提供的某些路径指向不存在的文件,则此调用将失败:ENOENT A pathname was empty or had a nonexistent component.
因此,Docker实际执行以下操作:
$ sudo strace -f -p $(pidof containerd) \
-e trace=%file,mount -yy |& grep -e hostfile -e home
...
[pid 23945] newfstatat(AT_FDCWD, "/var/lib/docker/overlay2/b2c32423952d49f21e7a9c1addec6201c7f036c8dba1da975bac6a34d5abbe11/merged/home/hostfile", 0xc00016ce08, 0) = -1 ENOENT (No such file or directory)
...
[pid 23945] openat(AT_FDCWD, "/var/lib/docker/overlay2/b2c32423952d49f21e7a9c1addec6201c7f036c8dba1da975bac6a34d5abbe11/merged/home/hostfile", O_RDONLY|O_CREAT|O_CLOEXEC, 0755) = 7</var/lib/docker/overlay2/b2c32423952d49f21e7a9c1addec6201c7f036c8dba1da975bac6a34d5abbe11/merged/home/hostfile>
[pid 23945] mount("/home/qazer/dockx/hostfile", "/var/lib/docker/overlay2/b2c32423952d49f21e7a9c1addec6201c7f036c8dba1da975bac6a34d5abbe11/merged/home/hostfile", 0xc00013bb00, MS_BIND|MS_REC, NULL) = 0
首先,在容器文件系统中检查
/home/hostfile
文件是否存在(newfstat()
调用)。该文件不存在(ENOENT
),因此Docker 创建它以避免我们之前看到的错误(openat(O_CREAT)
调用),并且只有在此之后,容器引擎才会将hostfile
实际绑定(bind)安装到容器文件系统( mount()
调用)。在撰写本文时,
/home
目录已经从主机绑定(bind)挂载(第一次挂载),因此此写操作将转到该主机目录。最后,当容器停止时,Docker编写的文件将保留在主机目录中,这就是您所看到的。至于Mac OS主机的文件所有权,我认为原因与this your question相同。