Docker(五)Docker数据卷

一.什么是Docker的数据卷

想要了解Docker Volume,首先要从Docker的文件系统是如何工作的说起。Docker镜像是由多个文件系统(只读层)叠加而成。当我们启动一个容器的时候,Docker会加载只读镜像层并在其上(即镜像栈顶部)添加一个读写层。如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏。当删除Docker容器,并通过该镜像重新启动时,之前的更改将会丢失。

为了能够保存(持久化)数据以及共享容器间的数据,Docker提出了Volume的概念。简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。

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

作用:

  • 持久化数据
  • 容器间共享数据

Docker中数据管理主要有两种方式:数据卷和数据卷容器。

二.数据卷

数据卷(Data Volumes): 容器内数据直接映射到宿主机。

数据卷如何使用呢?有两种方式:(1)启动时通过命令行添加;(2)通过DockerFile添加。

1.直接添加

数据卷的使用,类似于 Linux 下对目录进行 mount,如果想在容器中使用主机上的某个目录,你可以通过-v参数来指定:

1
docker run -it -v /宿主机绝对路径目录:/容器内目录 ${镜像名}

这样Docker将会使用指定的主机目录挂载到容器,并对应到容器的指定目录。
PS:

  • 如果主机上的路径不存在,目录将自动在给定的路径中创建。
  • 可以多次使用-v命令将多个主机目录挂载到容器。

示例演示:

  1. 执行命令docker run -it -v /temp/volume_test/:/my_data centos启动一个centos容器。

  2. 在宿主机上执行docker inspect ${容器id或容器名}查看数据卷挂载是否成功。

    其中"RW":true表示既可读也可写。

  3. 验证容器和宿主机之间数据是否共享

    结果:容器/my_data目录下的文件和宿主机下/tmp/volume_test/的文件会完全同步。

  4. 容器停止退出后,主机修改后数据是否同步?
    结果:是

  5. 创建只读数据卷
    前面创建的容器数据卷是可读可写的,也可以创建容器内只可读不可写(read only)的数据卷,命令是

    1
    docker run -it -v /宿主机绝对路径目录:/容器内目录:ro ${镜像名}

    容器指定目录则变成了只可读的了

    使用inspect命令,可以看到"RW":false字样。

    注意:在宿主机仍然是可读可写的。

2.DockerFile添加

  1. 创建一个DockerFile文件。DockerFile内容为

    FROM centos
    VOLUME [“/dataVolumeContainer1”,”/dataVolumeContainer2”]
    CMD echo “finished,——–success”
    CMD /bin/bash

  2. 通过build命令将创建的DockerFile构建为一个新的镜像。

    1
    docker build -f /root/docker_file/myDockerFile -t my_custom/centos .

    该命令中的参数:

    • -f:file,指定DockerFile文件的路径
    • -t:taget,指定构建后的镜像名和版本(tag),不指定tag则默认是latest。
    • 结尾的.号:用来指定镜像构建过程中的上下文环境的目录为当前目录。

  3. 运行这个新镜像的容器
    可以看到容器中就会有在DockerFile中定义的数据卷了。

  4. 通过docker inspect命令可以查看容器数据卷对应到宿主机目录

三.数据卷容器

数据卷容器(Data Volume Containers): 使用特定容器维护数据卷。
多个容器之间进行数据共享我们需要用到命令--volumes-from,有点类似于Java中继承的概念。下面是演示示例:

  1. 启动一个带有数据卷的容器centos01

    1
    docker run -it -v /tmp/docker_volume_data:/container_data --name centos01 centos

    在数据卷目录下新增一个test.log文件,并向文件中写入数据。

  2. 再运行两个容器centos02和centos03,在这两个容器中使用--volumes-from来挂载centos01容器中的数据卷。

    1
    2
    docker run -it --name centos02 --volumes-from centos01 centos
    docker run -it --name centos03 --volumes-from centos01 centos

    可以看到进入到这两个容器之后,都能共享数据卷目录/container_data下的数据。

    这样可以做到:三个容器任何一方在该目录下的写入数据,其他容器都可以看到。

  3. 如果通过命令docker rm -f删除centos01容器,/container_data仍然可以在centos02和centos03之间共享。

  4. 再新建centos4并使用--volumes-from来挂载centos03容器中的数据卷。即使删除了centos02和centos03,/container_data仍然存在。

  5. 最后连centos4也删除,则容器数据卷的生命周期结束。

官网上有一句话描述的是,容器之间配置信息的传递,数据卷的生命周期会一致持续到没有容器使用它为止,换言之,只要有一个容器仍在使用该数据卷,该数据卷一直都可以进行数据共享,通俗地来说,如果此时我们把父容器关闭掉,两个字容器之间依旧可以进行数据共享,而且通过继承子容器生成的新容器,一样可以与子容器进行数据共享。这就是docker容器间的数据传递共享。

常见的应用:使用纯数据容器来持久化数据库、配置文件或者数据文件等。

------ 本文完 ------