docker安装在主机上的卷

我已经成功地在一个使用卷的docker容器之间共享文件夹

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

但我的问题是这和Dockerfile中使用VOLUME命令之间的区别

 VOLUME /path 

我正在使用具有VOLUME命令的图像,我想知道如何与我的主机共享。 我已经使用上面的-v命令完成了,但是我不知道是否需要-vVOLUME

VOLUME命令将在您的容器中安装一个目录,并将在该目录中创build或编辑的所有文件存储在容器文件结构外的主机磁盘上,绕过联合文件系统。

这个想法是,你的容器可以在Docker容器之间共享,只要有一个引用它们的容器(运行或停止),它们就会停留在周围。

您可以让其他容器在运行容器时使用--volumes-from命令装载现有卷(在容器之间有效地共享它们)。

VOLUME-v之间的根本区别在于: -v将从你的操作系统中的docker容器中挂载现有的文件, VOLUME将在你的主机上创build一个新的空卷 ,并将其挂载到你的容器中。

例:

  1. 你有一个Dockerfile定义了VOLUME /var/lib/mysql
  2. 您build立docker图像并为其添加some-volume
  3. 你运行容器

接着,

  1. 你有另一个docker图像,你想使用这个卷
  2. 使用以下命令docker run --volumes-from some-volume docker-image-name:tag容器: docker run --volumes-from some-volume docker-image-name:tag
  3. 现在你已经有一个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的映像应该是可移植的。目录将不会在所有潜在的主机上可用。“