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

绑定挂载(bind mounts)在 Docker 的早期就已经出现了。与卷相比,绑定挂载的功能有限。当您使用绑定挂载时,主机上的文件或目录将挂载到容器中。文件或目录由其在主机上的完整或相对路径引用。相反地,当您使用卷时,在主机上 Docker 的存储目录中创建一个新目录,Docker 管理该目录的内容。

该文件或目录不需要已经存在于 Docker 主机上。如果还不存在,则按需创建。绑定挂载的性能非常好,但它们依赖于主机的文件系统,该文件系统具有特定的可用目录结构。如果您正在开发新的 Docker 应用程序,请考虑改用命名卷。不能使用 Docker CLI 命令直接管理绑定挂载。

docker-types-of-mounts-bind

选择 -v 或者 --mount 标记

最初,-v 或 --volume 标记用于独立容器,--mount 标记用于集群服务。但是,从 Docker 17.06 开始,您也可以将 --mount 用于独立容器。通常,--mount 标记表达更加明确和冗长。最大的区别是 -v 语法将所有选项组合在一个字段中,而 --mount 语法将选项分离。下面是每个标记的语法比较。

新用户推荐使用 --mount 语法,有经验的用户可能更熟悉 -v or --volume 语法,但是更鼓励使用 --mount 语法,因为研究表明它更易于使用。

-v 或 --volume: 由三个字段组成,以冒号(:)分隔。字段必须按照正确的顺序排列,且每个字段的含义不够直观明显。

对于绑定挂载(bind mounts), 第一个字段是主机上文件或目录的路径。

第二个字段是容器中文件或目录挂载的路径。

第三个字段是可选的,是一个逗号分隔的选项列表,比如 ro、consistent、 delegated、 cached、 z 和 Z。这些选项会在本文下面讨论。

--mount:由多个键-值对组成,以逗号分隔,每个键-值对由一个 <key>=<value> 元组组成。--mount 语法比 -v 或 --volume 更冗长,但是键的顺序并不重要,标记的值也更容易理解。

挂载的类型(type),可以是 bind、volume 或者 tmpfs。本主题讨论绑定挂载(bind mounts),因此类型(type)始终为绑定挂载(bind)。

挂载的源(source),对于绑定挂载,这是 Docker 守护进程主机上的文件或目录的路径。可以用 source 或者 src 来指定。

目标(destination),将容器中文件或目录挂载的路径作为其值。可以用 destination、dst 或者 target 来指定。

readonly 选项(如果存在),则会将绑定挂载以中。

bind-propagation 选项(如果存在),则更改绑定传播。 可能的值是 rprivate、 private、 rshared、 shared、 rslave 或 slave 之一.

选项(如果存在), 可能的值是 consistent、 delegated 或 cached 之一。 这个设置只适用于 Docker Desktop for Mac,在其他平台上被忽略。

--mount 标记不支持用于修改 selinux 标签的 z 或 Z选项。

下面的示例尽可能同时展示 --mount 和 -v 两种语法,并且先展示 --mount。

-v 和 --mount 行为之间的差异

由于 -v 和 -volume 标记长期以来一直是 Docker 的一部分,它们的行为无法改变。这意味着 -v 和 -mount 之间有一个不同的行为。

如果您使用 -v 或 -volume 来绑定挂载 Docker 主机上还不存在的文件或目录,则 -v 将为您创建它。它总是作为目录创建的。

如果使用 --mount 绑定挂载 Docker 主机上还不存在的文件或目录,Docker 不会自动为您创建它,而是产生一个错误。

启动带有绑定挂载的容器

考虑这样一个情况:您有一个目录 source,当您构建源代码时,工件被保存到另一个目录 source/target/ 中。您希望工件在容器的 /app/ 目录可用,并希望每次在开发主机上构建源代码时,容器能访问新的构建。使用以下命令将 target/ 目录绑定挂载到容器的 /app/。在 source 目录中运行命令。在 Linux 或 macOS 主机上,$(pwd) 子命令扩展到当前工作目录。

下面的 --mount 和 -v 示例会产生相同的结果。除非在运行第一个示例之后删除了 devtest 容器,否则不能同时运行它们。

--mount:

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

-v:

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

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

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

这表明挂载是一个 bind 挂载,它显示了正确的源和目标,也显示了挂载是可读写的,并且传播设置为 rprivate。

停止容器:

$ docker container stop devtest $ docker container rm devtest 挂载到容器上的非空目录

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

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