docker compose 卷类型 - 绑定与卷

Posted

技术标签:

【中文标题】docker compose 卷类型 - 绑定与卷【英文标题】:docker compose volume type - bind vs volume 【发布时间】:2019-08-17 09:09:36 【问题描述】:

TLDR

docker-compose中,有什么区别

volumes:
    - type: volume
      source: mydata
      target: /data

volumes:
    - type: bind
      source: mydata
      target: /data

?

问题很长:

当您在docker-compose 文件中指定volumes 选项时,您可以使用long-syntax style

根据文档,type 选项接受 3 个不同的值:volumebindtmpfs

我了解tmpfs 选项 - it means that the volume will not be saved after the container is down.。

但我在文档中找不到任何关于其他 2 个选项之间区别的参考:bindvolume,有人能告诉我吗?

【问题讨论】:

【参考方案1】:

当绑定挂载是来自主机的文件时,卷更像是 docker 的 nas。

绑定挂载是从主机(运行 docker 守护程序的主机)挂载到容器上的文件。 卷就像完全由 docker 管理的存储空间。 您会在文献中找到两种类型的卷: 命名卷(您提供它的名称) 匿名卷(来自 docker 的常用 UUID 名称,就像您可以在容器或未标记的图像上找到它们一样)

这些卷带有自己的一组docker commands;您也可以通过

查看此列表
docker volume --help

您可以通过

查看您现有的卷
docker volume ls

您可以通过以下方式创建命名卷

docker volume create my_named_volume

但您也可以通过docker-compose 文件创建卷

version: "3.3"

services:
  mysql:
    image: mysql
    volumes:
      - type: volume
          source: db-data
          target: /var/lib/mysql/data

volumes:
  db-data:

这是说 请 docker,将名为 db-data 的卷挂载到容器目录 /var/lib/mysql/data 上的部分p>

- type: volume
    source: db-data
    target: /var/lib/mysql/data

这是对 docker 说的部分请为我创建一个名为 db-data

的卷
volumes:
  db-data:

关于三种挂载类型的 Docker 文档:

https://docs.docker.com/storage/bind-mounts/ https://docs.docker.com/storage/volumes/ https://docs.docker.com/storage/tmpfs/

【讨论】:

谢谢,它现在正在清除。你能告诉我,当我在卷中使用短语法样式(路径:路径)时,类型默认为哪个选项? 无。或者实际上,两者兼而有之。 Docker 在这方面变得越来越聪明。如果它得到一个/pat/to/file,它将是一个绑定。如果它也得到一个./relative/path/to/file,如果它只是一个name,那么docker明白它是一个卷【参考方案2】:

如果我对您的理解正确,您是在问:卷和绑定挂载有什么区别?

主机上管理和隔离的区别

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

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

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

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

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

与绑定挂载相比,Volumes 的更多优势:

    没有主机问题。 可以使用 Docker CLI 进行管理。 卷可以为您节省一些与 uid/gid 问题相关的权限,这些权限在容器用户的 uid 与主机 gid 不匹配等情况下发生。 新卷的内容可以由容器预先填充。

示例

让我们假设 2 个场景。

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

使用绑定挂载 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:

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

【讨论】:

我认为这个答案比接受的答案解释得更好,谢谢 " 一旦容器停止运行,任何将写入容器联合文件系统中可写层的数据都将丢失。" --> 容器被删除后。没有停止。来源:docs.docker.com/storage/storagedriver 非常明确的回答。

以上是关于docker compose 卷类型 - 绑定与卷的主要内容,如果未能解决你的问题,请参考以下文章

docker数据存储方式(bind--mount)

docker-tmpfs挂载

LVM逻辑卷管理--在线扩容逻辑卷与卷组容量缩减逻辑卷快照

Docker/Docker-Compose 中的 NFS 卷

升级镜像时 Docker-compose 卷重置

使用docker compose部署服务