首先,我想说明一下,我已经在研究此主题时进行了尽职调查。这个问题非常紧密相关,但实际上并不能解决我的困惑。
我了解VOLUME
在Dockerfile中指定时,这会指示Docker在映射到容器内指定目录的容器期间创建未命名的卷。例如:
# Dockerfile
VOLUME ["/foo"]
这将创建一个卷以包含存储在/foo
容器内部的任何数据。该体积(当通过观看时docker volume ls
)将显示为随机的数字混杂物。
每次执行docker run
此操作时,都不会重复使用该卷。这是造成混乱的关键。对我来说,卷的目标是包含在图像的所有实例(所有容器均从其启动)中持久存在的状态。所以基本上,如果我这样做,而没有显式的卷映射:
#!/usr/bin/env bash
# Run container for the first time
docker run -t foo
# Kill the container and re-run it again. Note that the previous
# volume would now contain data because services running in `foo`
# would have written data to that volume.
docker container stop foo
docker container rm foo
# Run container a second time
docker run -t foo
我希望未命名的卷可以在2个run
命令之间重用。然而,这种情况并非如此。因为我没有通过该-v
选项显式映射卷,所以将为每个创建新的卷run
。
这是重要的部件号2:由于我需要明确指定-v
在run
命令之间共享持久状态,所以为什么要VOLUME
在Dockerfile中指定?没有VOLUME
,我可以这样做(使用前面的示例):
#!/usr/bin/env bash
# Create a volume for state persistence
docker volume create foo_data
# Run container for the first time
docker run -t -v foo_data:/foo foo
# Kill the container and re-run it again. Note that the previous
# volume would now contain data because services running in `foo`
# would have written data to that volume.
docker container stop foo
docker container rm foo
# Run container a second time
docker run -t -v foo_data:/foo foo
现在,确实,第二个容器将安装/foo
有前一个实例所在的数据。我可以在没有VOLUME
Dockerfile的情况下执行此操作。从命令行,我可以将容器内的任何目录转换为主机上绑定目录或Docker中卷的装载。
所以我的问题是:VOLUME
无论如何,无论如何必须通过主机上的命令将命名卷显式映射到容器?我丢失了某些东西,或者这只是令人困惑和混淆。
请注意,我在这里的所有断言都是基于我对docker的行为以及从文档中收集到的信息的观察。
像VOLUME
和EXPOSE
这样的指令有点不合时宜。我们今天知道的命名卷是在三年前的Docker 1.9中引入的。
在Docker 1.9之前的版本中,运行一个其镜像具有一个或多个VOLUME
指令(或使用该--volume
选项)的容器是创建用于数据共享或持久化的卷的唯一方法。实际上,过去的最佳实践是创建仅数据容器,其唯一目的是保存一个或多个卷,然后使用该--volumes-from
选项与应用程序容器共享这些卷。这是一些描述这种过时模式的文章。
另外,请查看moby / moby#17798(docker 1.9.0中已废弃的仅数据容器?),其中讨论了从仅数据容器到命名卷的更改。
今天,我认为该VOLUME
说明是一种高级工具,仅在特殊情况下并经过仔细考虑后才应使用。例如,官方的postgres图片声明VOLUME
为/var/lib/postgresql/data
。通过将数据库数据保留在分层文件系统之外,这可以提高现成的postgres容器的性能。Docker不必遍历容器映像的所有层以查找文件请求/var/lib/postgresql/data
。
但是,该VOLUME
指令确实要付出一定的代价。
后者会导致类似的问题。
对于GitLab问题,有人希望使用预先配置的数据扩展GitLab映像以进行测试,但是由于父映像中/ var / opt / gitlab的VOLUME,因此无法在下游映像中提交该数据。
tl; dr:VOLUME
是为Docker 1.9之前的世界设计的。最好只是把它留在外面。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句