繁体   English   中英

docker 数据量与挂载的主机目录

[英]docker data volume vs mounted host directory

我们可以在 docker 中拥有一个数据量:

$ docker run -v /path/to/data/in/container --name test_container debian
$ docker inspect test_container
...
Mounts": [
    {
        "Name": "fac362...80535",
        "Source": "/var/lib/docker/volumes/fac362...80535/_data",
        "Destination": "/path/to/data/in/container",
        "Driver": "local",
        "Mode": "",
        "RW": true
    }
]
...

但是,如果数据卷位于/var/lib/docker/volumes/fac362...80535/_data ,它与使用-v /path/to/data/in/container:/home/user/a_good_place_to_have_data挂载的文件夹中的数据有什么不同-v /path/to/data/in/container:/home/user/a_good_place_to_have_data

尽管使用卷和绑定安装感觉相同(唯一的变化是目录的位置),但行为上存在差异。

卷与绑定安装

  • 使用 Bind Mount,将主机上的文件或目录挂载到容器中。 文件或目录由其在主机上的完整或相对路径引用。
  • 使用 Volume,会在主机上的Docker 存储目录中创建一个新目录, Docker 管理该目录的内容。

与绑定安装相比,卷的优势:

  • 与绑定安装相比,卷更容易备份或迁移。
  • 您可以使用 Docker CLI 命令或 Docker API 管理卷。
  • 卷适用于 Linux 和 Windows 容器。
  • 卷可以在多个容器之间更安全地共享。
  • 卷驱动程序允许您在远程主机或云提供商上存储卷、加密卷的内容或添加其他功能。
  • 新卷的内容可以由容器预先填充。

编辑(9.9.2019):
根据@Sebi2020 的评论,绑定挂载更容易备份。 Docker 不提供任何命令来备份卷。 您必须使用带有绑定安装的临时容器来创建备份。

由 Docker 创建和管理。 您可以使用 docker volume create 命令显式创建卷,或者 Docker 可以在容器或服务创建期间创建卷。

创建卷时,它存储在 Docker 主机上的目录中。 当您将卷挂载到容器中时,此目录就是挂载到容器中的目录。 类似于绑定挂载的工作方式,不同之处在于卷由 Docker 管理并且与主机的核心功能隔离。

一个给定的卷可以同时安装到多个容器中。 当没有正在运行的容器正在使用卷时,该卷仍然可供 Docker 使用,并且不会自动删除。 您可以使用 docker volume prune 删除未使用的卷。

挂载卷时,它可能是命名的或匿名的。 匿名卷在首次挂载到容器中时没有明确的名称,因此 Docker 为它们提供了一个随机名称,该名称保证在给定的 Docker 主机中是唯一的。 除了名称之外,命名卷和匿名卷的行为方式相同。

卷还支持使用卷驱动程序,这允许您将数据存储在远程主机或云提供商上,以及其他可能性。

在此处输入图片说明

绑定坐骑

自 Docker 早期就可用。 与卷相比,绑定挂载的功能有限。 使用绑定挂载时,主机上的文件或目录会挂载到容器中。 文件或目录由其在主机上的完整路径引用。 该文件或目录不需要已经存在于 Docker 主机上。 如果它尚不存在,则按需创建。 绑定挂载非常高效,但它们依赖于主机的具有特定目录结构的文件系统。 如果您正在开发新的 Docker 应用程序,请考虑改用命名卷。 您不能使用 Docker CLI 命令直接管理绑定挂载。

在此处输入图片说明

还有tmpfs mounts
tmpfs 挂载

tmpfs 挂载不会持久保存在磁盘上,无论是在 Docker 主机上还是在容器内。 在容器的生命周期内,容器可以使用它来存储非持久状态或敏感信息。 例如,在内部,swarm 服务使用 tmpfs 挂载将机密挂载到服务的容器中。
在此处输入图片说明

参考:
https://docs.docker.com/storage/

这与使用 -v /path/to/data/in/container:/home/user/a_good_place_to_have_data 挂载文件夹中的数据有什么不同吗?

