docker容器实现数据持久化的两种方式及其区别

julien 2020-01-02

前言

这篇博文是我对docker实现数据持久化几种方式的特征进行一个总结。

在docker中,它的存储文件系统是在dockerhost上原有的xfs或ext4架设了一层文件系统:overlay2(将此行重点标注的原因就是我在面试中被问到过:docker使用的是什么文件系统?),通过docker info命令可以查看出主机上docker相关的信息,包括支持的网络类型、系统版本、内核版本、docker主机的cpu、内存等信息。如下:

docker容器实现数据持久化的两种方式及其区别

在docker中实现数据持久化有两种方式:Bind mount和Docker Manager Volume。

Bind mount和Docker Manager Volume的区别:

  • Bind mount数据持久化的方式,如果是挂载本地的一个目录,则容器内对应的目录下的内容会被本地的目录覆盖掉,而Docker Manager Volume这种方式则不会,不管哪种方式的持久化,在容器被销毁后,本地的数据都不会丢失。
  • 使用“-v”选项挂载时,Bind mount明确指定了要挂载docker host本地的某个目录到容器中,而Docker Manager Volume则只指定了要对容器内的某个目录进行挂载,而挂载的是docker host本地的哪个目录,则是由docker来管理的。

数据持久化的特点:

  • Data Volume是目录或文件,不能是没有格式化的磁盘(块设备)。
  • 若要挂载一个文件到容器中,那么该文件必须是已经存在,否则,会被当成一个目录挂载到容器中。
  • 默认挂载到容器内的文件或目录,容器是有读写权限。可以在运行容器时-v指定完挂载目录后面加“:ro” 限制容器的写入权限(:ro来限制)。
  • volume数据可以永久保存,即使使用它的容器已经被销毁。

1、Bind mount——数据卷容器:--volumes-from方式实现数据持久化

以下数据卷容器挂载的方式就是Bind mount实现方式。

实现的大概思路如下:

  1. 运行一个容器作为数据卷容器,挂载本地目录到容器内的本地目录,无需所挂载的源目录或目标挂载点是否存在,docker会自动创建相应的目录的,也无需考虑使用哪个镜像来运行这个容器,任意镜像都可以;
  2. 之后无论运行多少容器,都可以使用--volumes-from选项来指定第一个运行的容器进行数据持久化;
  3. 实现的效果为:挂载数据卷容器实现数据持久化的容器,会自动将数据卷容器挂载的本地目录挂载到该容器本身(本身的挂载点与数据卷容器的挂载点自动保持一致),也仅仅只会挂载数据卷容器实现了数据持久化的目录到自己本身,而不是数据卷容器的全部目录。

上面实现的效果可能我表达的不够好,举个例子 :
有A、B、C这三个容器,其中A作为数据卷容器,挂载了本地的/data/web01和/data/web02这两个目录到容器内的/usr/share/nginx/html/和/data这两个目录。
容器B和容器C在运行之初,通过--volumes-from选项来指定容器A的名称或ID,那么最终实现的效果就是,A、B、C这三个容器内都会存在/usr/share/nginx/html及/data这两个目录,并且是实现了数据持久化的,对应的本地目录都是/data/web01和/data/web02。

#基于busybox镜像来做数据卷容器
[ ~]# docker run -tid --name data -v /data/web01/:/dbdata -v /data/web02:/index busybox
#运行两个nginx容器
[ ~]# docker run -d --name web01 --volumes-from data -P nginx
[ ~]# docker run -d --name web02 --volumes-from data -P nginx

当容器运行成功后,通过命令docker inspect 容器名称来查看容器的挂载信息(在查看出来的信息中找到mount字段):

1)数据卷容器data查看到的mount信息如下:

[ ~]# docker inspect data

docker容器实现数据持久化的两种方式及其区别

2)容器web01查看到的mount信息如下:

[ ~]# docker inspect web01

docker容器实现数据持久化的两种方式及其区别

3)容器web02查看到的mount信息如下:

[ ~]# docker inspect web02

docker容器实现数据持久化的两种方式及其区别

不难发现,采用数据卷容器这种方式可以让多个容器挂载相同的目录,让其要实现数据持久化的目录保持一致。

在需要运行的容器都运行完成后,--volumes-from指定的容器,停止或被删除,都不会影响基于nginx镜像运行的容器数据持久化。

数据卷容器使用场景:

  • 多个容器需要实现数据持久化的目录是一致的,可以采用这种方式。
  • 如果不使用这种方式,并且还要对多个目录实现数据持久化,那么每运行个容器都要指定很多"-v"选项来指定目录,并且出现指定错误的几率比较大。

2、Docker Manager Volume实现数据持久化

#运行容器时,-v选项只指定一个路径,则就是容器内的目录,也就是Docker Manager Volume方式
[ ~]# docker run -tid -v /usr/share/nginx/html -P --name web03 nginx
[ ~]# docker inspect web03   #查看容器的mount字段信息

返回的信息如下:

docker容器实现数据持久化的两种方式及其区别

可以看到,它是挂载的本地一个目录,这个目录看起来比较杂乱无章,其实不然,它是docker 的root根目录,在其根目录下有一个volume目录,这个目录就是用来存放Docker Manager Volume实现数据持久化产生的数据的,在volume目录下会有以容器ID命名的目录,然后下面会有_data这个目录,这个目录就是和容器内的数据持久化目录遥相对应的。建议了解一下docker 的根目录下都有哪些东西,面试的时候我被问到过。根目录下的部分信息如下:

docker容器实现数据持久化的两种方式及其区别

———————— 本文至此结束,感谢阅读 ————————

相关推荐