Docker 基础知识 - 使用绑定挂载(bind mounts)管理应用程序数据 (2)

如果您将其绑定挂载到容器上的一个非空目录中,则该目录的现有内容会被绑定挂载覆盖。这可能是有益的,例如当您想测试应用程序的新版本而不构建新镜像时。然而,它也可能是令人惊讶的,这种行为不同于 docker volumes。

这个例子被设计成极端的,仅仅使用主机上的 /tmp/ 目录替换容器的 /usr/ 目录的内容。在大多数情况下,这将导致容器无法正常工作。

--mount 和 -v 示例有相同的结果。

--mount:

$ docker run -d \ -it \ --name broken-container \ --mount type=bind,source=http://www.likecs.com/tmp,target=http://www.likecs.com/usr \ nginx:latest docker: Error response from daemon: oci runtime error: container_linux.go:262: starting container process caused "exec: \"nginx\": executable file not found in $PATH".

-v:

$ docker run -d \ -it \ --name broken-container \ -v /tmp:/usr \ nginx:latest docker: Error response from daemon: oci runtime error: container_linux.go:262: starting container process caused "exec: \"nginx\": executable file not found in $PATH".

容器被创建,但没有启动。删除它:

$ docker container rm broken-container 使用只读绑定挂载

对于一些开发应用程序,容器需要写入绑定挂载,因此更改将传播回 Docker 主机。在其他时候,容器只需要读访问。

这个示例修改了上面的示例,但是通过在容器内的挂载点之后的选项列表(默认为空)中添加 ro,将目录挂载为只读绑定挂载。当有多个选项时,使用逗号分隔它们。

--mount 和 -v 示例有相同的结果。

--mount:

$ docker run -d \ -it \ --name devtest \ --mount type=bind,source="$(pwd)"/target,target=http://www.likecs.com/app,readonly \ nginx:latest

-v:

$ docker run -d \ -it \ --name devtest \ -v "$(pwd)"/target:/app:ro \ nginx:latest

使用 docker inspect devtest 验证绑定挂载是否被正确创建。查看 Mounts 部分:

"Mounts": [ { "Type": "bind", "Source": "/tmp/source/target", "Destination": "/app", "Mode": "ro", "RW": false, "Propagation": "rprivate" } ],

停止容器:

$ docker container stop devtest $ docker container rm devtest 配置绑定传播

对于绑定挂载和卷,绑定传播默认都是 rprivate 。只能为绑定挂载配置,而且只能在 Linux 主机上配置。绑定传播是一个高级主题,许多用户从不需要配置它。

绑定传播是指在给定绑定挂载或命名卷中创建的挂载是否可以传播到该挂载的副本。考虑一个挂载点 /mnt,它也挂载在 /tmp 上。传播设置控制 /tmp/a 上的挂载是否也可以在 /mnt/a 上使用。每个传播设置都有一个递归对应点。在递归的情况下,考虑一下 /tmp/a 也被挂载为 /foo。传播设置控制 /mnt/a 和/或 /tmp/a 是否存在。

传播设置 描述
shared   原始挂载的子挂载公开给副本挂载,副本挂载的子挂载也传播给原始挂载。  
slave   类似于共享(shared)挂载,但仅在一个方向上。如果原始挂载公开子挂载,副本挂载可以看到它。但是,如果副本挂载公开子挂载,则原始挂载无法看到它。  
private   该挂载是私有的。原始挂载的子挂载不公开给副本挂载,副本挂载的子挂载也不公开给原始挂载。  
rshared   与 shared 相同,但传播也扩展到嵌套在任何原始或副本挂载点中的挂载点。  
rslave   与 slave 相同,但传播也扩展到嵌套在任何原始或副本挂载点中的挂载点。  
rprivate   默认值。与 private 相同,这意味着原始或副本挂载点中的任何位置的挂载点都不会在任何方向传播。  

当你在挂载点上设置绑定传播之前,主机文件系统需要已经支持绑定传播。

有关绑定传播的更多信息,请参见 Linux 内核共享子树文档。

下面的示例两次将 target/ 目录挂载到容器中,第二次挂载设置了 ro 选项和 rslave 绑定传播选项。

--mount 和 -v 示例有相同的结果。

--mount:

$ docker run -d \ -it \ --name devtest \ --mount type=bind,source="$(pwd)"/target,target=http://www.likecs.com/app \ --mount type=bind,source="$(pwd)"/target,target=http://www.likecs.com/app2,readonly,bind-propagation=rslave \ nginx:latest

-v:

$ docker run -d \ -it \ --name devtest \ -v "$(pwd)"/target:/app \ -v "$(pwd)"/target:/app2:ro,rslave \ nginx:latest

现在,如果您创建 /app/foo/, /app2/foo/ 也存在。

配置 selinux 标签

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpsypj.html