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 文件, 具体参考选用btrfs driver的官方文档 https://docs.docker.com/storage/storagedriver/btrfs-driver/#configure-docker-to-use-the-btrfs-storage-driver
{
"storage-driver": "btrfs"
}
对于不同的Linux发行版的主机, 官方有一些推荐说明:
https://docs.docker.com/storage/storagedriver/select-storage-driver/
https://success.docker.com/article/compatibility-matrix
对于CentOS 7推荐使用 overlay2, 可参考 https://blog.csdn.net/lusyoe/article/details/80208260 ,


几个查询storage driver的命令:
docker info 命令, 查询docker运行环境使用的storage-driver.
docker image inspect 命令,查看镜像使用的存储driver.
docker container inspect 命令,查看容器使用的存储driver.

======================
volume driver
======================
volume 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, 更多信息见官方文档: https://docs.docker.com/engine/reference/commandline/volume_create/#usage

有了上面的知识, 很容易就能实现容器和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 daemon 下的容器, When containers are placed in the same network, they are reachable by each other using their container name and other alias as host.
https://stackoverflow.com/questions/35832095/difference-between-links-and-depends-on-in-docker-compose-yml

======================
参考
======================
http://www.cnblogs.com/sammyliu/p/5932996.html
http://www.cnblogs.com/lkun/p/7750629.html
https://blog.csdn.net/lusyoe/article/details/80208260

原文地址:https://www.cnblogs.com/harrychinese/p/docker_storage_and_volume.html