【问题标题】:What Is The Difference Between Binding Mounts And Volumes While Handling Persistent Data In Docker Containers?在 Docker 容器中处理持久数据时绑定挂载和卷有什么区别?
【发布时间】:2021-08-17 23:53:15
【问题描述】:

我想知道为什么我们有两种不同的选择来做同样的事情,两者之间有什么区别。

【问题讨论】:

标签: docker


【解决方案1】:

对于持久性数据,我们基本上有 3 种类型的卷或挂载:

  1. 绑定坐骑

  2. 命名卷

  3. dockerfiles 中的卷

绑定挂载基本上只是从容器内的主机绑定某个目录或文件(docker run -v /hostdir:/containerdir IMAGE_NAME)

命名卷是您使用docker volume create VOLUME_NAME 手动创建的卷。它们是在/var/lib/docker/volumes 中创建的,只能通过它们的名称来引用。假设您创建了一个名为“mysql_data”的卷,您可以像 docker run -v mysql_data:/containerdir IMAGE_NAME 这样引用它。

然后在 dockerfiles 中有卷,它们是由 VOLUME 指令创建的。这些卷也在/var/lib/docker/volumes 下创建,但没有特定名称。他们的“名字”只是某种散列。运行容器时会创建卷,并且可以方便地保存持久数据,无论您是否使用-v 启动容器。开发人员可以说出重要数据在哪里以及哪些数据应该持久化。

我应该使用什么?

您想使用什么主要取决于偏好或您的管理。如果您想将所有内容保留在“码头区”(/var/lib/docker)中,您可以使用卷。如果您想保留自己的目录结构,可以使用绑定。

Docker 建议使用卷而不是使用绑定,因为卷是由 docker 创建和管理的,并且绑定有更多失败的可能性(也由于第 8 层问题)。 p>

如果您使用绑定并希望在另一台主机上传输您的容器/应用程序,您必须重建您的目录结构,因为每个主机上的卷更加统一。

【讨论】:

  • 将容器转移到另一台主机时绑定怎么办?我们如何复制 docker 引擎中的卷?
  • 这些“第 8 层”问题是什么?谁能给个提示?
  • 第 8 层问题是对 OSI 模型的引用,其中第 8 层将是用户。这只是取笑用户问题的另一种形式。就像短语“PEBCAK” - 意思是“椅子和键盘之间存在问题”:)
  • 我有点困惑。如果这个docker run -v /hostdir:/containerdir IMAGE_NAME 绑定挂载。这个命令有什么作用:docker run --mount type=bind,source=/hostdir,target=/containerdir IMAGE_NAME?
  • @MykolaZotko:IMO 是一样的。
【解决方案2】:

Volumes 是持久化 Docker 容器生成和使用的数据的首选机制。 bind mounts 依赖于宿主机的目录结构,volumes 完全由 Docker 管理。 Volumes 通常是比在容器的可写层中持久化数据更好的选择,因为卷不会增加使用它的容器的大小,并且卷的内容存在于给定容器的生命周期之外。 More on

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

由于-v 和--volume 标志长期以来一直是Docker 的一部分,因此它们的行为无法更改。 这意味着 -v 和--mount 之间存在一种不同的行为。

如果您使用-v 或--volume 绑定挂载Docker 主机上尚不存在的文件或目录,-v 将为您创建端点。 它总是被创建为一个目录。

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

Docker for Windows 共享文件夹限制

Docker for Windows 确实使大部分 VM 对 Windows 主机透明,但它仍然是一个虚拟机。例如,当将–v 与 mongo 容器一起使用时,MongoDB 需要文件系统支持的其他内容。还有一个关于卷安装非常慢的问题。 More on

【讨论】:

    【解决方案3】:

    绑定挂载就像卷(命名或未命名)的超集。 绑定挂载是通过将主机系统中的现有文件夹(主机系统是本机 linux 机器或 vm(在 windows 或 mac 中))绑定到容器中的路径来创建的。

    Volume 命令会生成一个新文件夹,在 /var/lib/docker 下的主机系统中创建

    推荐使用卷,因为它们由 docker 引擎(prune、rm 等)管理。

    绑定挂载的一个很好的用例是将开发文件夹链接到容器中的路径。主机文件夹中的任何更改都将反映在容器中。 绑定挂载的另一个用例是保留应用程序日志,这不像数据库那样重要。

    两种情况下的命令语法几乎相同:

    绑定挂载: 请注意,主机路径应以“/”开头。为方便起见,请使用 $(pwd)。

    docker container run -v /host-path:/container-path image-name
    

    未命名的卷: 在主机中创建一个任意名称的文件夹

    docker container run -v /container-path image-name  
    

    命名卷: 不应以“/”开头,因为这是为绑定挂载保留的。 'volume-name' 在这里不是完整路径。该命令将导致在主机中使用路径“/var/lib/docker/volumes/volume-name”创建一个文件夹。

    docker container run -v volume-name/container-path image-name  
    

    命名卷也可以在容器运行之前创建(docker volume create)。但这几乎不需要。

    【讨论】:

    • 最后一个 sn-p 中的 / 不是错字吗,不应该是 : 吗?
    【解决方案4】:

    作为开发人员,我们总是需要在工具或技术提供的选项之间进行比较...对于 Volume & Bind mount,我建议列出您要容器化的应用程序类型...以下是在选择 Volume 而不是 Bind Mount 之前我会考虑的参数 - 1. Docker 在容器外轻松地为 Volumes 提供各种 CLI 命令, 2.备份,恢复卷比绑定容易得多,因为它取决于底层主机操作系统 3. 卷与平台无关,因此它可以在 Linux 以及窗口容器上运行 4. 使用 Bind,您有 2 种技术来处理您的主机目录结构以及 docker, 5. 卷的迁移不仅在本地机器上更容易,在云机器上也是如此 6. Volumes可以在多个容器之间轻松共享

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-22
      • 2020-05-27
      • 1970-01-01
      • 2014-08-08
      • 2017-07-21
      • 2021-12-20
      • 2017-07-05
      • 2019-07-30
      相关资源
      最近更新 更多