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