应用服务是在容器中运行的,容器随时会被删除,如果是个mysql容器呢?数据存储在容器里,容器删除了,数据也没了,那就是个噩梦。 所以一些数据是需要存储在容器之外的,可以是宿主机,可以是网络存储位置上,目的是为了数据能保留下来,这就是数据的持久化。
接下来,我们了解一下,如何将容器中需要持久化的数据,持久化到容器之外的位置。
Docker提供三种方式将数据从宿主机挂载到容器中:
• volumes:Docker管理宿主机文件系统的一部分(/var/lib/docker/volumes)。保存数据的最佳方式。
• bind mounts:将宿主机上的任意位置的文件或者目录挂载到容器中。
• tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久存储在任何位置,可以使用
tmpfs,同时避免写入容器可写层提高性能。
下面的实验,我们做前2种方式:
#列出volume [root@192 /]# docker volume ls DRIVER VOLUME NAME #查看docker volume 帮助 [root@192 /]# docker volume --help Usage: docker volume COMMAND Manage volumes Commands: create Create a volume inspect Display detailed information on one or more volumes ls List volumes prune Remove all unused local volumes rm Remove one or more volumes Run 'docker volume COMMAND --help' for more information on a command. # 先测试通过docker volume创建卷,并关联给容器使用。这个卷里保存容器的持久化数据 #新建一个卷,卷名=nginx-vol [root@192 /]# docker volume create nginx-vol nginx-vol #列出volume,确认卷创建成功 [root@192 /]# docker volume ls DRIVER VOLUME NAME local nginx-vol #查看卷详细信息 [root@192 /]# docker volume inspect nginx-vol [ { "CreatedAt": "2019-03-14T12:44:04+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/nginx-vol/_data", "Name": "nginx-vol", "Options": {}, "Scope": "local" } ] #进入nginx-vol卷文件存储目录 [root@192 /]# cd /var/lib/docker/volumes/nginx-vol/_data #列出当前目录下文件 [root@192 _data]# ls #列出当前存在的镜像文件 [root@192 _data]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 881bd08c0b08 9 days ago 109MB busybox latest d8233ab899d4 3 weeks ago 1.2MB centos 7 1e1148e4cc2c 3 months ago 202MB centos latest 1e1148e4cc2c 3 months ago 202MB java 8 d23bdf5b1b1b 2 years ago 643MB #列出最近的容器 [root@192 _data]# docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5e67c2448806 nginx "nginx -g 'daemon of…" 2 days ago Up 3 hours 0.0.0.0:8800->80/tcp trusting_banach #停止指定容器 [root@192 _data]# docker container stop 5e67c2448806 5e67c2448806 [root@192 _data]# docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES #启动指定容器 [root@192 _data]# docker container start 5e67c2448806 5e67c2448806 #停止指定容器 [root@192 _data]# docker container stop 5e67c2448806 5e67c2448806 #启动一个容器,--mount src=nginx-vol,dst=/usr/share/nginx/html 将宿主机的nginx-vol卷,挂在到容器中的 /usr/share/nginx/html目录 # docker volume特点,volume和容器中数据实时同步了,不论在那端修改了数据,会实时同步,2边数据会保持一致。 删除volume时,如果有关联的容器存在(停止和运行状态),那么无法删除volume. 只有移除容器,volume才能被删除 [root@192 _data]# docker container run -d --mount src=nginx-vol,dst=/usr/share/nginx/html -p 8800:80 nginx 6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2 [root@192 _data]# docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6886984c9b2d nginx "nginx -g 'daemon of…" 31 seconds ago Up 30 seconds 0.0.0.0:8800->80/tcp eloquent_jackson #进入nginx-vol卷 [root@192 _data]# cd /var/lib/docker/volumes/nginx-vol/_data #查看是否存在文件,发现2个文件 [root@192 _data]# ls 50x.html index.html #进入容器 [root@192 _data]# docker container exec -it 6886984c9b2d bash #进入dst目录 root@6886984c9b2d:/# cd /usr/share/nginx/html/ #列出文件,发现源和目标文件时一致的,测试在源和目标修改index.html,都会生效 root@6886984c9b2d:/usr/share/nginx/html# ls 50x.html index.html root@6886984c9b2d:/usr/share/nginx/html# cat index.html <h1>Welcome to volume test!</h1> root@6886984c9b2d:/usr/share/nginx/html# echo 'This modify is in container'>index.html root@6886984c9b2d:/usr/share/nginx/html# cat index.html This modify is in container root@6886984c9b2d:/usr/share/nginx/html# exit exit [root@192 _data]# cd / #下面测试在容器运行中删除卷,删除卷失败。 [root@192 /]# docker volume rm nginx-vol Error response from daemon: remove nginx-vol: volume is in use - [6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2] #下面测试在容器状态时停止时删除卷,删除卷失败。 [root@192 /]# docker container stop 6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2 6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2 [root@192 /]# docker volume rm nginx-vol Error response from daemon: remove nginx-vol: volume is in use - [6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2] [root@192 /]# docker container ps -qa 6886984c9b2d 5e67c2448806 [root@192 /]# docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES #下面测试,删除容器后,删除卷,卷删除成功 [root@192 /]# docker container rm 6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2 6886984c9b2df1dec674abb72a659e02d6a98afbb11dccdddb926571b08085b2 [root@192 /]# docker volume rm nginx-vol nginx-vol [root@192 /]# docker volume ls DRIVER VOLUME NAME # 下面测试数据持久化的第2种方式:bind mount ,可以将宿主机的任意文件位置挂载到容器的任意位置,容器中的路径下如果存在文件,这些文件将会被隐藏 # 新建目录 wwwroot [root@192 /]# mkdir wwwroot # 启动一个容器,--mount type=bind,src=$PWD/wwwroot,dst=/usr/share/nginx/html, 将宿主机src目录,挂在到容器/usr/share/nginx/html的目录 [root@192 /]# docker container run -d -p 8900:80 --mount type=bind,src=$PWD/wwwroot,dst=/usr/share/nginx/html nginx dbc6252103716d58aa7897919e98025e51972149246b9f078304a3e26ce8d6a0 # 查看宿主机wwwroot目录下,不存在文件 [root@192 /]# ls wwwroot/ [root@192 /]# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var wwwroot # 查看容器/usr/share/nginx/html的目录下,不存在文件; [root@192 /]# docker container exec -it dbc6252103716d58aa7897919e98025e51972149246b9f078304a3e26ce8d6a0 bash root@dbc625210371:/# cd /usr/share/nginx/html/ root@dbc625210371:/usr/share/nginx/html# ls root@dbc625210371:/usr/share/nginx/html# exit exit # 在宿主机wwwroot目录下,创建文件 [root@192 /]# cd wwwroot/ [root@192 wwwroot]# ls [root@192 wwwroot]# touch index.html [root@192 wwwroot]# vi index.html # 进入容器,查看是否存在文件,观察到也存在文件了 [root@192 wwwroot]# docker container exec -it dbc6252103716d58aa7897919e98025e51972149246b9f078304a3e26ce8d6a0 bash root@dbc625210371:/# cd /usr/share/nginx/html/ root@dbc625210371:/usr/share/nginx/html# ls index.html # 在容器中创建文件 root@dbc625210371:/usr/share/nginx/html# touch a.out root@dbc625210371:/usr/share/nginx/html# exit exit # 在宿主机观察到,在容器中创建的文件存在,说明在2边的操作,会互相同步。 [root@192 wwwroot]# ls a.out index.html
总结:
Volume特点:
• 多个运行容器之间共享数据。
• 当容器停止或被移除时,该卷依然存在。
• 多个容器可以同时挂载相同的卷。
• 当明确删除卷时,卷才会被删除。
• 将容器的数据存储在远程主机或其他存储上
• 将数据从一台Docker主机迁移到另一台时,先停止容器,然后备份卷的目录(/var/lib/docker/volumes/)
Bind Mounts特点:
• 从主机共享配置文件到容器。默认情况下,挂载主机/etc/resolv.conf到每个容器,提供DNS解析。
• 在Docker主机上的开发环境和容器之间共享源代码。例如,可以将Maven target目录挂载到容器中,每次在Docker主机
上构建Maven项目时,容器都可以访问构建的项目包。
作者: 梅梅~
出处: https://www.cnblogs.com/keeptesting
关于作者:专注软件测试,测试运维相关工作,请多多赐教!
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 欢迎博客园朋友加微信联系。 微信:yangguangkg20140901 暗号:博客园.