一、容器数据卷的介绍
1、什么是容器数据卷?
记得以前上Linux课的时候,学校的教学平台每次上完课数据都会清空,所以每次老师上课都要提前十几分钟过来安装虚拟机。这样就会很麻烦,每次上课都得安装。通常,我们在使用docker容器的时候会产生很多的数据文件,而当我们关闭docker容器的时候,这些数据文件是会消失的。然而,这些数据有可能是我们需要的,所以需要保存起来进行使用。因此,我们希望Docker容器在运行过程中产生到的有用的数据是可以持久化的,并能够实现数据共享。
在介绍容器数据卷之前,需要明白Docker的文件系统的工作流程。上一讲中介绍了:Docker镜像是由多个文件系统叠加而成。当我们启动一个容器的时候,Docker会加载只读镜像层,并在只读镜像层上面添加一个读写层。这种由只读层和在顶部的读写层所构成的组合称之为联合文件系统(Union File System)。如果运行中的容器修改了现有的一个已经存在的文件,则该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中此文件的副本所隐藏。如果删除Docker容器,并通过该镜像重新启动时,之前的更改就会丢失。因此,为达到数据持久化并且共享荣期间的数据的目的,Docker提出了卷(Volume)的概念。所谓的卷,就是目录或者文件,它存在于一个或多个容器中,由Docker挂载到容器,其设计目标就是实现数据持久化,并独立于容器的生命周期。它可以绕过默认的联合文件系统,以正常的文件或者目录的形式存在于宿主机之上。我们可以把Docker容器数据卷看成生活中使用的U盘,多个U盘都可以插到电脑上,实现数据之间的传递依赖。
2、容器数据卷的特点
- 数据卷可以在容器之间共享或重用数据。
- 数据卷中的更改可以直接生效。
- 数据卷中的更改不会包含在镜像的更新中。
- 数据卷的生命周期一直持续到没有容器使用它为止。
3、使用场景
-
在多个容器之间共享数据,多个容器可以同时以只读或者读写的方式挂载同一个数据卷,从而共享数据卷中的数据。
-
当宿主机不能保证一定存在某个目录或一些固定路径的文件时,使用数据卷可以规避这种限制带来的问题。
-
需要把容器中的数据存储在宿主机之外的地方时,比如远程主机上或云存储上。
-
需要把容器数据在不同的宿主机之间备份、恢复或迁移时,数据卷是很好的选择。
二、添加容器数据卷的两种方式
1、直接命令添加数据卷
(1)命令:docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
(2)实例
执行命令:docker run -it -v /hostDir:/containerDir centos
查看挂载是否成功:docker inspect 156c8235a5d5
(3)数据共享实例
a.进入宿主机的hostDir目录,并创建text.txt,添加信息。
b.进入到容器的containerDir查看信息。
c.在text.txt中,容器加入自己的信息。
d.在宿主机端查看text.txt的内容
(4)权限的设定
命令:docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名 (ro:只读;wo:只写;rw:读写)
如下:容器指定只读,因此通过touch text.txt,就提示该文件是只读的。
(5)容器停止退出后,主机修改后数据是否同步
a.停止容器,exit退出。
b.在宿主机的hostDir中新建一个newFile.txt
c.重新启动容器,并进入containerDir,查看当前目录下的文件,发现有newFile.txt。
docker start ID 启动容器
docker attach ID 进入容器
d.结论:主机修改后,数据会同步。
2、DockerFile添加
(1)基本使用过程
a.在宿主机的根目录下新建mydocker文件夹并进入。
b.在 DockerFile中使用 VOLUME 指令来给镜像添加一个或多个数据卷
命令:VOLUME["/dataVolumeContainer1","/dataVolumeContainer2","/dataVolumeContainer3"]
说明:出于可移植和分享的考虑,用 -v 主机目录:容器目录这种方法不能够直接在 DockerFile中实现。由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。
c.dockerfile构建,在dockerfile中加入以下内容:
#volume test
#继承centos镜像
FROM centos
#在上面继承的centos目录下建立两个数据卷
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished and success!!!"
CMD /bin/bash
d.build后生成镜像
命令:docker build -f /mydocker/Dockerfile -t yht/centos .
结果:
说明:
-t是-tag list的意思。
从上面的build也能体现出Docker镜像的分层结构。
e.启动容器
命令:docker run -it yht/centos
f.查看容器内的卷目录地址对应的宿主机目录路径
g.进入dataVolumeContainer1,创建text.txt文件
h.在宿主机的目录下查看文件
注意:如果Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied,则只需在挂载目录后多加一个--privileged=true参数即可。
三、数据卷容器
数据卷容器是指命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,而挂载数据卷的容器称之为数据卷容器。接下来以上述新建的yht/centos为例演示一下数据卷容器。
1、基本过程
(1)先启动一个父容器dc01,并在dataVolumeContainer1中新增内容
(2)继续创建容器dc02、dc03,分别继承自dc01。
命令:
docker run -it --name dc02 --volumes-from dc01 yht/centos
docker run -it --name dc03 --volumes-from dc01 yht/centos
执行命令并查看目录dataVolumeContainer1下的文件
(3)在dc02、dc03的dataVolumeContainer1下分别创建doc02.txt和doc3.txt,之后启动dc01,可看到dc02和dc03添加的数据。
2、几点说明
(1)先删除 dc01,然后修改dc02 ,dc03 是否可以访问——可以
(2)新建dc04继承dc03后再删除dc03,是否可以访问原内容——可以
(3)结论
容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。也就是说,只要有一个容器仍在使用该数据卷,该数据卷一直都可以进行数据共享。通俗地来说,如果此时我们把父容器关闭掉,两个字容器之间依旧可以进行数据共享,而且通过继承子容器生成的新容器,同样能够与子容器进行数据共享。这就是docker容器间的数据传递共享。