我们可以在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
装入文件夹中的数据有什么不同?
答案 0 :(得分:42)
虽然在使用它们时感觉相同,但只有目录位置的变化,才有不同。
卷与绑定坐骑
卷绑定安装的优势:
体积
由Docker创建和管理。您可以显式创建卷 使用docker volume create命令,或者Docker可以创建一个卷 在容器或服务创建期间。
创建卷时,它存储在目录上 Docker主机。将卷装入容器时,这个 目录是装入容器的内容。这类似于 绑定挂载的工作方式,除了卷管理 Docker与主机的核心功能隔离开来 机器。
给定的卷可以同时安装到多个容器中。 当没有正在运行的容器正在使用卷时,该卷仍然是 可用于Docker,不会自动删除。你可以删除 未使用的卷使用docker volume prune。
装入卷时,可能会命名或匿名。匿名 首次装入卷时,不会给出明确的名称 到一个容器,所以Docker给他们一个随机的名字 保证在给定的Docker主机中是唯一的。除了名字, 命名和匿名卷的行为方式相同。
卷也支持使用卷驱动程序,这些允许您使用 将您的数据存储在远程主机或云提供商等等 可能性。
绑定坐骑
自Docker早期开始提供。绑定坐骑有限 与卷相比的功能。使用绑定装载时,文件 或主机上的目录安装到容器中。文件 或目录由主机上的完整路径引用。该 文件或目录不需要已存在于Docker主机上。 如果它尚不存在,则按需创建。绑定是非常的 高性能,但他们依赖于主机的文件系统 特定目录结构可用。如果你正在开发新的 Docker应用程序,请考虑使用命名卷。你不能 使用Docker CLI命令直接管理绑定挂载。
还有tmpfs mounts
tmpfs登录
在Docker主机或磁盘上,tmpfs挂载不会保留在磁盘上 在一个容器内。它可以在生命周期内由容器使用 容器,存储非持久状态或敏感 信息。例如,在内部,swarm服务使用tmpfs挂载 将秘密装入服务的容器中
答案 1 :(得分:35)
与使用-v / path / to / data / in / container:/ home / user / a_good_place_to_have_data挂载的文件夹中的数据有什么不同?
这是因为,如“Mount a host directory as a data volume”
中所述主机目录本质上是依赖于主机的。因此,您无法从Dockerfile安装主机目录,因为构建的映像应该是可移植的。主机目录在所有潜在主机上都不可用。
如果您想要在容器之间共享某些持久性数据,或者想要从非持久性容器中使用,那么最好创建一个命名的数据卷容器,然后从中挂载数据。
您可以将两种方法结合起来:
docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
我们在这里推出了一个新容器,并从
dbdata
容器中安装了卷 然后我们将本地主机目录挂载为/backup
最后,我们传递了一个命令,该命令使用tar
将dbdata
卷的内容备份到backup.tar
目录中的/backup
文件。当命令完成并且容器停止时,我们将留下dbdata
卷的备份。
答案 2 :(得分:5)
是的,从几个角度来看,这是安静的。 就像您在问题标题中所写的一样,这全都在于了解为什么我们需要数据卷而不是将绑定绑定到主机。
让我们采取两种情况。
案例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:
请注意,在这种情况下,对于命名卷,源是卷的名称 (对于匿名卷,将省略此字段)。
主机上管理和隔离方面的差异
绑定安装存在于主机文件系统上,并由主机维护者管理。
Docker外部的应用程序/进程也可以对其进行修改。
卷也可以在主机上实现,但是Docker将为我们管理它们,并且无法在Docker之外访问它们。
音量是更广泛的解决方案
尽管这两种解决方案都可以帮助我们将数据生命周期与容器分开, 通过使用 Volumes ,您可以在系统上获得更多的功能和灵活性。
使用 Volumes ,我们可以有效地设计数据并将其与系统的其他部分分离,方法是将其存储在专用的远程位置(例如Cloud)并将其与外部服务(如备份,监控,加密)集成和硬件管理。
答案 3 :(得分:3)
主机目录和数据卷之间的区别在于Docker通过将其放入$DOCKER-DATA-DIR/volumes
目录并附加对它的引用(名称或随机生成的ID)来管理后者。那就是你有点方便。
主机目录和数据卷都是主机上的目录。两者都依赖于主机。您无法在Dockerfile
中引用其中任何一个;每次启动新容器时,VOLUME
指令都会创建一个新的无名(具有随机生成的id)卷,并且无法引用现有卷。
* $DOCKER-DATA-DIR
此处为/var/lib/docker
。