????是时候了解Docker如何管理数据了。本节主要说明持久化和非持久化,着重持久化
????数据存储分为两类,持久化和非持久化。
????????● 持久化数据是需要保存的数据,例如客户的信息、财务、审计日志等
????????● 非持久化数据是不需要保存的数据
????每个Docker容器都有自己的非持久化存储,非持久化存储自动创建,从属于容器,生命周期与容器相同。这意味着删除容器也会删除全部非持久化数据。简要说服务应用删除、重启后数据丢失,一般在内存缓存中的数据在服务重启后会丢失
????如果需要自己的容器数据保留下来,则需要将数据存储在卷上。卷与容器是解耦的,从而可以独立的创建并管理卷,并且卷并未与任何容器生命周期绑定。简要说就是把服务应用删除、停止、重启后历史的数据还会存在,以文件形式存储在磁盘上
????????●?非持久化数据是在容器内部应用的缓存中,与容器生命周期为一体
????????● 持久化数据与容器是相互隔离状态,不随容器状态的改变而改变
二. 数据持久化实现方式????● volume
????????docker自身管理的一种数据持久化方式
????● mount bind
????????数据由人为自定义管理的一种方式
????下面将对2种持久化做一个演示
????1. 如何去查看容器的存储路径
????????Docker自身提供了"docker volume ls"的指令查看数据卷
????????第二列"VOLUME NAME"为数据存储目录名称,第一眼看很懵,数据存储对应的是那个容器?如果数据量过小可以使用"find"指令去查到关键文件从而获得容器数据存储路径,当数据量过大时使用"find"不太现实
? ? 2. 如何去自定义容器的存储路径
????? ? Docker提供了"-v"参数来自定义容器卷名称,示范如下
????????可以看到,在"volumes"目录下,docker自身创建了"test_volume/_data"目录,并且nginx主页文件"index.html"、"50x.html"也在这个目录下。说明容器内的文件会自动迁移到主机数据存储目录中
? ? ? ? -v:host_dirname:container_dirname
????????????注意:host_dirname 不需要写绝对路径,只需指明单独一个目录即可,会将数据统一存储在docker自身的数据管理目录下
????????这里数据存储路径命名得有规范性,若是随意命名有可能导致环境混乱,笔者建议按照服务的名称或者是提供业务去命名
? ? 3. 数据卷共享
? ? ? ? 创建一个实例"nginx-volume-test1"
??????????在本地创建一个"test.html"的文件并访问
echo?"nginx?data?volume?test"?>?test.html?&&?chmod?644?test.html #?本地请求 [root@doc03?_data]#?curl?10.125.7.74:9999/test.html nginx?data?volume?test [root@doc03?_data]#?curl?10.125.7.74:8888/test.html nginx?data?volume?test????????注意:这里得注意文件权限644
? ? 4. 数据卷持久化
????? ? 删除实例"nginx-volume-test2"
[root@doc03?~]#?docker?stop?nginx-volume-test2 nginx-volume-test2 [root@doc03?~]#?docker?rm?nginx-volume-test2 nginx-volume-test3 [root@doc03?~]#?tree?/opt/app/Docker/volumes/test-volume /opt/app/Docker/volumes/test-volume └──?_data ????├──?50x.html ????└──?index.html ????└──?test.html????? ? 查看"test-volume"数据目录,文件并未被删除
????????注意:这里得说明下"/opt/app/Docker/volumes/metadata.db"这个文件,metadata.db,存储路径的元数据并不是动态更新修改,当目录已经创建并关联的容器删除时,其他新建的容器无法使用已经创建过的这个目录,需要手动删除历史使用过的目录,可使用"docker volume --help"查看具体使用方式
五. mount bind持久化????与"volume"不同的是,此方式用户可以自定义数据挂载路径
????docker run -d -v host_path:container_path ······
? ? 1. 自定义数据存储路径
[root@doc03?Docker]#?pwd /opt/app/Docker [root@doc03?Docker]#?tree?Container_data/ Container_data/ 0?directories,?0?files? ? 2. 实例化一个容器? ??
[root@doc03?Docker]#?docker?run?-d?--name?nginx-volume-test10?-p?33333:80?-v?//opt/app/Docker/Container_data/nginx-volume-test10:/usr/share/nginx/html?nginx:v1 2b2a7e4b05b4d0bdefa9f4b6ad32c40a7beadbcbca216bac42103518b97b427b [root@doc03?Docker]#?tree?Container_data/ Container_data/ └──?nginx-volume-test10 1?directory,?0?files [root@doc03?Docker]#?tree?Container_data/nginx-volume-test10/ Container_data/nginx-volume-test10/????????"nginx-volume-test10"数据存储目录自动创建,且目录下不存在nginx主页文件"50x.html"、"index.html"
? ? 3. 多容器数据卷共享
????????创建一个nginx-volume-test11的实例,共享"nginx-volume-test10"文件系统
????????在这里可以使用"inspect"去核查2个容器之间数据目录是否共享
[root@doc03?Docker]#?pwd /opt/app/Docker #?"nginx-volume-test11"使用了"ro"只读模式 [root@doc03?Docker]#?docker?run?-d?--name?nginx-volume-test11?-p?44444:80?-v?/opt/app/Docker/Container_data/nginx-volume-test10:/usr/share/nginx/html:ro?nginx:v1 ca310b2e5076a7340aaa43e1a7737306ce53ffb7dd8d14f90114b3156e467106????????在宿主机上创建访问主页
[root@doc03?Docker]#?echo?"volume?shard?test"?>?Container_data/nginx-volume-test10/index.html [root@doc03?Docker]#?chmod?644?Container_data/nginx-volume-test10/index.html????????进入"nginx-volume-test10"并追加"test10"内容,通过"nginx-volume-test10"、"nginx-volume-test11"访问主页
[root@doc03?Docker]#?docker?exec?-it?nginx-volume-test10?/bin/bash root@2b2a7e4b05b4:/#?cd?/usr/share/nginx/html/ root@2b2a7e4b05b4:/usr/share/nginx/html#?ls index.html root@2b2a7e4b05b4:/usr/share/nginx/html#?echo?"test10?add?content"?>>?index.html? root@2b2a7e4b05b4:/usr/share/nginx/html#?cat?index.html root@2b2a7e4b05b4:/usr/share/nginx/html#?exit exit [root@doc03?Docker]#?curl?http://10.125.7.74:33333 volume?shard?test test10?add?content [root@doc03?Docker]#?curl?http://10.125.7.74:44444 volume?shard?test test10?add?content????????进入"nginx-volume-test11"尝试追加内容
[root@doc03?Docker]#?docker?exec?-it?nginx-volume-test11?/bin/bash root@ca310b2e5076:/#?cd?/usr/share/nginx/html/ root@ca310b2e5076:/usr/share/nginx/html#?echo?1?>?index.html? bash:?index.html:?Read-only?file?system????????"nginx-volume-test10"、"nginx-volume-test11"测试说明数据已经共享,但是"nginx-volume-test11"由于设置了"ro"只读权限,没有权限做增删改操作,如果在主机上删除文件,则2个容器的数据也会删除
? ? 4.?多容器数据继承
????????指令模型: docker run -itd --name 子容器名称 --volumes-from? 父容器名称 镜像名称 /bin/bash
????????创建"nginx-volume-test20"实例
[root@doc03?Docker]#?docker?run?-d?--name?nginx-volume-test20?-p?60000:80?-v?//opt/app/Docker/Container_data/nginx-volume-test20:/usr/share/nginx/html?nginx:v1 cda5bd44e77c979ddede127322fca7d5a0abe4997be78a4a8973b0700bceb81d????????以"nginx-volume-test20" 实例为父容器,创建"nginx-volume-test20.1"子容器
[root@doc03?Docker]#?docker?run?-d?--name?nginx-volume-test20.1?--volumes-from?nginx-volume-test20?nginx:v1 96df84470069a6cb59a1ba160ffd74b1fc0c91f11e60eae9f6d6544a90bf742f????????以"nginx-volume-test20.1" 实例为父容器,创建"nginx-volume-test20.1.1"子容器??
????????nginx-volume-test20.1 继承 nginx-volume-test20、nginx-volume-test20.1.1 继承 nginx-volume-test20.1,继承方自动创建目录
多容器数据场景使用的不多,这里不做过多的演示,只说明个人结论
????????? ? ● 父子容器磁盘共享,所有容器均可对容器卷做读写操作
????????????●?删除父子容器中的某个节点,不会对数据造成损坏、丢失
六. volume、mount bind2者的特点? ? 1. volume
????????●?数据存储路径由docker程序自身管理
????????●?container 内部目录数据统一在 "$volumes/_data"路径下
????????●?container内数据有文件,则会统一同步至 "$volumes/_data"路径下
????????●?多个container 使用相同的 "$volumes/_data"时,所有数据共享
????????●?即使容器被销毁,数据也不会丢失
????????●?当本地路径不存在时,会自动创建
????????●?权限控制,当有多个容器共享统一数据时,可以针对部分容器目录只有只读权限(不做演示,test-volume3:/usr/share/nginx/html:ro),此限制只针对容器
????????●?实例可移植性强,数据存储路径有docker自身管理
????????●?-v参数定义的名称必定是目录,不可能是文件
? ? 2. bind mount
????????●?数据存储路径由用户自身去定义
? ? ????●?container内部有数据文件时,不会迁移至数据存储目录
? ? ????●?多个container 使用相同的数据存储目录时,所有数据共享
? ? ????●?即使容器被销毁,数据也不会丢失
????????●?当本地路径不存在时,会自动创建
????????●?权限控制,当有多个容器共享统一数据时,可以针对部分容器目录只有只读权限(不做演示,test-volume3:/usr/share/nginx/html:ro),此限制只针对容器
????????●?可移植性差,因为有用户自定义的host_path参数
????????●?-v 参数即可指明目录也可以指明文件,当指明文件时此文件必须存在