docker在主机上安装卷

时间:2014-08-14 15:14:45

标签: docker mount-point volumes

我已经成功地使用

在具有卷的docker容器之间共享文件夹
docker run -v /host/path:/container/path ...

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

VOLUME /path

我使用的是具有VOLUME命令的图片,我想知道如何与我的主机分享。我是使用上面的-v命令完成的,但我不知道我是否需要-vVOLUME

6 个答案:

答案 0 :(得分:136)

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

我们的想法是,你的卷可以在你的docker容器之间共享,只要有一个引用它们的容器(运行或停止),它们就会保持不变。

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

VOLUME-v之间的根本区别在于:-v将在您的docker容器中安装操作系统中的现有文件,而VOLUME创建一个主机上新的空卷,并将其安装在容器中。

示例:

  1. 您有一个定义VOLUME /var/lib/mysql
  2. 的Dockerfile
  3. 您构建了泊坞窗图片并将其标记为some-volume
  4. 您运行容器
  5. 然后,

    1. 您有另一个要使用此卷的泊坞窗图像
    2. 使用以下命令运行docker容器: docker run --volumes-from some-volume docker-image-name:tag
    3. 现在,您正在运行一个Docker容器,其中some-volume的卷已安装在/var/lib/mysql
    4. 注意:使用--volumes-from将卷安装在卷位置中存在的卷上。即,如果你在/var/lib/mysql中有东西,它将被替换为卷的内容。

答案 1 :(得分:33)

让我添加自己的答案,因为我相信其他人都错过了Docker的观点。

在Dockerfile中使用VOLUME是Right Way™,因为您让Docker知道某个目录包含永久数据。 Docker将为该数据创建一个卷,并且永远不会删除它,即使您删除了使用它的所有容器。

它还绕过了union文件系统,因此该卷实际上是一个实际的目录,它在所有共享它的容器中的正确位置(读写或只读)。

现在,为了从主机访问该数据,您只需要检查容器:

# 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 ,以便我可以轻松访问卷并管理它们包含的数据(仅适用于您关注的卷):

ln -s /var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6... /srv/myapp-www
ln -s /var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87... /srv/myapp-log

答案 2 :(得分:9)

Dockerfile中使用VOLUME来公开其他容器使用的卷。例如,将Dockerfile创建为:

FROM ubuntu:14.04

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

构建图片:

$ 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>

答案 3 :(得分:7)

基本上VOLUME-v选项几乎相等。这些意味着在您的容器上安装特定目录&#39;。例如,VOLUME /data-v /data的含义完全相同。如果您运行具有VOLUME /data-v /data选项的映像,则会在您的容器中装入/data目录。此目录不属于您的容器。

想象一下,您在容器上向/data添加了一些文件,然后将容器提交到新图像中。数据目录中没有任何文件,因为挂载的/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选项之间的区别在于您可以在启动容器时动态使用-v选项。这意味着你可以动态安装一些目录。另一个区别是您可以使用-v

将主机目录挂载到容器上

答案 4 :(得分:6)

这是来自Docker文档本身,可能有帮助,简单明了:

“主机目录本质上是依赖于主机的。因此,您无法从Dockerfile安装主机目录,VOLUME指令不支持传递host-dir,因为构建的映像应该是可移植的。主机目录在所有潜在的主机上都不可用。“。

答案 5 :(得分:0)

如果您来这里是因为您正在寻找一种浏览任何VOLUME的简单方法:

  1. 使用docker volume list
  2. 查找卷的名称
  3. 关闭该卷所连接的所有正在运行的容器
  4. 运行docker run -it --rm --mount source=[NAME OF VOLUME],target=/volume busybox
  5. 将打开一个外壳。 cd /volume输入音量。