15.dockerfile之VOLUME指令

一、VOLUME指令说明


 Docker镜像被存储在一系列的只读层。当我们开启一个容器,Docker读取只读镜像并添加一个读写层在顶部。如果正在运行的容器修改了现有的文件,该文件将被拷贝出底层的只读层到最顶层的读写层。在读写层中的旧版本文件隐藏于该文件之下,但并没有被不破坏 - 它仍然存在于镜像以下。当Docker的容器被删除,然后重新启动镜像时,将开启一个没有任何更改的新的容器 - 这些更改会丢失。此只读层及在顶部的读写层的组合被Docker称为Union File System(联合文件系统)。

为了能够保存(持久)数据以及共享容器间的数据,Docker提出了Volumes的概念。

Volume可以将容器以及容器产生的数据分离开来,这样,当你使用docker rm container删除容器时,不会影响相关的数据;

Volume可以使得多个容器共享数据;

即我们可以在宿主机上创建一个目录与容器的某个目录(称为挂载点、或者叫卷)关联起来,容器上的挂载点下的内容就是宿主机的这个目录下的内容。

二、VOLUME使用方式


 1.通过docker run命令创建挂载点

首先,查看本地的镜像:

我们tomcat:7这个镜像来启动容器并且创建挂载点:

说明:

docker run是启动容器命令;
-d代表后台运行;
-P代表端口自动帮我们绑定;
--name tomcat代表将启动的容器命名为tomcat;
-v标记在容器中设置了一个挂载点 /usr/local/data(就是容器中的一个目录),并将主机上的 /home/env/containerdata 目录中的内容关联到/usr/local/data下。

容器启动后,先查看宿主机/home/env目录下是否有一个containerdata:

宿主机已存在该目录,接着我们进入容器内部,查看是否生成/usr/local/data目录:

不管宿主机或容器内部,都自动创建了目录,接着我们在宿主机创建一个abc文件,再来查看下容器内是否同步了abc文件:

最后,我们在容器内部创建hello文件,看宿主机挂载的目录是否也存在hello文件:

注意:在启动容器时设置挂载点也可以不指定宿主机的目录,这时docker会自动绑定主机上的一个目录:

通过docker inspect 容器命令可以查看到挂载的目录:

上面 Mounts下的每条信息记录了容器上一个挂载点的信息,"Destination" 值是容器的挂载点,"Source"值是对应的主机目录,查看宿主机是否存在该目录:

注意:使用docker run命令的-v标识创建的挂载点只能对创建的容器有效,如果要创建多个容器,那么每个容器创建时必须指定挂载点。

2.通过dockerfile创建挂载点

通过dockerfile的 VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点,但值得注意的是通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,而是自动生成的

首先,编写dockerfile:

#base image
FROM centos

#MAINTAINER,this dockerfile creater
MAINTAINER [email protected]

#VOLUME,指定挂在目录
VOLUME ["/usr/local/data1"]

其次,通过该dockerfile构建镜像:

最后,启动容器,再通过docker inspect查看挂在到宿主机的目录:

启动容器

根据容器查看挂在信息

注意:在dockerfile中VOLUME可以指定多个挂在目录,即["/usr/local/data1","/usr/local/data2"]代表这两个目录都会挂在到宿主机的自动生成的目录。

3.容器共享挂载点(共享卷)

启动容器时使用--volumes-from 被共享的容器来共享挂载点

首先,创建两个dockerfile,我们要分来源于同一个镜像和来源于不同镜像共享挂载点:

第一个dockerfile:

#base image
FROM tomcat:7

#MAINTAINER,this dockerfile creater
MAINTAINER [email protected]

#VOLUME指令,配置挂载目录参数
VOLUME ["/usr/local/volume1","/usr/local/volume2"]

第二个dockerfile:

#base image
FROM tomcat:7

#MAINTAINER,this dockerfile creater
MAINTAINER [email protected]

#VOLUME指令,配置挂载目录参数
VOLUME ["/usr/local/volume3"]

其次,我们分别根据这两个dockerfile构建两个镜像,分别是tomcat1,tomcat2:

接着,查看我们的镜像:

在准备工作做好后,我们先根据tomcat:v1.0创建一个容器出来,然后校验是否挂载成功:

①.启动容器

②.进入容器中,根据docker inspect 容器查看自动挂载到宿主机的目录

容器中,已经根据dockerfile VOLUME参数生成了两个目录

③.接下来查看挂载到宿主机的目录

④.来源于同一个镜像的不同容器间的挂载目录共享

由于我们目前的容器tomcat1是通过镜像dae47854feea启动的,所以我们重新启动个容器,依然是通过镜像dae47854feea启动,来达到同一个镜像中的不同容器间挂载目录的共享

命令:

docker run --name tomcatextend -it --volumes-from tomcat1 dae47854feea /bin/bash

查看新容器tomcatextend:

通过docker inspect 容器查看该容器共享的挂载目录:

再去对比下tomcat1这个容器的挂载目录,完全一致,证明已经共享挂载目录了。

⑤.来源于不同镜像的不同容器间的挂载目录共享

再次查看本地镜像,方便看整个流程:

目前,仅有的两个容器都是基于tomcat1:v1.0这个镜像生成的容器,所以这次我们根据tomcat2:v1.0镜像启动的容器,并且指定共享的挂载目录来源于镜像为tomcat:v1.0的tomcat1容器,以达到不同镜像的不同容器间的挂载目录共享

说明:tomcat3共享了tomcat1的挂载目录就拥有volume1和volume2两个共享目录,再加tomcat3本身是通过tomcat2:v1.0启动,而tomcat2:v1.0通过dockerfile构建时本身就自带挂载目录volume3,所以这里展示出来是3个。

以上就是分不同情况共享挂载目录。

上面的命令总结:

#指定挂在目录
docker run --name tomcat -it -v /home/env/containerdata:/usr/local/data image /bin/bash
#docker会自动绑定主机上的一个目录
docker run --name tomcat -it -v /usr/local/data image /bin/bash
#自动绑定主机上的目录,需要查看主机目录路径,通过docker inspect 容器可查看
#共享挂载点
1.来源同一个镜像
docker run --name tomcatextend -it --volumes-from tomcat1 dae47854feea  /bin/bash
#这里的image是启动tomcatextend和tomcat1容器是的同一个镜像
2.来源不同镜像
docker run --name tomcat2 -it --volumes-from tomcat1 86ba8c26af60  /bin/bash
#这里的tomcat2是通过86ba8c26af60镜像启动,而tomcat1是通过镜像dae47854feea启动

猜你喜欢

转载自www.cnblogs.com/Json1208/p/8975403.html