08-Docker容器数据持久化和数据共享

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huangjun0210/article/details/86221924

1. 概述

docker 主要有两种数据存储形式, 一种是storage driver(也叫做 Graph driver), 另一种是 volume driver。 stroage driver主要是存储那些无状态的数据,写入密集型的场景应该使用 volume driver。

2. storage driver

容器运行的文件系统是镜像层和容器层组成的,一层一层叠加,只有最上面的那层是可写的,其他层都是只读的。 Docker通过Union FS技术支持文件的读写和新建,Docker 采用插件式的方式支持多种Union FS实现,官方文档中一般使用stroage driver术语,目前已经有多种实现的插件, 比如: aufs、overlay、overlay2、devicemanger等等。

boot2docker 缺省使用的storage-driver 为 aufs,下面命令将创建一个使用 overlay2 的 storage driver docker运行环境。

docker-machine create --driver virtualbox --engine-storage-driver overlay2 test2

正式的docker 环境, 需要修改 /etc/docker/daemon.json 文件

{
"storage-driver": "btrfs"
}

几个查询storage driver的命令:

  • docker info:查询docker运行环境使用的storage-driver
  • docker image inspect:查看镜像使用的存储driver
  • docker container inspect :查看容器使用的存储driver

3.volume driver

volume driver 经常用来实现数据持久化和文件共享功能, 具体有两种存在方式,分别是:

3.1 bind mount方式

是将host的目录或文件直接mount到容器中, host的目录或文件既可以容器运行之前就已存在的,也可以是在容器运行之前不存在的。
如果在docker run 命令中采用了 -v /host/dir_or_file:/container/dir_or_file的形式, 就是bind mount方式,即指定了host的挂载点的绝对路径。

3.2 volume方式

是由 Docker 管理,该volume最终存储到host的 /var/lib/docker/volumes 下。 volume 方式还分为 named volume 和 Anonymous volume。named volume 有两种创建方法:

  • docker run命令中采用了 -v one_volume_name:/container/dir_or_file,这里的one_volume_name不是host中的绝对路径,而是一个名称。
  • 通过 docker volume create 创建的,该命令支持更多的选项, 推荐使用。

匿名volume方式 是通过 docker run 命令中传入了 -v /container/dir 类型的参数。

扫描二维码关注公众号,回复: 5031849 查看本文章

3.3 bind mount和volume对比

  • 1)bind mount方式, docker容器直接访问host的目录或文件,性能是最好的。

  • 2)bind mount方式, docker容器直接访问host的目录或文件,对于该host绝对目录可能会引入权限问题。 如果容器仅需要只读访问权限,最好是显式设定只读方式。

  • 3)对于 volume方式, 如果host中落地目录为空, docker先将容器中的对应目录复制到host下, 然后再进行挂载操作;对于bind mount方式,挂载之前没有复制操作。

容器要依赖host主机的一个绝对路径, 使得容器的移植性变差, docker 官方并不推荐bind mount, 而是推荐使用volume。
在这里插入图片描述
在这里插入图片描述
几个示例说明

 #创建了一个named volume, 该volume 在 /var/lib/docker/volume/myetc 下. 
docker run -d --name web0 -v myetc:/etc busybox /bin/sh -c "while true; do echo hello world; sleep 1; done" 

 #创建了一个匿名的volume, 该volume在/var/lib/docker/volume父目录下, 具体子目录不确定, 
 #比如 /var/lib/docker/volume/9170d32e15b7578240afde81d5514637beece7d469b7ea253e23759a23b0a397 
docker run -d --name web1 -v /etc busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"

 #使用 bind mount 方式, host上的目录为 /etc2 
docker run -d --name web2 -v /etc2:/etc busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"

docker run 命令的–volume 和 --mount 参数
–volume 和 --mount 两种参数写法都支持上述volume和bind mount方式, --mount 采用key-value的写法, 支持更多的设置选项, docker 新版更加推荐使用 --mount 参数写法,但 --volume 写法更加简洁,仍然给广泛使用。

另一种推荐的volume写法是, 显式地使用 docker volume create 命令创建 named volume。

有了上面的知识,很容易就能实现容器和Host之间共享数据。对于同一Host下多个容器共享数据,直接docker run -v参数非常不方便, 最好是使用 data container作为桥梁。一般data container 不启任何应用,也不需要将容器真正运行起来,仅仅是挂载一下 volume, data container除了用于多个容器之间数据共享之外,也可用于volume的备份和恢复。

data container和volume的备份恢复

#创建一个名 为 dbstore 的数据容器, 设置一个匿名的/dbdata volume. 
docker create -v /dbdata --name dbstore busybox /bin/sh 

#创建一个名为 web3 的应用容器, 将 dbstore 数据容器的volume 挂载过来. 
docker run -d --name web3 --volumes-from dbstore busybox /bin/sh -c "while true; do echo hello world; sleep 1; done"

#备份数据容器 dbstore 的/dbdata目录到容器到host的host_backup目录下, 最终在host上的文件名为 /host_backup/backup.tar
docker run --rm --volumes-from dbstore -v /host_backup:/backup busybox tar -cvf /backup/backup.tar /dbdata
 
#恢复数据容器dbstore 的/dbdata目录, 数据源为host上的文件 /host_backup/backup.tar
docker run --rm --volumes-from dbstore -v /host_backup:/backup busybox /bin/sh -c "cd /dbdata && tar -xvf /backup/backup.tar --strip 1"

docker的容器设计理念是可以即开即用,用完可以随意删除,而新建容器是根据镜像进行渲染,容器的修改是不会影响到镜像,但是有时候容器里面运行的产生的数据(如mysql)或者配置项(如nginx的nginx.conf)我们又需要保存起来的,因而我们需要对容器某些修改的数据进行挂载,也就是把这些数据持久化。

猜你喜欢

转载自blog.csdn.net/huangjun0210/article/details/86221924