Dockerfile中的VOLUME有什么作用 [英] what does VOLUME inside Dockerfile do

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

问题描述

我试图理解以下DockerFile:

I am trying to understand the below DockerFile:

https://github.com/nfnty/dockerfiles/blob/master/images/arch-bootstrap/latest/Dockerfile

FROM nfnty/arch-mini:latest
.....
RUN     install --directory --owner=root --group=root --mode=700 /var/lib/bootstrap/{,archive}

USER root
VOLUME ["/var/lib/bootstrap"]
ENTRYPOINT ["/opt/bootstrap/build.sh"]

RUN正在创建目录/ var / lib / bootstrap / archive,在构建后,映像将永久具有该文件夹

RUN is creating directory /var/lib/bootstrap/archive and after build the image will be having this folder permanenantly

从中创建容器时,它将具有文件夹 / var / lib / bootstrap /存档,因为它存在于映像中。

When the container is created from it, it will have the folder "/var/lib/bootstrap/archive" because its existing in the image.

声明VOLUME / var / lib / bootstrap /

What is the point of declaring VOLUME /var/lib/bootstrap/

我可以在命令行-v [主机路径]中理解:[conta

I can understand in command line -v [host path]:[container:path] will mount the host folder on the containers folder.

但是dockerfile中的Volumne是什么,尤其是在上述情况下。

but what is Volumne in dockerfile especially in the above case do.

好吧,我正在显示一些我已完成的测试:

Ok I am showing some test i have done:

-- trying to create a container with dockerfile above
i.e VOLUME ["/var/lib/bootstrap"]

hostsystem#  docker run -it --entrypoint=/bin/bash nfnty/arch-bootstrap
[root@684120b46cfb /]# ls -al /var/lib/bootstrap/
total 12
drwx------ 3 root root 4096 Oct 18 05:53 .
drwxr-xr-x 1 root root 4096 Aug 23 12:48 ..
drwx------ 2 root root 4096 Aug 23 12:48 archive

-- I have created a sample001.txt file inside it.
[root@684120b46cfb /]# touch /var/lib/bootstrap/sample001.txt
[root@684120b46cfb /]# ls -al /var/lib/bootstrap/
total 12
drwx------ 3 root root 4096 Oct 18 05:54 .
drwxr-xr-x 1 root root 4096 Aug 23 12:48 ..
drwx------ 2 root root 4096 Aug 23 12:48 archive
-rw-r--r-- 1 root root    0 Oct 18 05:54 sample001.txt
[root@684120b46cfb /]# 

[root@684120b46cfb /]# exit

-- As per [@izazkhan answer][1] the VOLUME ["/var/lib/bootstrap"]
instruction is persisting the data by creating a volume in 
/var/lib/docker on the host and mount it on /var/lib/bootstrap 
in the container. So expect the sample001.txt lies there at 
/var/lib/docker/(var/lib/bootstrap)

-- Now again trying to create a container
hostsystem#  docker run -it --entrypoint=/bin/bash nfnty/arch-bootstrap
[root@5fa7c4fc72e2 /]# ls -al /var/lib/bootstrap/
total 12
drwx------ 3 root root 4096 Oct 18 06:00 .
drwxr-xr-x 1 root root 4096 Aug 23 12:48 ..
drwx------ 2 root root 4096 Aug 23 12:48 archive
[root@5fa7c4fc72e2 /]# 

-- i dont see my sample001.txt file here.

And i check the dockers:

#  docker container ls -a
CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                      PORTS               NAMES
ff2d37e5399a        nfnty/arch-bootstrap   "/bin/bash"         16 seconds ago      Exited (0) 3 seconds ago                        stupefied_sinoussi
bfbff0778fe9        nfnty/arch-bootstrap   "/bin/bash"         7 minutes ago       Exited (0) 30 seconds ago                       objective_noether


And i check the volumes:

#  docker volume ls
DRIVER              VOLUME NAME
local               47ae26f1b4b17cd2792972b50dcae9da9af1d3f06ccd984cfbf5a75be7365bbd
local               fd5a1caf07024f7103a3a225f4de00a2c1efb79a74fa939737f11c939837b32a

What i found is there are two volumes since i have created two containers.

-- Also checking the volume folders:

# cd /var/lib/docker/volumes

#  find . -exec ls -dl \{\} \; | awk '{print $3, $4, $9}'
root root .
root root ./47ae26f1b4b17cd2792972b50dcae9da9af1d3f06ccd984cfbf5a75be7365bbd
root root ./47ae26f1b4b17cd2792972b50dcae9da9af1d3f06ccd984cfbf5a75be7365bbd/_data
root root ./47ae26f1b4b17cd2792972b50dcae9da9af1d3f06ccd984cfbf5a75be7365bbd/_data/archive
root root ./fd5a1caf07024f7103a3a225f4de00a2c1efb79a74fa939737f11c939837b32a
root root ./fd5a1caf07024f7103a3a225f4de00a2c1efb79a74fa939737f11c939837b32a/_data
root root ./fd5a1caf07024f7103a3a225f4de00a2c1efb79a74fa939737f11c939837b32a/_data/archive
root root ./fd5a1caf07024f7103a3a225f4de00a2c1efb79a74fa939737f11c939837b32a/_data/sample001.txt
root root ./metadata.db

我期望在任何容器中都可以看到sample001.txt。即所有容器都使用相同的卷文件夹。但是即使安装点是由dockerfile中的VOLUME定义的,它们似乎仍在/ var / lib / docker / volumes中创建了不同的文件夹。

I was expecting sample001.txt to be see in any container. i.e All containers are using the same volume folder. but it looks like they are having different folders created at /var/lib/docker/volumes eventhought the mount point is as defined by the VOLUME in dockerfile.

我感到困惑的是,无论我们创建了多少容器,dockerfile中的VOLUME都指向主机上/ var / lib / docker / volumes上的单个文件夹。但这不是事实,因为它们在每个容器的/ var / lib / docker / volumes中具有不同的主机文件夹。

I was confused that VOLUME in dockerfile is refering to one single folder on the host machine at /var/lib/docker/volumes irrespective of how many contianers we create. But its not true since they have different host folders at /var/lib/docker/volumes for each container.

然后,VOLUMES的用途是什么。我感觉到的一种帮助是,如果我在容器中创建了一些文件并将它们存储在VOLUME位置,并且我想从主机访问它们,那么我可以去检查卷文件夹。

Then what is the purpose of VOLUMES. One help i feel is if i create some files in the container and store them at the VOLUME place and i want to access them from host then i can go and check the volume folders.

但是卷文件夹的名称并不容易弄清楚它们属于哪个容器。

But the names of volume folders are not easy to figure out which container they belong to.

对不起,我对docker中的卷是全新的,我是-v [主机]:[容器],但是第一次遇到dockerfile中的VOLUME。因此,我完全感到困惑,无法弄清发生了什么。

Sorry i am completely new to volumes in docker, i new -v [host]:[container], but first time came across VOLUME in dockerfile. So i was completely confused and unable to figure out whats happening.

在阅读 https://docs.docker.com/storage/volumes/ 我找到了为什么音量的答案

After reading https://docs.docker.com/storage/volumes/ i found the answer for why VOLUME


此外,与将数据持久保存在
a容器的可写层中相比,卷通常是更好的选择,因为卷不会增加使用它的容器的
大小,并且卷的内容存在
在给定容器的生命周期之外。

In addition, volumes are often a better choice than persisting data in a container’s writable layer, because a volume does not increase the size of the containers using it, and the volume’s contents exist outside the lifecycle of a given container.

此外,下面的链接有助于了解如何拥有共同的体积并在其中使用它不同的容器(与我的问题不同)

Also the below link helps to know how to have a common volume and use it in different container (not the same as my question)

https://linuxhint.com/storing-sharing-docker-volumes/

推荐答案

Docker卷:

卷d将存储在其中的数据的寿命与创建它们的容器的寿命相结合。这样一来,您就可以 docker rm my_container ,并且不会删除您的数据。

Volumes decouple the life of the data being stored in them from the life of the container that created them. This makes it so you can docker rm my_container and your data will not be removed.

可以创建卷有两种方式:

A volume can be created in two ways:

在Dockerfile中指定 VOLUME / some / dir

Specifying VOLUME /some/dir in a Dockerfile

将其作为运行命令的一部分指定为 docker run -v / some / dir

Specying it as part of your run command as docker run -v /some/dir

无论哪种方式,这两件事都是完全一样的。它告诉Docker在主机上的Docker根路径(默认为 / var / lib / docker )内创建一个目录,并将其安装到您指定的路径中(上面的 / some / dir )。当您使用该卷删除容器时,卷本身将继续存在。

Either way, these two things do exactly the same thing. It tells Docker to create a directory on the host, within the docker root path (by default /var/lib/docker), and mount it to the path you've specified (/some/dir above). When you remove the container using this volume, the volume itself continues to live on.

如果指定的路径在容器中不存在,则将自动创建目录。

If the path specified does not exist within the container, a directory will be automatically created.

您可以告诉docker连同容器一起删除卷:

You can tell docker to remove a volume along with the container:

docker rm -v my_container

有时候您已经在主机上找到了想要的目录可以在容器中使用,因此CLI可以使用一个额外的选项来指定:

Sometimes you've already got a directory on your host that you want to use in the container, so the CLI has an extra option for specifying this:

docker run -v /host/path:/some/path ...

这告诉docker具体使用指定的主机路径,而不是创建将其自身放置在docker根目录下,并将其安装到容器内的指定路径(上述 / some / path )。

This tells docker to use the specified host path specifically, instead of creating one itself within the docker root, and mount that to the specified path within the container (/some/path above).

请注意,这也可以是文件而不是目录。在Docker术语中,这通常称为绑定安装(尽管从技术上讲,从实际发生的意义上讲,所有卷都是绑定安装)。如果主机上的路径不存在,则会在给定路径下自动创建目录。

Note, that this can also be a file instead of a directory. This is commonly referred to as a bind-mount within docker terminology (though technically speaking, all volumes are bind-mounts in the sense of what is actually happening). If the path on the host does not exist, a directory will be automatically be created at the given path.

从Docker文档中:

VOLUME ["/data"]

VOLUME 指令创建具有指定名称的安装点,并将其标记为保存来自本地主机或其他容器的外部安装的卷。该值可以是JSON数组, VOLUME [ / var / log /] 或具有多个参数的纯字符串,例如 VOLUME / var / log VOLUME / var / log / var / db 。有关通过Docker客户端的更多信息/示例和安装说明,请参阅通过卷共享目录。

The VOLUME instruction creates a mount point with the specified name and marks it as holding externally mounted volumes from native host or other containers. The value can be a JSON array, VOLUME ["/var/log/"], or a plain string with multiple arguments, such as VOLUME /var/log or VOLUME /var/log /var/db. For more information/examples and mounting instructions via the Docker client, refer to Share Directories via Volumes documentation.

docker run命令使用存在的任何数据初始化新创建的卷。在基本映像内的指定位置。例如,考虑以下Dockerfile片段:

The docker run command initializes the newly created volume with any data that exists at the specified location within the base image. For example, consider the following Dockerfile snippet:

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

此Dockerfile生成导致docker运行的映像在 / myvol 中创建一个新的挂载点,并将问候文件复制到新创建的卷中。

This Dockerfile results in an image that causes docker run to create a new mount point at /myvol and copy the greeting file into the newly created volume.

答案:

因此,在上述情况下, VOLUME [ / var / lib / bootstrap] 指令通过在主机上的 / var / lib / docker 中创建一个卷并将其安装在 / var / lib /上来持久化数据引导程序

So in the above case , the VOLUME ["/var/lib/bootstrap"] instruction is persisting the data by creating a volume in /var/lib/docker on the host and mount it on /var/lib/bootstrap in the container.

有关指定卷的说明

关于Dockerfile中的卷,请记住以下几点。

Keep the following things in mind about volumes in the Dockerfile.

基于Windows的容器上的卷:使用基于Windows的容器时,容器内卷的目的地必须是以下其中之一:

Volumes on Windows-based containers: When using Windows-based containers, the destination of a volume inside the container must be one of:


  • 不存在或空目录

  • 不是C的驱动器:

Ch从Dockerfile中对卷进行老化::如果在声明了该卷后有任何构建步骤更改了该卷中的数据,则这些更改将被丢弃。

Changing the volume from within the Dockerfile: If any build steps change the data within the volume after it has been declared, those changes will be discarded.

JSON格式:该列表被解析为JSON数组。您必须用双引号()而不是单引号(')括住单词。

JSON formatting: The list is parsed as a JSON array. You must enclose words with double quotes (")rather than single quotes (').

主机目录是在容器运行时声明的:主机目录(挂载点)从本质上来说是依赖于主机的,这是为了保留映像的可移植性,因为不能保证给定的主机目录在所有主机上都可用,因此,您不能从Dockerfile挂载主机目录。 VOLUME 指令不支持指定host-dir参数。创建或运行容器时必须指定挂载点。

The host directory is declared at container run-time: The host directory (the mountpoint) is, by its nature, host-dependent. This is to preserve image portability, since a given host directory can’t be guaranteed to be available on all hosts. For this reason, you can’t mount a host directory from within the Dockerfile. The VOLUME instruction does not support specifying a host-dir parameter. You must specify the mountpoint when you create or run the container.

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

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