一.什么是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命令将多个主机目录挂载到容器。
示例演示:
执行命令
docker run -it -v /temp/volume_test/:/my_data centos
启动一个centos容器。
在宿主机上执行
docker inspect ${容器id或容器名}
查看数据卷挂载是否成功。
其中"RW":true
表示既可读也可写。验证容器和宿主机之间数据是否共享
结果:容器/my_data
目录下的文件和宿主机下/tmp/volume_test/
的文件会完全同步。容器停止退出后,主机修改后数据是否同步?
结果:是创建只读数据卷
前面创建的容器数据卷是可读可写的,也可以创建容器内只可读不可写(read only)的数据卷,命令是1
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro ${镜像名}
容器指定目录则变成了只可读的了
使用inspect命令,可以看到
"RW":false
字样。
注意:在宿主机仍然是可读可写的。
2.DockerFile添加
创建一个DockerFile文件。DockerFile内容为
FROM centos
VOLUME [“/dataVolumeContainer1”,”/dataVolumeContainer2”]
CMD echo “finished,——–success”
CMD /bin/bash通过build命令将创建的DockerFile构建为一个新的镜像。
1
docker build -f /root/docker_file/myDockerFile -t my_custom/centos .
该命令中的参数:
- -f:file,指定DockerFile文件的路径
- -t:taget,指定构建后的镜像名和版本(tag),不指定tag则默认是latest。
结尾的.号:用来指定镜像构建过程中的上下文环境的目录为当前目录。
运行这个新镜像的容器
可以看到容器中就会有在DockerFile中定义的数据卷了。
通过
docker inspect
命令可以查看容器数据卷对应到宿主机目录
三.数据卷容器
数据卷容器(Data Volume Containers): 使用特定容器维护数据卷。
多个容器之间进行数据共享我们需要用到命令--volumes-from
,有点类似于Java中继承的概念。下面是演示示例:
启动一个带有数据卷的容器centos01
1
docker run -it -v /tmp/docker_volume_data:/container_data --name centos01 centos
在数据卷目录下新增一个
test.log
文件,并向文件中写入数据。
再运行两个容器centos02和centos03,在这两个容器中使用
--volumes-from
来挂载centos01容器中的数据卷。1
2docker run -it --name centos02 --volumes-from centos01 centos
docker run -it --name centos03 --volumes-from centos01 centos可以看到进入到这两个容器之后,都能共享数据卷目录
/container_data
下的数据。
这样可以做到:三个容器任何一方在该目录下的写入数据,其他容器都可以看到。
如果通过命令
docker rm -f
删除centos01容器,/container_data
仍然可以在centos02和centos03之间共享。再新建centos4并使用
--volumes-from
来挂载centos03容器中的数据卷。即使删除了centos02和centos03,/container_data
仍然存在。最后连centos4也删除,则容器数据卷的生命周期结束。
官网上有一句话描述的是,容器之间配置信息的传递,数据卷的生命周期会一致持续到没有容器使用它为止,换言之,只要有一个容器仍在使用该数据卷,该数据卷一直都可以进行数据共享,通俗地来说,如果此时我们把父容器关闭掉,两个字容器之间依旧可以进行数据共享,而且通过继承子容器生成的新容器,一样可以与子容器进行数据共享。这就是docker容器间的数据传递共享。
常见的应用:使用纯数据容器来持久化数据库、配置文件或者数据文件等。