6.Docker数据持久化
通过网盘分享的文件MD文档笔记链接: https://pan.baidu.com/s/1ao2wfyLEdN50YmIqdzfGYQ?pwd5w5z 提取码: 5w5z–来自百度网盘超级会员v6的分享在容器层的 UnionFS(联合文件系统)中对文件/目录的任何修改,无论是手工修改还是容器在运行过程中的修改,在该容器丢失或被删除后这些修改将全部丢失(即这些修改是无法保存下来的)若要保存下来这些修改通常有以下方式定制镜像持久化将这个修改过的容器生成一个新的镜像,让这些修改变为只读的镜像应用场景对 UnionFS 产生一次性变化,且这种变化易于持久化为镜像不适合变更非常频繁的实时性场景数据卷持久化将这些修改通过数据卷同步到宿主机数据卷属于宿主机文件系统,与 UnionFS 是挂载关系,与容器挂载点是硬链接关系.容器的存在与否与数据卷没有关系数据卷持久化可以做到对容器变更的实时性持久化,不会出现数据丢失的情况Dockerfile持久化理解 docker run –v 方式与 Dockerfile 的VOLUME 指令方式指定数据卷的区别docker run –v方式是针对已经存在的镜像的,而 Dockerfile 的VOLUME 指令方式是针对准备创建的镜像的docker run –v方式可以指定宿主机中的数据卷目录,而 Dockerfile 的VOLUME 指令方式无法指定宿主机中的数据卷目录,其是 Docker Daemon 自动分配的所以对于用户来说通过docker run –v方式来指定数据卷会更为清晰明了些一.定制镜像持久化1.需求这里要实现的功能是为 tomcat:10.0 镜像修改其 webapps 目录这是因为新版本的tomcat目录结构发生了变化,webapps 目录变成了空目录,而原先的webapps目录中的内容放到了webapps.dist 目录中,因此用户访问tomcat 页面会报 404现要将原 webapps 目录删除,然后重命名 webapps.dist 目录为 webapps,以使用户可以看到 tomcat页面2.实现(1).运行 tomcat 容器首先以分离模式启动 tomcat 容器dockerrun--namemytomcat-dp8081:8080 tomcat:10.0此时通过浏览器是无法访问到 tomcat 页面的http://192.168.1.11:8081/(2).进入容器后删除目录通过 docker exec 命令可以进入到容器命令行,可以看到 webapps 目录是空的而真正需要的内容在webapps.dist 目录中dockerexec-itmytomcat /bin/bash删除 webapps 目录,然后将 webapps.dist 目录重命名为 webappsrm-rfwebapps/mvwebapps.dist webapps此时刷新浏览器就可以看到 tomcat 页面了(3).容器生成镜像重新开启会话或者CTRLPQ退出容器执行 docker commit 命令,以当前运行的容器为模版生成镜像-m 指定本次提交的日志tomcat10:own 为新镜像的repository:tag此时可以看到已经生成dockercommit-mmodify webappsmytomcat tomcat10.0:own(4).测试新镜像dockerrun--nameowntomcat-dp9000:8080 tomcat10.0:own通过浏览器可以直接访问到 tomcat 页面二.数据卷持久化Docker 提供了三种实时同步(宿主机与容器 FS 间数据的同步)方式数据卷Bind mounts(绑定挂载)tmpfs(临时文件系统)1.数据卷概述(1).Docker的理念将应用与运行的环境打包形成容器运行, Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了但是我们对数据的要求希望是持久化的、容器之间希望有可能共享数据为了能保存数据在docker中我们使用数据卷(2).什么是数据卷数据卷是宿主机中的一个特殊的文件/目录,这个文件/目录与容器中的另一个文件/目录进行了直接关联,在任何一端对文件/目录的写操作,在另一端都会同时发生相应变化在宿主中的这个文件/目录就称为数据卷,而容器中的这个关联文件/目录则称为该数据卷在该容器中的挂载点数据卷的设计目的就是为了实现数据持久化,其完全独立于容器的生命周期,属于宿主机文件系统,但不属于 UnionFS因此容器被删除时不会删除其挂载的数据卷(3).数据卷的特性数据卷具有如下明显特性数据卷在容器启动时初始化如果容器启动后容器本身已经包含了数据,那么这些数据会在容器启动后直接出现在数据卷中,反之亦然可以对数据卷或挂载点中的内容直接修改,修改后对方立即可看到数据卷会一直存在,即使挂载数据卷的容器已经被删除数据卷可以在容器之间共享和重用(4).容器数据卷能做什么容器数据的持久化容器之间继承和共享数据2.创建数据卷2.1.创建只读数据卷2.1.1.只读数据卷简介只读数据卷指的是容器对挂载点的操作权限是只读的,宿主机对数据卷的操作权限始终是读写的有些情况下为了防止容器在运行过程中对文件产生修改就需要创建只读数据卷具体语法如下dockerrun –it –v /宿主机目录绝对路径:/容器内目录绝对路径:ro 镜像2.1.2.使用示例(1).创建数据卷以交互方式启动一个 ubuntu 容器,同时指定在启动容器时创建只读数据卷dockerrun--namemyubuntu-it-v/home/host_mount:/opt/uc_mount:ro ubuntu:latest /bin/bash(2).数据卷/挂载点互操作在容器中修改挂载点中的文件,系统会给出只读文件系统的提示,说明容器对数据卷是只读的cd/opt/uc_mount/echohello worldhello.log宿主机中对数据卷文件的修改是成功的CTRLPQ退出容器cd/home/host_mount/echohello worldhello.log在容器中同样也是可以看到宿主机中的修改的dockerexec-itmyubuntuls-l/opt/uc_mount(3).查看数据详情通过 docker inspect [容器] 命令可以查看到该数据卷的只读属性dockerinspect myubuntu2.2.创建读写数据卷2.2.1.读写数据卷简介读写数据卷指的是容器对挂载点具有读写权限数据卷是在使用 docker run 启动容器时指定的其语法格式为dockerrun –it –v /宿主机目录绝对路径:/容器内目录绝对路径 镜像注:无论是宿主机中的数据卷还是容器中的挂载点,如果指定的目录不存在,那么 docker引擎都会自动创建(即使是多级目录不存在)2.2.2.读写数据卷示例需求:在宿主机中的/root/host_mount 目录与 ubuntu 容器的/opt/uc_mount 目录间建立关联,即宿主机中的/root/host_mount 目录作为数据卷,而 ubuntu 容器的/opt/uc_mount 目录作为挂载点(1).创建数据卷以交互方式启动一个 ubuntu 容器,同时指定在启动容器时创建数据卷容器启动完毕后在容器中查看/opt 目录,可以看到新建了一个 uc_mount 子目录,这个就是容器中的挂载点目录dockerrun--namemyubuntu-it-v/root/host_mount:/opt/uc_mount ubuntu:latest /bin/bashls-l/opt再打开一个会话窗口,查看宿主机的/root 目录,可以看到新建了一个 host_mount 目录,这个就是数据卷目录(2).数据卷/挂载点互操作宿主机数据卷目录与容器挂载点目录中进行文件修改互操作,修改完毕后,对方都可立即看到修改在宿主机数据卷目录中创建一个新的文件echohello world/root/host_mount/hello.logls-l/root/host_mount/在容器中可以查看到该文件出现了ls-l/opt/uc_mount/在容器中对文件内容进行修改echocontainer modify/opt/uc_mount/hello.log在宿主机中可以查看到该修改过的文件内容cat/root/host_mount/hello.log(3).停止容器后的操作即使容器停止了,在宿主机中只要修改了数据卷目录内容,在重新启动容器后,该修改过的数据仍会出现在容器中因为容器是一个 UnionFS,是一个存在于宿主机中的文件系统,无论容器是否运行,该 FS 都是存在的通过exit 退出并停止容器exit在宿主机数据卷目录修改文件echohost modify/root/host_mount/hello.log重新启动并进入容器,查看容器中挂载点目录中的文件内容,发现已发生改变dockerstart myubuntudockerexec-itmyubuntu /bin/bashcat/opt/uc_mount/hello.log(4).查看数据卷详情通过 docker inspect [容器] 命令可以查看到当前容器中挂载点与数据卷的绑定关系dockerinspect myubuntu这里给出了数据卷 Source 与挂载点 Destination 的绑定关系,且容器对挂载点的默认操作权限是 RW 读写的3.数据卷容器3.1.什么是数据卷容器当一个容器与另一个容器使用相同的数据卷时就称这两个容器实现了数据卷共享数据卷容器是实现数据卷共享的一种非常有效的方案如果有一些持续更新的数据需要在容器之间共享最好创建数据卷容器当一个容器 C 启动运行时创建并挂载了数据卷,若其它容器也需要共享该容器 C 挂载的数据卷,这些容器只需在docker run启动时通过--volumes-from[容器 C]选项即可实现数据卷共享,此时容器C 就称为数据卷容器如果删除了挂载的容器(包括 dbdata、db1 和 db2),数据卷并不会被自动删除如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用docker rm -v命令来指定同时删除关联的数据卷3.2.创建数据卷容器需求:myubuntu2 容器要共享myubuntu1 容器的数据卷,即宿主机中/root/host_mount为数据卷目录,而这两个容器的挂载点目录都是/opt/uc_mount(1).创建容器1的数据卷dockerrun--namemyubuntu-it-v/root/host_mount:/opt/uc_mount ubuntu:latest /bin/bashls-l/opt# 进入挂载点目录/opt/uc_mountcd/opt/uc_mount/(2).创建容器2这里在创建并运行myubuntu2 容器时,使用–volumes-from 指定该容器要共享myubuntu的数据卷,即指定myubuntu 容器为数据卷容器此时可以发现myubuntu2 容器中也同样出现了挂载点目录/opt/uc_mount# 创建容器dockerrun--namemyubuntu2 --volumes-from myubuntu-itubuntu:latest /bin/bash# 进入目录cd/opt/uc_mount/(3).数据卷共享操作经过上述操作,myubuntu1 与 myubuntu2 这两个容器实现了数据卷共享此时无论是在宿主机,还是 myubuntu1 或 myubuntu2 任意容器中挂载点目录中的任意写操作,在另外两方均可同步看到该写操作的结果下面举例首先在宿主机数据卷目录中创建一个文件 data.logecho你好世界/root/host_mount/data.log在 myubuntu1 容器中可以查看到 data.log 文件然后myubuntu1 容器也修改该文件# 进入容器,如果是多窗口操作则不需要该步骤dockerexec-itmyubuntu /bin/bash# 查看文件cat/opt/uc_mount/data.log# 容器1修改文件echomyubuntu1 modify/opt/uc_mount/data.log在 myubuntu2 容器中可以查看到 data.log 文件然后myubuntu2 容器也修改该文件# 进入容器,如果是多窗口操作则不需要该步骤dockerexec-itmyubuntu2 /bin/bash# 查看文件cat/opt/uc_mount/data.log# myubuntu2 容器对文件的修改echomyubuntu2 modify/opt/uc_mount/data.log在 myubuntu1 容器中可看到cat/opt/uc_mount/data.log在宿主机中可看到cat/root/host_mount/data.log三.DockerFile持久化Dockerfile 持久化就是通过使用 Dockerfile 的 VOLUME 指令指定数据卷方式实现的持久化VOLUME 指令可以在容器中创建可以挂载数据卷的挂载点其参数可以是字符串数组,也可以是使用空格隔开的多个纯字符串例如VOLUME[/var/www,/etc/apache]或VOLUME /var/www /etc/apache1.创建 Dockerfile在/root目录中mkdir一个目录vols(例如vols),然后在其中新建 Dockerfile,内容如下这里指定/opt/xxx 与/opt/ooo 为容器端的挂载点[rootdocker ~]# cd /root[rootdocker ~]# mkdir vols[rootdocker ~]# cd vols/[rootdocker ~]# vim DockerfileFROM ubuntu VOLUME /opt/xxx /opt/ooo CMD /bin/bash2.构建镜像 build使用 Dockerfile 构建镜像 volscon:latestdockerbuild-tvolscon.3.运行新建镜像以交互方式运行新建镜像dockerrun--namemyvols-itvolscon ll /opt/4.查看宿主机端目录重新开启一个会话(Ctrl P Q 退出容器后,使用 docker inspect 查看当前容器中的挂载点目录到底与宿主机中的哪个数据卷对应)dockerinspect myvols5.验证在容器端首先进入/opt/xxx 目录,并在其中新建一个文件 hello.logdockerexec-itmyvols /bin/bashcd/opt/xxxechohello worldhello.log在宿主机端,从 docker inspcet 命令中找到/opt/xxx 目录对应的数据卷Source 目录,首先进入到该目录,然后就可以查看到对应的 hello.log 文件了说明数据卷设置成功,可以实现从容器到数据卷的持久化了cd/root/images/volumes/b0a468e52fe84b0faf6838e7c50dcccc3e9bb8f5a9b7ac8ef372f14f9010658a/_datacathello.log在宿主机端修改文件内容,在容器端同样也是可以看到的这里不再演示