linux - 在 Linux 上的 docker 中重叠绑定(bind)挂载和权限

标签 linux docker file-permissions

在 Linux 主机上重叠绑定(bind)安装似乎会在 root 拥有的主机上创建 ghost 文件。这是故意的吗?这是一个例子:

# 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

运行命令后,可以在 tempdir 中找到 hostfile,但归 root 所有。

注意

  • 在 OS X 主机上运行相同的 bash 脚本会导致 hostfile 由启动容器的用户拥有,
  • docker run 调用中指定主机上用户的用户和组 ID 不会改变任何内容。

最佳答案

此行为是预期的行为。让我们尝试了解发生了什么并手动执行相同的安装。

我们在某个位置创建hostfile、“host”目录和目标“container”目录(比如,它是我的/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 中的相同。 .

关于linux - 在 Linux 上的 docker 中重叠绑定(bind)挂载和权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50238503/

相关文章:

linux - Hadoop 集群中 tasktracker 上的 UnknownHostException

java - 从 sshj 启动时,来自控制台的命令不运行

c - 在 Ubuntu 12.04 上设置 ncurses 库

linux - 将脚本加载到/bin,然后删除,但仍然有效

linux - 为Linux中的目录启用写权限

docker - Git 到 docker 导出

php - 重新启动失败的Selenium浏览器

docker - Docker ADD和卷冲突

linux - openssl输出文件权限

Android 根应用程序不工作 : Can't remove file from terminal or Java