docker安装在主机上的卷
我已经成功地在一个使用卷的docker容器之间共享文件夹
docker run -v /host/path:/container/path ...
但我的问题是这和Dockerfile中使用VOLUME
命令之间的区别
VOLUME /path
我正在使用具有VOLUME
命令的图像,我想知道如何与我的主机共享。 我已经使用上面的-v
命令完成了,但是我不知道是否需要-v
和VOLUME
。
VOLUME
命令将在您的容器中安装一个目录,并将在该目录中创build或编辑的所有文件存储在容器文件结构外的主机磁盘上,绕过联合文件系统。
这个想法是,你的容器可以在Docker容器之间共享,只要有一个引用它们的容器(运行或停止),它们就会停留在周围。
您可以让其他容器在运行容器时使用--volumes-from
命令装载现有卷(在容器之间有效地共享它们)。
VOLUME
和-v
之间的根本区别在于: -v
将从你的操作系统中的docker容器中挂载现有的文件, VOLUME
将在你的主机上创build一个新的空卷 ,并将其挂载到你的容器中。
例:
- 你有一个Dockerfile定义了
VOLUME /var/lib/mysql
。 - 您build立docker图像并为其添加
some-volume
- 你运行容器
接着,
- 你有另一个docker图像,你想使用这个卷
- 使用以下命令
docker run --volumes-from some-volume docker-image-name:tag
容器:docker run --volumes-from some-volume docker-image-name:tag
- 现在你已经有一个docker容器运行了,这个容器将在
/var/lib/mysql
挂载some-volume
注意:使用--volumes-from
会将卷挂载到卷的位置上。 也就是说,如果你有/var/lib/mysql
东西,它将被卷的内容replace。
让我加我自己的答案,因为我相信其他人都错过了Docker的观点。
在Dockerfile中使用VOLUME
是正确的方法,因为你让Docker知道某个目录包含永久数据。 Docker将为该数据创build一个卷,并且永远不会删除它,即使删除了所有使用它的容器。
它也绕过联合文件系统,因此卷实际上是一个实际的目录,它被挂载(读写或只读)在所有共享它的容器的正确位置。
现在,为了从主机访问这些数据,你只需要检查你的容器:
# docker inspect myapp [{ . . . "Volumes": { "/var/www": "/var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6...", "/var/cache/nginx": "/var/lib/docker/vfs/dir/62499e6b31cb3f7f59bf00d8a16b48d2...", "/var/log/nginx": "/var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87..." }, "VolumesRW": { "/var/www": false, "/var/cache/nginx": true, "/var/log/nginx": true } }]
我通常做的是在/ srv等标准位置创build符号链接 ,以便我可以轻松访问这些卷并pipe理它们所包含的数据(仅限于您关心的卷):
ln -s /var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6... /srv/myapp-www ln -s /var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87... /srv/myapp-log
基本上VOLUME
和-v
选项几乎相等。 这意味着“在你的容器上安装特定的目录”。 例如, VOLUME /data
和-v /data
含义完全相同。 如果您运行具有VOLUME /data
或-v /data
选项的映像,则将/data
目录装入您的容器。 这个目录不属于你的容器。
想象一下,你添加一些文件到/data
容器上的/data
,然后提交容器到新的形象。 数据目录中没有任何文件,因为mounted /data
目录属于原始容器。
$ docker run -it -v /data --name volume ubuntu:14.04 bash root@2b5e0f2d37cd:/# cd /data root@2b5e0f2d37cd:/data# touch 1 2 3 4 5 6 7 8 9 root@2b5e0f2d37cd:/data# cd /tmp root@2b5e0f2d37cd:/tmp# touch 1 2 3 4 5 6 7 8 9 root@2b5e0f2d37cd:/tmp# exit exit $ docker commit volume nacyot/volume 835cfe3d8d159622507ba3256bb1c0b0d6e7c1419ae32751ad0f925c40378945 nacyot $ docker run -it nacyot/volume root@dbe335c7e64d:/# cd /data root@dbe335c7e64d:/data# ls root@dbe335c7e64d:/data# cd /tmp root@dbe335c7e64d:/tmp# ls 1 2 3 4 5 6 7 8 9 root@dbe335c7e64d:/tmp# root@dbe335c7e64d:/tmp#
像/data
这样的挂载目录被用来存储不属于你的应用程序的数据。 您也可以使用VOLUME
预定义不属于容器的数据目录。
Volume
和-v
选项之间的区别在于,您可以在启动容器时dynamic使用-v
选项。 这意味着你可以dynamic地挂载一些目录。 另一个区别是你可以使用-v
来挂载你的主机目录
在Dockerfile
中使用VOLUME来显示其他容器使用的卷。 例如,创buildDockerfile
为:
从Ubuntu的:14.04
RUN mkdir /myvol RUN echo "hello world" > /myvol/greeting VOLUME /myvol
build立形象:
$ docker build -t testing_volume .
运行容器,比如container1:
$ docker run -it <image-id of above image> bash
现在用volume-from选项运行另一个容器(比如说container2)
$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash
您将从container1 /myvol
目录中的所有数据到同一位置的container2。
-v
选项是在容器的运行时给出的,该容器用于在主机上安装容器的目录。 使用起来很简单,只需要提供带有参数的-v
选项作为<host-path>:<container-path>
。 整个命令可能是$ docker run -v <host-path>:<container-path> <image-id>
这是来自Docker文档本身,可能有帮助,简单明了:
“主机目录本质上是依赖于主机的,因此,你不能从Dockerfile挂载主机目录,VOLUME指令不支持传递主机目录,因为构build的映像应该是可移植的。目录将不会在所有潜在的主机上可用。“