Dockerfile 中 VOLUME 的实际用途是什么? [英] What is the practical purpose of VOLUME in Dockerfile?

查看:51
本文介绍了Dockerfile 中 VOLUME 的实际用途是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

First of all, I want to make it clear I've done due diligence in researching this topic. Very closely related is this SO question, which doesn't really address my confusion.

我了解,当在 Dockerfile 中指定 VOLUME 时,这会指示 Docker 在容器的持续时间内创建一个未命名的卷,该卷映射到其中的指定目录.例如:

I understand that when VOLUME is specified in a Dockerfile, this instructs Docker to create an unnamed volume for the duration of the container which is mapped to the specified directory inside of it. For example:

# Dockerfile
VOLUME ["/foo"]

这将创建一个卷来包含存储在容器内的 /foo 中的任何数据.卷(通过 docker volume ls 查看时)将显示为随机的数字.

This would create a volume to contain any data stored in /foo inside the container. The volume (when viewed via docker volume ls) would show up as a random jumble of numbers.

每次执行 docker run 时,都不会重复使用此卷.这是造成混乱的关键点.对我来说,卷的目标是在图像的所有实例中包含持久的状态(所有容器都从它开始).所以基本上如果我这样做,没有明确的卷映射:

Each time you do docker run, this volume is not reused. This is the key point causing confusion here. To me, the goal of a volume is to contain state persistent across all instances of an image (all containers started from it). So basically if I do this, without explicit volume mappings:

#!/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 创建一个新卷.

I expect the unnamed volume to be reused between the 2 run commands. However, this is not the case. Because I did not explicitly map a volume via the -v option, a new volume is created for each run.

这是重要的第 2 部分:由于我需要明确指定 -v 以在 run 命令之间共享持久状态,我为什么要指定 VOLUME 在我的 Dockerfile 中?如果没有 VOLUME,我可以这样做(使用前面的示例):

Here's important part number 2: Since I'm required to explicitly specify -v to share persistent state between run commands, why would I ever specify VOLUME in my Dockerfile? Without VOLUME, I can do this (using the previous example):

#!/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 中.我可以在我的 Dockerfile 中不使用 VOLUME 来做到这一点.通过命令行,我可以将容器内的任何目录转换为挂载到主机上的绑定目录或 Docker 中的卷.

Now, truly, the second container will have data mounted to /foo that was there from the previous instance. I can do this without VOLUME in my Dockerfile. From the command line, I can turn any directory inside the container into a mount to either a bound directory on the host or a volume in Docker.

所以我的问题是:当您必须通过主机上的命令将命名卷显式映射到容器时,VOLUME 的意义何在?要么我遗漏了一些东西,要么这只是令人困惑和混淆.

So my question is: What is the point of VOLUME when you have to explicitly map named volumes to containers via commands on the host anyway? Either I'm missing something or this is just confusing and obfuscated.

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

Note that all of my assertions here are based on my observations of how docker behaves, as well as what I've gathered from the documentation.

推荐答案

VOLUMEEXPOSE 这样的指令有点不合时宜.我们今天所知道的命名卷是在 Docker 1.9,差不多三年前.

Instructions like VOLUME and EXPOSE are a bit anachronistic. Named volumes as we know them today were introduced in Docker 1.9, almost three years ago.

在 Docker 1.9 之前,运行一个容器,其镜像具有一个或多个 VOLUME 指令(或使用 --volume 选项)是为数据创建卷的唯一方法分享或坚持.事实上,过去的最佳实践是创建仅用于保存一个或多个卷的纯数据容器,然后使用 --volumes-from 与您的应用程序容器共享这些卷选项.这里有一些文章描述了这种过时的模式.

Before Docker 1.9, running a container whose image had one or more VOLUME instructions (or using the --volume option) was the only way to create volumes for data sharing or persistence. In fact, it used to be a best practice to create data-only containers whose sole purpose was to hold one or more volumes, and then share those volumes with your application containers using the --volumes-from option. Here's some articles that describe this outdated pattern.

另外,请查看 moby/moby#17798(仅数据容器已在 docker 1.9.0 中过时?) 讨论了从仅数据容器到命名卷的变化.

Also, check out moby/moby#17798 (Data-only containers obsolete with docker 1.9.0?) where the change from data-only containers to named volumes was discussed.

今天,我认为 VOLUME 指令是一种高级工具,应该只用于特殊情况,并且经过深思熟虑.例如,官方 postgres 镜像声明了一个 VOLUME/var/lib/postgresql/data.这可以通过将数据库数据保留在分层文件系统之外来提高开箱即用的 postgres 容器的性能.Docker 不必在容器映像的所有层中搜索 /var/lib/postgresql/data 处的文件请求.

Today, I consider the VOLUME instruction as an advanced tool that should only be used for specialized cases, and after careful thought. For example, the official postgres image declares a VOLUME at /var/lib/postgresql/data. This can improve the performance of postgres containers out of the box by keeping the database data out of the layered filesystem. Docker doesn't have to search through all the layers of the container image for file requests at /var/lib/postgresql/data.

但是,VOLUME 指令确实是有代价的.

However, the VOLUME instruction does come at a cost.

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

后一个问题会导致类似的问题.

The latter issue results in problems like these.

对于 GitLab 问题,有人想使用预配置数据扩展 GitLab 映像以进行测试,但由于 VOLUME at/var/opt/gitlab 在父镜像中.

For the GitLab question, someone wants to extend the GitLab image with pre-configured data for testing purposes, but it's impossible to commit that data in a downstream image because of the VOLUME at /var/opt/gitlab in the parent image.

tl;dr:VOLUME 是为 Docker 1.9 之前的世界而设计的.最好别管它.

tl;dr: VOLUME was designed for a world before Docker 1.9. Best to just leave it out.

这篇关于Dockerfile 中 VOLUME 的实际用途是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