通过本篇文章我们可以了解到容器镜像结构、将主机数据挂载到容器的方式、容器数据卷及数据卷的备份与恢复等技术,下面我们就一起来学习吧!
默认情况下容器中所有创建的文件及数据都被存储在了容器的可写层,如果按默认操作会有如下问题:
1)容器被删除数据不会保存,同时如果另外一个进程想要调用容器中数据也非常困难;
2)容器的可写层与运行容器的主机紧密耦合,无法轻松地将数据移动到其它地方;
3)容器数据写入容器可写层需要使用Storage driver(容器存储驱动)来管理文件系统进行写操作,因为多了这一层导致其比直接将数据写入主机的文件系统的效率低很多。
针对上述问题,Docker 提供了四种不同的方式将数据从 Docker 主机直接挂载到容器中,分别为卷(volumes),绑定挂载(bind mounts),临时文件系统(tmpfs)及命名通道(named pipe),这四种方式的named pipe是windows系统独有的(因为实际工作中容器大多都是部署在linux系统上的,所以本篇文章我们主要介绍前三种挂载方式)。卷(volumes),绑定挂载(bind mounts)及临时文件系统(tmpfs)这三种挂载方式特点如下:
1)卷存储在 Docker 管理的主机文件系统的一部分中(/var/lib/docker/volumes/)中,完全由 Docker 管理,卷存储是docker数据保存最推荐的方法;
2)bind mounts 绑定挂载,可以存储在主机系统上的任何位置,甚至可以是重要的系统文件或目录,Docker主机或Docker容器上的非Docker进程可以随时对其进行修改;
3)tmpfs 仅存储在主机系统的内存中,而不会写入主机的文件系统。
下面我们就来看看怎么创建这三种存储方式吧!
卷是这三种存储方式中唯一使用Docker来创建与管理的,卷的推荐使用场景如下:
1)在多个运行容器进行数据共享;
2)当您要将容器的数据存储在远程主机或云上时;
3)当您需要将数据从一台Docker主机备份,还原或迁移到另一台Docker主机时,卷是一个更好的方案;
4)容器中程序需要更好的IO性能。
下面我们看看如何使用docker命令来操作卷
(1) 查看卷列表
1. # 查看卷列表
2. # docker volume ls
(2) 创建卷
创建卷的具体命令如下:
1. # 创建卷
2. # docker volume create [Volume Name]
我们现在创建一个volume2,同时查看创建卷的详细参数,操作如下
1. # 创建卷
2. # docker volume create volume2
3. #
4. # 查看volume2的详细信息
5. # docker volume inspect volume2
(3) 挂载卷
挂载卷是在创建容器时进行绑定的,在创建容器docker container run后面加参数进行卷的挂载,其挂载有两种方式一种通过-v挂载一种通过--mount,-v用于单独的容器挂载而—mount一般用于docker service(也就是docker swarm),下面是这两个参数的具体说明:
1. -v:
2. 由三个由冒号(:)分隔的字段组成,[HOST-DIR:]CONTAINER-DIR[:OPTIONS]
3. 1)HOST-DIR 代表主机上的目录或数据卷的名字。省略该部分时,会自动创建一个匿名卷。如果是指定主机上的目录,需要使用绝对路径。
4. 2)CONTAINER-DIR 代表将要挂载到容器中的目录或文件,即表现为容器中的某个目录或文件
5. 3)OPTIONS 代表配置,例如设置为只读权限(ro),此卷仅能被该容器使用(Z),或者可以被多个容器使用(z)。多个配置项由逗号分隔。
6.
7. --mount:
8. 由多个键值对组成,键值对之间由逗号分隔。例如:type=volume,source=volume2,destination=/volume2,ro=true
9. 1)type,指定类型,可以指定为 bind,volume,tmpfs。
10. 2)source,当类型为 volume 时,指定卷名称,匿名卷时省略该字段。当类型为 bind,指定路径。可以使用缩写 src。
11. 3)destination,挂载到容器中的路径。可以使用缩写 dst 或 target。
12. 4)ro 为配置项,多个配置项直接由逗号分隔一般使用 true 或 false。
下面我们-v命令进行卷挂载具体操作如下:
1. #创建容器test10,并通过-v进行卷volume1挂载,将volume1挂载到容器file1目录
2. docker container run -it --name test10 --hostname test10
3. -v volume1:/file1 centos /bin/bash
我们可以通过如下命令查看容器test10与volume的映射关系
1. #查看容器详细的配置信息
2. docker container inspect test10
(4) 删除卷
现在我们来看看删除卷的命令格式
1. # 删除卷
2. docker volume rm [volume name]
我们删除刚才创建的卷volume2具体操作如下
自docker发布以来就支持绑定挂载了,绑定挂载支持的功能相较于卷来说比较有限。绑定挂载通过将主机上的目录绑定到容器中,容器就可以操作和修改主机上该目录的内容。绑定挂载性能非常好,但是它们依赖于具有特定目录结构的主机文件系统。
绑定挂载的参数与卷一致,可以通过-v或者—mount进行挂载,-v用于单独的容器挂载而—mount一般用于docker service。我们在本地主机上创建目录bind_mount_test,同时在目录中创建一个文件file1,然后将该目录绑定挂载到容器/home/bind_mount_test目录具体操作如下:
1. # 创建容器test1,同时将目录bind_mount_test绑定到容器的/home/bind_mount_test目录
2. docker container run -it -v
3. /root/bind_mount_test:/home/bind_mount_test --name test1 centos /bin/bash
绑定挂载的主机目录如果不存在,则会自动创建该目录,现在我们给主机目录bind_mount_test中再创建一个文件file2.txt并输入内容"kan dao ma",我们看看在容器中是否能够看到,同时我们在容器test1的bind_mount_test目录中创建一个文件file3.txt,看看在主机上是否能够查看到,具体操作如下
通过上述操作我们可以发现通过绑定挂载的容器目录其实完全由主机的文件系统进行管理,而不像卷是通过docker自己管理的,所以像目录的权限,SELINUX 等问题都需要我们自己来管理。
卷与绑定挂载主要是用于主机和容器之间共享文件,容器停止后数据还可以保留,tmpfs挂载是临时的,数据保留在主机内存中的,当容器停止后数据就会被删除。该挂载方式的数据不能在两个容器间进行共享,同时该挂载方式只支持linux系统。
tmpfs挂载也有两个命令参数,一个是—tmps另外一个是—mount,跟卷与绑定挂载类似,--tmpfs用于单个容器挂载—mount用于docker service挂载。下面我们通过—tmpfs来将容器App目录挂载到内存中,具体操作如下:
1. # 创建容器tmptest,同时通过tmpfs命令将app目录挂载到内存中
2. docker container run -it --name tmptest --tmpfs /app centos /bin/bash
上面的章节我们了解了容器的几种存储方式,如果我们想要容器间共享一些实时更新的数据该怎么操作呢,其实docker给出了解决方案就是用户数据卷容器。数据卷容器通过卷方式挂载文件目录,其他容器通过挂载这个容器实现数据共享,这个挂载数据卷的容器就叫做数据卷容器。数据卷容器就是一种普通容器,它专门提供数据卷供其它容器挂载使用。现在我们看看怎么通过数据卷容器实现数据的共享,具体操作如下:
1)创建数据卷test_volume,同时创建一个数据卷容器(其实就是普通容器),将这个创建的卷挂载到数据卷容器中
1. # 创建卷test_volume
2. docker volume create test_volume
3.
4. #创建数据卷容器data_container,同时将test_volume卷挂载到该容器的share_dir目录
5. docker container run -it -v test_volume:/share_dir
6. --name data_container --hostname data_container centos /bin/bash
2)创建两个普通容器test100与test200同时继承数据卷容器所挂载的数据卷
1. # 创建容器test100,--volumes-from命令用于继承指定数据卷容器
2. docker container run -it --volumes-from data_container
3. --name test100 --hostname test100 centos /bin/bash
4.
5. # 创建容器test200,--volumes-from命令用于继承指定数据卷容器
6. docker container run -it --volumes-from data_container
7. --name test200 --hostname test200 centos /bin/bash
3)我们在容器test100与test200中分别对文件file1.txt进行操作,最后我们在数据卷容器中查看file1.txt文件是否在实时更新
通过上述操作我们可以发现通过数据卷容器可以实现不同容器间的数据共享需求。
(1) 数据备份
如果我们想对刚才的数据卷容器的数据卷中数据进行备份,可以创建一个备份容器,该容器继承数据卷容的数据卷,从而实现数据的备份。其实就是创建一个备份容器通过挂载绑定方式将主机文件目录挂载到备份容器中,然后在备份容器中将继承的数据卷目录备份到绑定挂载映射的目录,从而实现了数据的备份具体操作如下:
1. # 创建备份容器,然后该容器不仅继承数据卷容器的数据卷同时通过挂载绑定方式挂载主机系统备份目录
2. # 通过在容器中执行tar命令将数据卷映射的目录share_dir备份到挂载绑定映射的目录backup中
3. docker container run --volumes-from data_container
4. -v /root/backupfile:/backup centos tar cvf /backup/backup.tar /share_dir/
(2) 数据恢复
数据恢复其实跟备份类似,我们创建一个新容器同时将在主机系统备份目录通过挂载绑定的方式挂载到新容器中,然后通过在容器中执行tar包的解压缩命令就可以将数据进行恢复了具体操作如下:
至此我们docker存储管理就全部讲完了,大家有什么问题欢迎在文章后面进行评论留言,最后如果喜欢不要忘了点赞、关注与转发哦!