zoukankan      html  css  js  c++  java
  • 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 loose@docker.com
    
    #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 loose@docker.com
    
    #VOLUME指令,配置挂载目录参数
    VOLUME ["/usr/local/volume1","/usr/local/volume2"]

    第二个dockerfile:

    #base image
    FROM tomcat:7
    
    #MAINTAINER,this dockerfile creater
    MAINTAINER loose@docker.com
    
    #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启动
  • 相关阅读:
    一行代码搞定Dubbo接口调用
    测试周期内测试进度报告规范
    jq 一个强悍的json格式化查看工具
    浅析Docker容器的应用场景
    HDU 4432 Sum of divisors (水题,进制转换)
    HDU 4431 Mahjong (DFS,暴力枚举,剪枝)
    CodeForces 589B Layer Cake (暴力)
    CodeForces 589J Cleaner Robot (DFS,或BFS)
    CodeForces 589I Lottery (暴力,水题)
    CodeForces 589D Boulevard (数学,相遇)
  • 原文地址:https://www.cnblogs.com/Json1208/p/8975403.html
Copyright © 2011-2022 走看看