Dockerfile 中的 VOLUME 指令有什么用途?

Dockerfile 中的 VOLUME 指令有什么用途?

在文档中,它说 VOLUME 指令创建了一个 mout 点,但我使用创建了一个图像

FROM alpine
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting

我能够使用 /myvol 或容器文件系统上的任何其他路径docker run -v vol:/myvol myimage,并且能够在主机上的 /var/lib/docker/vol/_data 中看到数据。

VOLUME myvol添加至 Dockerfile 会有什么不同?

答案1

我一直在努力理解这一点,并且不得不做一些实际的测试,因为文档对我来说有点模糊。

使用 Dockerfile 中的 VOLUME 指令,您可以明确声明从该映像创建的容器公开的卷,即使在创建容器时未明确安装该卷 - 例如docker run -v <volume>:/data <image name>

相反,我可以在 Dockerfile 中有一个指令

FROM alpine

RUN mkdir /data && echo "Some data" > /data/mydata
VOLUME /data

从使用上述 Dockerfile 构建的镜像启动容器:

docker run -ti --rm --name volume-test voltest

检查正在运行的容器

docker container inspect volume-test

...
        "Mounts": [
            {
                "Type": "volume",
                "Name": "c4d070456dfa65540bd5c75b958930837bbf4277f4a4169b791679127f29a73a",
                "Source": "/var/snap/docker/common/var-lib-docker/volumes/c4d070456dfa65540bd5c75b958930837bbf4277f4a4169b791679127f29a73a/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ]
...

如您所见,容器的 /data 目录中已安装一个卷。由于 Dockerfile 中的 VOLUME 指令,此匿名卷是在容器创建期间自动创建的,并且由于容器是使用--rm选项启动的,因此当容器停止时它将被自动删除(假设当时没有其他东西会使用它)。您可以在docker volume ls停止容器后使用来确认这一点。

这允许从其他容器使用此类临时卷,例如通过运行以下命令安装它们:

docker run --rm -ti --name alpine-vol --volumes-from volume-test alpine sh

检查/data新启动的容器中的目录,它将包含写入卷上的原始容器的数据。

当数据需要在容器之间共享,但在原始容器被移除后不需要保留时(例如作为 sidecar 模式的一部分),我确实看到了这种用法。如果需要数据持久性,您仍然可以将卷明确地挂载到同一目录中。

答案2

VOLUME 的明显用途是使用容器提供的数据填充新的持久卷。无论您部署哪种类型的应用程序,几乎总是需要一些初始数据。文档明确指出此复制仅在新创建卷时才会发生。

相关内容