1. Docker 卷结构

Docker 镜像是分层结构,联合挂载,镜像中各层的文件都是只读的,容器中所有文件对外可见的状态是多层叠加后的可见状态。因此对于IO性能要求较高的容器,如果使用Overlayfs会严重影响容器的性能。
另外,容器在生命周期结束的时候会被删除,对于有数据持久化要求的容器而言,容器运行中有价值的数据并需要存储在外部的逻辑卷中。如果由容器直接使用共享存储系统,那么每次容器启动后都需要挂载,而且还需要具备与外界通信的能力,不仅繁琐,而且损失性能。
针对这种需求,docker推出了卷管理系统,在容器创建时直接使用宿主机的存储系统,当容器结束运行时,不会删除卷中的数据。
image.png
如图中,宿主机将远程NFS服务器中的数据盘挂载到本地/data/目录下,创建httpd容器时,将本地的/data/盘映射到容器中的网站根目录:/data/html中。
当httpd容器挂掉后,无论在哪台服务器,只要满足宿主机挂载NFS存储,并且httpd容器映射网站根目录到/data/html即可。针对不需要持久化存储的应用,则可以不使用存储卷管理。
将宿主机上的目录挂载到容器中有两种方式:

  • Bind mount volume

手动指定宿主机目录和容器中目录的映射关系,或使用容器编排工具(k8s或者docker-compose)指定

  • Docker-managed volume

Docker自动管理的挂载关系,这种情况下宿主机目录不固定,后期维护成本高,仅用于存放一些临时数据


2. 案例

2.1. Docker-managed volume

  1. [root@centos-82 ~]# docker container run --name web01 -v /data/ -it --rm busybox:latest ## Create container by docker-managed volumes
  2. / # df -h | grep data
  3. /dev/sda3 15.5G 2.4G 13.1G 16% /data
  4. [root@centos-82 ~]# docker container inspect -f {{.Mounts}} web01 ## show volumes info
  5. [{volume e001f57178528126c1ae0dc4d4edbf1e0c797a903031f91f9fc8484efacd4183 /var/lib/docker/volumes/e001f57178528126c1ae0dc4d4edbf1e0c797a903031f91f9fc8484efacd4183/_data /data local true }]
  6. [root@centos-82 ~]# ls /var/lib/docker/volumes/e001f57178528126c1ae0dc4d4edbf1e0c797a903031f91f9fc8484efacd4183/_data
  7. / # echo 'docker-mananged volume' > /data/test.txt ## write data to volume in container
  8. [root@centos-82 ~]# cat /var/lib/docker/volumes/e001f57178528126c1ae0dc4d4edbf1e0c797a903031f91f9fc8484efacd4183/_data/test.txt
  9. docker-mananged volume
  10. [root@centos-82 ~]# echo 'host docker-managed volume' >> /var/lib/docker/volumes/e001f57178528126c1ae0dc4d4edbf1e0c797a903031f91f9fc8484efacd4183/_data/test.txt
  11. / # cat /data/test.txt
  12. docker-mananged volume
  13. host docker-managed volume

2.2. Docker-managed volume

[root@centos-82 ~]# docker run --name web01 -it --rm -v /data/website:/data/ busybox:latest ## Bind mount volume
/ # df -h | grep data
/dev/sda3                15.5G      2.4G     13.1G  16% /data
[root@centos-82 ~]# docker container inspect -f {{.Mounts}} web01
[{bind  /data/website /data   true rprivate}]

/ # echo 'bind mount volume' > /data/test.txt   ## Test
[root@centos-82 ~]# cat /data/website/test.txt
bind mount volume
[root@centos-82 ~]# echo 'host bind mount volume' >> /data/website/test.txt
[root@centos-82 ~]# cat /data/website/test.txt
bind mount volume
host bind mount volume
/ # cat /data/test.txt
bind mount volume
host bind mount volume
/ # exit ## Exit
[root@centos-82 ~]# cat /data/website/test.txt ## When container exit,the data also exist.
bind mount volume
host bind mount volume
[root@centos-82 ~]# docker run --name web01 -it --rm -v /data/website:/data/ busybox:latest ## Restart container
/ # cat /data/test.txt
bind mount volume
host bind mount volume