是的,从几个角度来看,这是完全不同的。就像您在问题标题中所写的那样,它是关于理解为什么我们需要数据卷而不是将绑定绑定到主机。
第1部分-带有示例的基本方案
让我们采取两种情况。
情况1:Web服务器
我们想为我们的Web服务器提供一个可能经常更改的配置文件。
例如:根据当前环境公开端口。
我们可以每次使用相关的设置来重建映像,或者为每个环境创建2个不同的映像。这两种解决方案都不是很有效。
通过Bind挂载, 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外部的应用程序/进程也可以对其进行修改。
卷也可以在主机上实现,但是Docker将为我们管理它们,并且无法在Docker之外访问它们。
卷是一个更广泛的解决方案
尽管这两种解决方案都可以帮助我们将数据生命周期与容器分开,但是通过使用卷,您可以在系统上获得更多的功能和灵活性。
借助Volumes,我们可以通过将数据存储在专用的远程位置(例如,在云中)并将其与诸如备份,监视,加密和硬件管理之类的外部服务集成,来有效地设计数据并将其与系统的其他部分分离。