"a bind mount won't copy the container contents to the host automatically, unlike a named volume"



需要澄清此处的注释:

绑定装载的唯一"问题"是它不会复制与命名卷不同,容器内容会自动转移到主机。docs.docker.com/compose/compose file/#volumes

这准确吗?如果是,则:

  1. 如何获得容器的";新数据";当使用bind mount(在容器重新启动的情况下保持数据)时,(例如,一个正在增长的数据库)插入主机
  2. 在出现named volumes之前,Docker是如何在容器重新启动时保持数据的

绑定装载的唯一"问题"是它不会复制与命名卷不同,容器内容会自动转移到主机。

这准确吗?

接近准确,但我能看到混乱。主机卷,也就是绑定装载,没有docker的初始化功能。对于匿名卷和命名卷,docker将使用该路径上的映像内容初始化卷。此初始化包括所有权和权限,这有助于避免权限错误。此初始化仅在创建容器并且卷是新的或空的时运行,因此后续容器不会拾取在较新映像版本中对映像所做的更改。

如果是,则:

  1. 如何获得容器的";新数据";(例如,不断增长的数据库)在使用绑定装载(以持久化数据)时插入主机在容器重新启动的情况下)

从容器中的应用程序读取和写入将按预期继续到绑定装载中使用的主机文件系统。这只是初始化步骤没有运行。

  1. 在出现命名卷之前,Docker是如何在容器重新启动时保持数据的

有数据容器,从其他容器装载卷,但这是不灵活的(所有卷路径都固定到数据容器中的路径),并且将持久数据与临时容器混合管理,因此已逐步淘汰。

卷用于处理容器之间的数据持久性。单个容器重新启动(而不是被替换)仍将具有所有特定于容器的文件系统更改。docker rm命令删除这些文件系统更改,以及容器日志和容器的元数据/配置。

特定于容器的更改是docker使用的覆盖文件系统的读/写顶层。卷装载都是到这个覆盖文件系统的子目录中的单独装载(就像/home/var通常是Linux主机的/文件系统中的单独文件系统装载一样,对这些其他路径的所有读取和写入都会进入一个单独的底层文件系统)。

如果要将卷装载到容器中,并且希望该卷可靠地包含映像中的一些内容,则需要在容器启动时手动将其复制到容器中。一种方法是使用入口点包装器脚本:

#!/bin/sh
# Copy data into a possibly-mounted location
cp -a /app/static /var/www
# Then run the image's CMD
exec "$@"

你会把它包括在你的图像的Dockerfile 中

# Must use JSON-array syntax
ENTRYPOINT ["/app/entrypoint.sh"]
CMD same as it was before

这里有两个关于Docker命名卷的初始化行为的重要细节需要注意。首先,您注意到,Docker只将内容复制到Docker命名的卷中;绑定挂载不会发生这种情况,在Kubernetes等其他环境中也不会发生。

第二个更微妙的细节是,初始化只在容器第一次运行时发生。如果装载到容器中的卷中已经有内容,它将隐藏已经存在的内容。在其他SO问题中,你可以看到这个清单,例如,";我在Nodepackage.json文件中添加了一个包,但当我将node_modules目录放在卷中时,它会忽略更新";或";我正在使用一个卷将内容导出到nginx代理,但它不会更新;。

我认为@BMitch给出了被接受的答案是正确的,但我只会尝试添加一些细节,希望有用。

这准确吗?如果是,则:

鉴于我的索赔正在接受审查,我完全听从@BMitch的意见:)!然而,我还要补充一点:

  • https://github.com/docker/compose/issues/4581#issuecomment-38955990
    • 提供命名卷/主机卷行为的外行解释
    • 我的解释需要更新以反映"初始化"的概念
  • https://stackoverflow.com/a/40030535/3080207
    • 这是我建议目前在docker compose中设置卷的方式,由@kaiser提供

如何获得容器的";新数据";(例如,一个正在增长的数据库)在使用绑定装载(在容器重新启动的情况下保持数据)时插入主机?

主机卷命名卷都可以实现这一点。

我认为争论的焦点是你想在上发生什么

  • 容器的首次运行
  • 容器的后续运行
  • 卷在主机系统上的位置/可访问性

一旦卷连接到容器(无论是命名卷还是绑定装载),存储到该卷的任何内容都应该在重新启动之间保持不变,这实际上是免费的。这假设了相同的docker compose-config,并且没有手动删除卷。

以前,使用命名卷有点限制,因为您无法像使用bind-mount那样轻松地跟踪日志,也无法直接从主机编辑代码,但现在问题似乎已经解决/可以解决了。

绑定装载能够在重新启动之间保持数据。我个人发现绑定卷在99%的时间里都能完成我想要的任务,也就是说,命名卷现在可以"完成所有任务",我会继续使用这些卷。

不过,它们之间存在差异,我相信它们偶尔还是会咬人,需要它们联系真正的专家,而不是像我这样的用户:)。

相关内容

最新更新