热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《Dockerfile中VOLUME的实际用途是什么?》经验,为你挑选了1个好方法。

首先,我想明确表示我已经在研究这个主题方面做了尽职调查.非常密切相关的是这个问题,这并没有真正解决我的困惑.

我知道,当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

我希望在两个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这是前一个实例的数据.我可以VOLUME在我的Dockerfile中执行此操作.从命令行,我可以将容器内的任何目录转换为主机上的绑定目录或Docker中的卷.

所以我的问题是:VOLUME当你必须通过主机上的命令显式地将命名卷映射到容器时,有什么意义呢?我要么缺少某些东西,要么就是混乱和混淆.

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



1> King Chung H..:

VOLUMEEXPOSE这样的指令有些不合时宜。我们今天所知道的命名卷是在大约三年前的Docker 1.9中引入的。

在Docker 1.9之前的版本中,运行一个其映像具有一个或多个VOLUME指令(或使用该--volume选项)的容器是创建用于数据共享或持久化的卷的唯一方法。实际上,过去的最佳实践是创建仅数据容器,其唯一目的是保存一个或多个卷,然后使用该--volumes-from选项与应用程序容器共享这些卷。这是一些描述这种过时模式的文章。

Docker数据容器

为什么Docker数据容器(卷!)很好

另外,请查看moby / moby#17798(docker 1.9.0上已淘汰的仅数据容器?),其中讨论了从仅数据容器到命名卷的更改。

今天,我认为该VOLUME说明是一种高级工具,仅在经过特殊考虑后,才应用于特殊情况。例如,官方的postgres图片声明VOLUME/var/lib/postgresql/data。通过将数据库数据保留在分层文件系统之外,这可以提高现成的postgres容器的性能。Docker不必遍历容器映像的所有层以查找文件请求/var/lib/postgresql/data

但是,该VOLUME指令确实要付出一定的代价。

用户可能不知道正在创建的未命名卷,并在删除容器后继续占用其Docker主机上的存储空间。

无法删除在Dockerfile中声明的卷。下游映像无法将数据添加到存在卷的路径。

后者会导致类似的问题。

如何在Docker镜像中“取消声明”卷?

Docker上的GitLab:如何在部署之间持久保存用户数据?

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

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


我建议避免使用“ VOLUME”,但是“ EXPOSE”指令对于文档很有用。与“ VOLUME”不同,“ EXPOSE”指令没有任何有害的副作用。
推荐阅读
author-avatar
萧俊瑄俊明纬伦
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有