Docker应用程序数据管理与持久化
一、Docker数据持久化简介
默认情况下,container内部新创建文件或者修改文件,结果会保存在container的可读写层中,这意味着:当container消失时,与container一体的可读写层也一并消失,数据并没有持久化。并且,当一个container需要其它container中可读写层的数据时,取出操作非常困难。
官网介绍:https://docs.docker.com/storage/
1.1 Docker mount类型
无论选择哪种mount类型,从container内部看没有区别,它们都是目录或者文件。数据都是寄存在宿主机上,只不过具体位置有所区别,如下图:
(1)bind mount:将宿主机中的文件、目录mount到容器上。其上的数据可以被宿主机读写,可以被mount它的所有容器读写。
(2)volume:volume由docker管理,比如创建、删除等。默认情况下,volume的存储空间来自于宿主机文件系统中的某个目录,如/var/lib/docker/volumes/,docker系统之外的程序不应该修改其中的数据。volume是官方推荐的持久化方案。
(3)tmpfs mount:tmpfs类型文件与普通文件的区别是只存在于宿主机内存中,不会持久化。
1.2 volume适用场景
(1)多个容器这间共享数据
(2)宿主机不保证存在固定的目录结构
(3)持久化数据到远程主机或者云存储而非本地
(4)需要备份、迁移、合并数据时。停止container,将volume整体复制,用于备份、迁移、合并等。
1.3 bind mount适用场景
(1)container共享宿主机配置文件。比如docker会将宿主机文件/etc/resov.conf文件bind mount到容器上,两者会使用相同的DNS服务器。
(2)开发环境中宿主机与container之间共享源代码、构建构件等。比如将整个build过程container化,将宿主机上的源代码文件夹bind mount到build container中。修改代码后,运行build container的build命令,build container则将build结构写入另一个bind mount的文件夹中。
(3)一些监控类container,通过读取宿主机固定文件中的数据实现监控等。
二、Volume和Bind Mount实施
2.1 Volume
(1)创建一个nginx用的逻辑卷,卷名为nginx-vol
[root@docker ~]# docker volume create nginx-vol
(2)查看成功创建的逻辑卷
[root@docker ~]# docker volume ls DRIVER VOLUME NAME local nginx-vol
(3)列出nginx-vol卷的的详细信息
[root@docker /]# docker volume inspect nginx-vol [ { "CreatedAt": "2018-09-24T06:24:17+08:00", # 创建时间 "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/nginx-vol/_data", # 挂载点 "Name": "nginx-vol", # 卷名 "Options": {}, "Scope": "local" } ]
(4)创建容器去使用该卷(将容器网站的根目录挂载到宿主机创建的卷上),持久化使用
[root@docker /]# docker run -itd --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx b5c711716c529f9df922723bfba924f46d1c51bf940627fc59cde42ba75eebf4
(5)进入容器,在容器上修改挂载点数据和宿主机挂载点进行对比
[root@docker /]# docker exec -it nginx-test bash root@b5c711716c52:/# cd /usr/share/nginx/html/ root@b5c711716c52:/usr/share/nginx/html# ls 50x.html index.html [root@docker /]# ls /var/lib/docker/volumes/nginx-vol/_data/ 50x.html index.html
(6)显示所有容器的ID
[root@docker /]# docker ps -q -a b5c711716c52 001b4647a2d9
(7)删除所有的容器
[root@docker /]# docker rm -f $(docker ps -q -a)
(8)创建容器,并挂载卷,暴露端口,进行网页访问测试
[root@docker /]# docker run -itd --name nginx-test -p 88:80 --mount src=nginx-vol,dst=/usr/share/nginx/html nginx b3698f36bff7ec9788c91de65effeaf611993ee34fdd66e9a7ccead7b39940fe [root@docker ~]# docker exec -it nginx-test bash root@b3698f36bff7:/# cd /usr/share/nginx/html/ root@b3698f36bff7:/usr/share/nginx/html# touch 1.html root@b3698f36bff7:/usr/share/nginx/html# echo nginx >1.html
【注】如果创建100个nginx容器,使用同一个数据卷,就实现了数据共享。
(9)如果不指定卷名,系统会默认创建一个数据卷,随机生成一个卷名
[root@docker ~]# docker run -itd --name=nginx-test1 -p 89:80 --mount src=,dst=/usr/share/nginx/html nginx e0f572dba6d17415a8050734031459a9f71d489e1c606bbc4abf41c50192ae42 [root@docker ~]# docker volume ls
注意事项:
. 如果没有指定卷,自动创建。
. 建议使--mount,更通用。
官方文档:https://docs.docker.com/engine/admin/volumes/volumes/#start-a-container-with-a-volume
2.2 Bind mount
(1)创建容器在宿主机上的挂载点
[root@docker /]# mkdir -p /app/wwwroot
(2)创建容器挂载类型为bind,并指向自定义的宿主机挂载点。
【注】左边是Host路径,右边是容器内的路径。
方法一:
[root@docker /]# docker run -itd --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx 567313bf91919c4f3e0c2b3b541b413630d16ee916f63408f955aeb9a6cccabc
方法二:
[root@docker /]# docker run -d -it --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx
(3)进入容器,查看挂载情况
[root@docker /]# docker exec -it nginx-test bash root@567313bf9191:/# ls /usr/share/nginx/html/
【注意】使用bind挂载后,容器中挂载点文件会被隐藏,宿主机挂载点如果有数据会直接显示。
注意事项:
.如果源文件/目录没有存在,不会自动创建,会抛出一个错误。
.如果挂载目标在容器中非空目录,则该目录现有内容将被隐藏。
官方文档:https://docs.docker.com/engine/admin/volumes/bind-mounts/#start-a-container-with-a-bind-mount
作者:UStarGao
链接:https://www.starcto.com/docker/107.html
来源:STARCTO
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
UCloud云平台推荐
随便看看
- 2021-08-22Smokeping+Promethues+Grafana搭建网络质量监控
- 2021-01-27数据库宕机以后恢复的过程?如何保证事务的ACID特性?
- 2023-03-12Linux pstree命令树状图方式查看进程
- 2021-03-20Dockerfile构建容器镜像,搭建LNMP网站平台
- 2021-02-21Docker创建与查看容器常用参数解读