docker容器技术及管理(详解docker容器数据持久化和数据共享)
docker 主要有两种数据存储形式, 一种是storage driver(也叫做 Graph driver), 另一种是 volume driver. stroage driver主要是存储那些无状态的数据, 写入密集型的场景应该使用 volume driver.
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.
volume drivervolume driver 经常用来实现数据持久化和文件共享功能, 具体有两种存在方式, 分别是:
1. bind mount 方式:
是将host的目录或文件直接mount到容器中, host的目录或文件既可以容器运行之前就已存在的, 也可以是在容器运行之前不存在的.
如果在docker run 命令中采用了 -v /host/dir_or_file:/container/dir_or_file的形式, 就是bind mount方式, 即指定了host的挂载点的绝对路径.
2. volume 方式
是由 Docker 管理, 该volume最终存储到host的 /var/lib/docker/volumes 下. volume 方式还分为 named volume 和 Anonymous volume.
named volume 有两种创建方法,
(1) docker run 命令中采用了 -v one_volume_name:/container/dir_or_file , 这里的one_volume_name不是host中的绝对路径, 而是一个名称.
(2) 通过 docker volume create 创建的, 该命令支持更多的选项, 推荐使用.
匿名volume方式 是通过 docker run 命令中传入了 -v /container/dir 类型的参数.
3. bind mount 方式和volume方式的简单对比:
bind mount方式, docker容器直接访问host的目录或文件, 性能是最好的.
bind mount方式, docker容器直接访问host的目录或文件, 对于该host绝对目录可能会引入权限问题. 如果容器仅需要只读访问权限, 最好是显式设定只读方式.
对于 volume方式, 如果host中落地目录为空, docker先将容器中的对应目录复制到host下, 然后再进行挂载操作; 对于bind mount方式, 挂载之前没有复制操作.
容器要依赖host主机的一个绝对路径, 使得容器的移植性变差, docker 官方并不推荐这个方法, 而是推荐使用volume.
几个示例说明:
docker run -d --name web0 -v myetc:/etc busybox /bin/sh -c "while true; do echo hello world; sleep 1; done" #创建了一个named volume, 该volume 在 /var/lib/docker/volume/myetc 下. docker run -d --name web1 -v /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 web2 -v /etc2:/etc busybox /bin/sh -c "while true; do echo hello world; sleep 1; done" #使用 bind mount 方式, host上的目录为 /etc2
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)我们又需要保存起来的,因而我们需要对容器某些修改的数据进行挂载,也就是把这些数据持久化。
后面会分享更多关于devops和DBA内容,感兴趣的朋友可以关注下!!
,
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com