这是因为,如“ 将主机目录挂载为数据卷”中所述

主机目录本质上是依赖于主机的。 出于这个原因,您不能从 Dockerfile 挂载主机目录,因为构建的图像应该是可移植的。 主机目录不会在所有潜在主机上都可用。

如果你有一些持久化数据想要在容器之间共享,或者想要从非持久化容器中使用,最好创建一个命名的数据卷容器,然后从中挂载数据。

您可以结合使用这两种方法:

 docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

在这里,我们启动了一个新容器并从dbdata容器挂载了卷。
然后我们将本地主机目录挂载为/backup
最后,我们传递了一个命令,该命令使用tardbdata卷的内容备份到/backup目录中的一个backup.tar文件中。 当命令完成并且容器停止时,我们将保留dbdata卷的备份。

是的,从几个角度来看,这是完全不同的。 就像你在问题标题中写的那样,它是关于理解为什么我们需要数据卷与绑定安装到主机。

第 1 部分 - 带有示例的基本场景

让我们来看看 2 个场景。

案例 1:Web 服务器
我们希望为我们的 Web 服务器提供一个可能经常更改的配置文件。
例如:根据当前环境暴露端口。
我们可以每次使用相关设置重建映像,或者为每个环境创建 2 个不同的映像。 这两种解决方案都不是很有效。

使用Bind mounts Docker 将给定的源目录挂载到容器内的某个位置。
(联合文件系统内只读层中的原始目录/文件将被简单地覆盖)。

例如 - 将动态端口绑定到 nginx:

version: "3.7"
services:
  web:
    image: nginx:alpine
    volumes:
     - type: bind #<-----Notice the type
       source: ./mysite.template
       target: /etc/nginx/conf.d/mysite.template
    ports:
     - "9090:8080"
    environment:
     - PORT=8080
    command: /bin/sh -c "envsubst < /etc/nginx/conf.d/mysite.template > 
        /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"

(*) 请注意,此示例也可以使用 Volumes 求解。

案例 2:数据库
Docker 容器不存储持久数据——一旦容器停止运行,任何将写入容器联合文件系统中的可写层的数据都将丢失。

但是如果我们有一个数据库在容器上运行,而容器停止了——这意味着所有数据都将丢失怎么办?

来救援。
这些是由 Docker 为我们管理的命名文件系统树。

例如 - 持久化 Postgres SQL 数据:

services:    
  db:
    image: postgres:latest
    volumes:
      - "dbdata:/var/lib/postgresql/data"
    volumes:
     - type: volume #<-----Notice the type
       source: dbdata
       target: /var/lib/postgresql/data
volumes:
  dbdata:

请注意,在这种情况下,对于命名卷,源是卷的名称(对于匿名卷,此字段被省略)。

第 2 部分 - 比较

主机上管理和隔离的差异

绑定挂载存在于主机文件系统上并由主机维护者管理。
Docker 之外的应用程序/进程也可以修改它。

Volumes也可以在宿主机上实现,但是 Docker 会为我们管理它们,并且它们不能在 Docker 之外访问。

卷是一个更广泛的解决方案

尽管这两种解决方案都帮助我们将数据生命周期与容器分开,但通过使用Volumes,您可以获得比系统更多的功能和灵活性。

使用Volumes,我们可以有效地设计我们的数据并将其与系统的其他部分分离,方法是将其存储在专用的远程位置(例如,在云中)并将其与外部服务(如备份、监控、加密和硬件管理)集成。

主机目录和数据卷之间的区别在于,Docker 通过将其放入$DOCKER-DATA-DIR/volumes目录并附加对它的引用(名称或随机生成的 id)来管理后者。 那就是你得到了一点便利。

主机目录和数据卷都是主机上的目录。 两者都依赖于主机。 您不能在Dockerfile引用它们中的任何一个; 每次启动新容器时, VOLUME指令都会创建一个新的无名(具有随机生成的 ID)卷,并且不能引用现有卷。

* $DOCKER-DATA-DIR在这里是/var/lib/docker $DOCKER-DATA-DIR除非你改变了默认值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM