Dockerfile中VOLUME的实际用途是什么?

无效指针

首先,我想说明一下,我已经在研究此主题时进行了尽职调查。这个问题非常紧密相关,但实际上并不能解决我的困惑。

我了解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:由于我需要明确指定-vrun命令之间共享持久状态,所以为什么要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有前一个实例所在的数据。我可以在没有VOLUMEDockerfile的情况下执行此操作。从命令行,我可以将容器内的任何目录转换为主机上绑定目录或Docker中卷的装载。

所以我的问题是:VOLUME无论如何,无论如何必须通过主机上的命令将命名卷显式映射到容器?我丢失了某些东西,或者这只是令人困惑和混淆。

请注意,我在这里的所有断言都是基于我对docker的行为以及从文档中收集到的信息的观察。

黄忠皇

VOLUMEEXPOSE这样的指令有点不合时宜。我们今天知道的命名卷是在三年前的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指令确实要付出一定的代价。

  • 用户可能不知道正在创建的未命名卷,并在删除容器后继续占用其Docker主机上的存储空间。
  • 无法删除在Dockerfile中声明的卷。下游映像无法将数据添加到存在卷的路径。

后者会导致类似的问题。

对于GitLab问题,有人希望使用预先配置的数据扩展GitLab映像以进行测试,但是由于父映像中/ var / opt / gitlabVOLUME,因此无法在下游映像中提交该数据

tl; dr:VOLUME是为Docker 1.9之前的世界设计的。最好只是把它留在外面。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章