是的,这从几个角度来看是完全不同的。就像您在问题标题中所写的那样,它是关于理解为什么我们需要数据卷而不是绑定挂载到主机。
第 1 部分 - 带有示例的基本场景
让我们假设 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:
请注意,在这种情况下,对于命名卷,源是卷的名称
(对于匿名卷,此字段被省略)。
第 2 部分 - 比较
主机上管理和隔离的区别
绑定挂载存在于主机文件系统中,并由主机维护者管理。
Docker 之外的应用程序/进程也可以修改它。
Volumes也可以在宿主机上实现,但是Docker会替我们管理,不能在Docker外访问。
卷是一种更广泛的解决方案
虽然这两种解决方案都帮助我们将数据生命周期与容器分开,
通过使用Volumes,您可以获得比您的系统更多的功能和灵活性。
通过Volumes,我们可以有效地设计我们的数据并将其与系统的其他部分分离,方法是将其存储在专用的远程位置(例如,在云中),并将其与备份等外部服务集成,监控、加密和硬件管理。