【问题标题】:Overlapping bind-mounts and permissions in docker on linux在 linux 上的 docker 中重叠绑定挂载和权限
【发布时间】:2018-10-18 16:39:33
【问题描述】:

Linux 主机上的重叠绑定挂载似乎会在 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 所有。

注意

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

【问题讨论】:

    标签: linux docker file-permissions


    【解决方案1】:

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

    我们在某个位置创建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.
    

    是的,绑定挂载失败,因为目标文件不存在!查阅 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 挂载到容器文件系统(mount() 调用)。

    在撰写本文时,/home 目录已从主机绑定挂载(第一次挂载),因此此写入将转到此主机目录。最后,当容器停止时,Docker写入的文件留在了主机目录中,这就是你所看到的。

    关于 Mac OS 主机的文件所有权——我认为原因与this your question 相同。

    【讨论】:

      猜你喜欢
      • 2020-07-15
      • 2020-05-24
      • 2021-05-17
      • 1970-01-01
      • 2021-06-05
      • 1970-01-01
      • 2017-05-09
      • 1970-01-01
      • 2017-06-30
      相关资源
      最近更新 更多