数据卷概念
♣我们知道,当我们把一个运行中的容器关闭后,容器里的数据就没有了(如果你做了docker commit操作,数据会保留到新的镜像里面)。所以我们就需要用容器数据卷把容器数据进行持久化储存。
♣还有一种情况,就是希望容器之间能共享数据,这时也需要容器数据卷。
♣一句话,数据卷就是用来解决数据持久化和数据共享的。
♣卷就是目录或者文件,存在一个或者多个容器中,由docker宿主机挂载到容器上,但是不属于联合文件系统,因此能绕过联合文件系统提供一些用于持久化存储或者共享数据的特性。
♣卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此docker不会在容器删除时删除其挂载的数据卷。
♣特点:
1)数据卷可以再容器之间共享或者重用数据;
2)卷的更改可以直接生效
3)数据卷中得更改不会包含在镜像的更新中;
4)数据卷的生命周期一直持续到没有容器使用它为止
5)数据卷可以完成容器到宿主主机、宿主机到容器之家的数据共享
容器内添加数据卷
♣在容器中添加数据卷有两种方法,一个是直接用命令添加,一个是用dockerfile添加,下面分别介绍
♣直接命令添加数据卷
1)命令:docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
说明:-v是volume的意思
宿主机绝对目录和容器内目录都不用提前建立
[root@t-docker chenzx]# docker run -it -v /myDataVolume:/dataVolumeContainer centos [root@8ad4df9ec2fd /]# ls anaconda-post.log dataVolumeContainer etc lib media opt root sbin sys usr bin dev home lib64 mnt proc run srv tmp var [root@8ad4df9ec2fd /]# cd dataVolumeContainer/
2)查看数据卷是否挂载成功
[root@t-docker myDataVolume]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8ad4df9ec2fd centos "/bin/bash" 5 minutes ago Up 5 minutes lucid_swartz [root@t-docker myDataVolume]# docker inspect 8ad4df9ec2fd "Mounts": [ { "Type": "bind", "Source": "/myDataVolume", "Destination": "/dataVolumeContainer", "Mode": "", "RW": true, ##注意RW是true才能可读写 "Propagation": "rprivate"
3)验证容器和宿主机之间数据共享
在/myDataVolume和/dataVolumeContainer上各创建文件,都能互相看到。
4)容器停止退出后,主机修改后数据是否还同步
答:同步
[root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 99d00ed3abbe centos "/bin/bash" 5 minutes ago Exited (0) 11 seconds ago [root@localhost myDataVolume]# touch c.txt [root@localhost ~]# docker exec -it 99d00ed3abbe /bin/bash [root@99d00ed3abbe /]# ls DataVolumeContainer bin etc lib media opt root sbin sys usr anaconda-post.log dev home lib64 mnt proc run srv tmp var [root@99d00ed3abbe /]# cd DataVolumeContainer/ [root@99d00ed3abbe DataVolumeContainer]# ls a.txt b.txt c.txt
5)带权限的数据卷
命令:docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
说明:-v是volume卷的意思
宿主机绝对路径目录和容器内目录都不用提前建立
ro是read only只读权限
[root@t-docker chenzx]# docker run -it -v /myDataVolume:/dataVolumeContainer:ro centos [root@c13998a78deb /]# ls [root@t-docker myDataVolume]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c13998a78deb centos "/bin/bash" 2 minutes ago Up 2 minutes wonderful_khorana [root@t-docker myDataVolume]# docker inspect c13998a78deb "Mounts": [ { "Type": "bind", "Source": "/myDataVolume", "Destination": "/dataVolumeContainer", "Mode": "ro", "RW": false, ##不能写,只能读 "Propagation": "rprivate"
6)其他
♣有时候可能会出现docker挂载的宿主机目录,容器访问出现cannot open directory:permission denied。
解决办法:在挂载目录后面多加一个--privileged=true参数即可。
[root@t-docker chenzx]# docker run -it -v /myDataVolume:/dataVolumeContainer -privileged=true centos
dockerfile方式添加数据卷
1)根目录下创建mydocker文件夹并进入
[root@t-docker chenzx]# mkdir /mydocker [root@t-docker chenzx]# cd /mydocker/
2)可在dockerfile中使用volume指令给镜像添加一个或者多个数据卷
语法:VOLUME ["/dataVolumeContainer",‘/data/VolumeContainer2‘,‘/dataVolumeContainer3‘]
说明:出于可移植性和分享的考虑,用-v主机目录:容器目录这种方法不能直接在dockerfile中实现。因为宿主机目录是依赖于特定宿主机的,并不能保证在所有的宿主机上都存在这样的特定目录。
3)dockerfile构建
[root@t-docker chenzx]# cd /mydocker/ [root@t-docker mydocker]# cat Dockerfile #volume test #继承centos镜像 FROM centos #在上面继承的centos目录下建立两个数据卷 VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"] CMD echo "finished,--------success1" CMD /bin/bash
4)build后生成镜像
[root@t-docker mydocker]# cd /mydocker/ [root@t-docker mydocker]# docker build -f /mydocker/Dockerfile -t chenzx/centos /mydocker Sending build context to Docker daemon 2.048kB Step 1/4 : FROM centos ---> 5182e96772bf Step 2/4 : VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"] ---> Running in d7a71c40c684 Removing intermediate container d7a71c40c684 ---> 1edef45a66a2 Step 3/4 : CMD echo "finished,--------success1" ---> Running in 0cad5eaf3a5e Removing intermediate container 0cad5eaf3a5e ---> 027d129bc237 Step 4/4 : CMD /bin/bash ---> Running in 0f4088e1bf0e Removing intermediate container 0f4088e1bf0e ---> a37b96c1c7a7 Successfully built a37b96c1c7a7 Successfully tagged chenzx/centos:latest [root@t-docker mydocker]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE chenzx/centos latest a37b96c1c7a7 18 seconds ago 200MB
♣ 说明: -t是-tag list的意思
5)run容器
[root@t-docker mydocker]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE chenzx/centos latest a37b96c1c7a7 7 minutes ago 200MB [root@t-docker mydocker]# docker run -it chenzx/centos [root@3ccb67a921de /]# [root@3ccb67a921de /]# ls anaconda-post.log dataVolumeContainer1 dev home lib64 mnt proc run srv tmp var bin dataVolumeContainer2 etc lib media opt root sbin sys usr [root@3ccb67a921de /]#
ls后看到容器内有dataVolumeContainer1和dataVolumeContainer2两个目录
6)查看容器内的卷目录地址对应的宿主机目录地址
[root@t-docker /]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3ccb67a921de chenzx/centos "/bin/sh -c /bin/bash" 6 minutes ago Up 6 minutes gallant_jang [root@t-docker /]# docker inspect 3ccb67a921de "Mounts": [ { "Type": "volume", "Name": "0055c21730734a9a73751de1ae1c7a5865f369e180d911490569d4aa1b78479d", "Source": "/var/lib/docker/volumes/0055c21730734a9a73751de1ae1c7a5865f369e180d911490569d4aa1b78479d/_data", "Destination": "/dataVolumeContainer1", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "18c5bc0fba2ec1913a7fd4997fc2181d16f2640d0c271571c0b580db89797c06", "Source": "/var/lib/docker/volumes/18c5bc0fba2ec1913a7fd4997fc2181d16f2640d0c271571c0b580db89797c06/_data", "Destination": "/dataVolumeContainer2", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }
上面我们看到是宿主机上的
/var/lib/docker/volumes/0055c21730734a9a73751de1ae1c7a5865f369e180d911490569d4aa1b78479d/_data对应容器里面的/dataVolumeContainer1,
/var/lib/docker/volumes/18c5bc0fba2ec1913a7fd4997fc2181d16f2640d0c271571c0b580db89797c06/_data对应容器里面的/dataVolumeContainer2
容器数据卷
♣命名的容器挂载数据卷,其他容器通过挂载这个父容器实现数据共享,挂载数据卷的容器,称之为数据卷容器。
♣下面我们以以上一步新建的镜像chenzx/centos为模板并运行容器dc01/dc02/dc03。
♣我们通过前面新建的镜像chenzx/centos为模板,生成的容器是挂载着/dataVolumeContainer1和/dataVolumeContainer2两个数据卷
1)先启动一个父容器dc01,并在dataVolumeContainer1中新增内容
[root@t-docker chenzx]# docker images chenzx/centos REPOSITORY TAG IMAGE ID CREATED SIZE chenzx/centos latest a37b96c1c7a7 3 hours ago 200MB [root@t-docker chenzx]# docker run -it --name dc01 chenzx/centos [root@b786166d80d7 /]# ls dataVolumeContainer1 dataVolumeContainer2 [root@b786166d80d7 /]# cd dataVolumeContainer1 [root@b786166d80d7 dataVolumeContainer1]# touch dc01_add.txt [root@t-docker chenzx]# [root@t-docker chenzx]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b786166d80d7 chenzx/centos "/bin/sh -c /bin/bash" 8 minutes ago Up 8 minutes dc01
2)dc02/dc03继承dc01(--volumes-from参数)
[root@t-docker chenzx]# docker run -it --name dc02 --volumes-from dc01 chenzx/centos [root@e71e1991a17b /]# ls anaconda-post.log dataVolumeContainer1 dev home lib64 mnt proc run srv tmp var bin dataVolumeContainer2 etc lib media opt root sbin sys usr [root@e71e1991a17b /]# cd dataVolumeContainer1 [root@e71e1991a17b dataVolumeContainer1]# ls dc01_add.txt [root@e71e1991a17b dataVolumeContainer1]# touch dc02_add.txt [root@e71e1991a17b dataVolumeContainer1]# ls dc01_add.txt dc02_add.txt [root@t-docker chenzx]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e71e1991a17b chenzx/centos "/bin/sh -c /bin/bash" 3 minutes ago Up 3 minutes dc02 b786166d80d7 chenzx/centos "/bin/sh -c /bin/bash" 14 minutes ago Up 14 minutes dc01
[root@t-docker chenzx]# docker run -it --name dc03 --volumes-from dc01 chenzx/centos [root@69c4c254cb0f /]# cd dataVolumeContainer1 [root@69c4c254cb0f dataVolumeContainer1]# ls dc01_add.txt dc02_add.txt [root@69c4c254cb0f dataVolumeContainer1]# touch dc03_add.txt [root@69c4c254cb0f dataVolumeContainer1]# ls dc01_add.txt dc02_add.txt dc03_add.txt [root@t-docker chenzx]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 69c4c254cb0f chenzx/centos "/bin/sh -c /bin/bash" 2 minutes ago Up About a minute dc03 e71e1991a17b chenzx/centos "/bin/sh -c /bin/bash" 7 minutes ago Up 7 minutes dc02 b786166d80d7 chenzx/centos "/bin/sh -c /bin/bash" 18 minutes ago Up 18 minutes dc01
3)回到dc01可以看到dc02/dc03添加的数据了
[root@t-docker chenzx]# docker exec -it dc01 /bin/bash [root@b786166d80d7 /]# ls anaconda-post.log dataVolumeContainer1 dev home lib64 mnt proc run srv tmp var bin dataVolumeContainer2 etc lib media opt root sbin sys usr [root@b786166d80d7 /]# cd dataVolumeContainer1 [root@b786166d80d7 dataVolumeContainer1]# ls dc01_add.txt dc02_add.txt dc03_add.txt
4)删除dc01,dc02修改后dc03可否访问
[root@t-docker chenzx]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 69c4c254cb0f chenzx/centos "/bin/sh -c /bin/bash" About an hour ago Up About an hour dc03 e71e1991a17b chenzx/centos "/bin/sh -c /bin/bash" About an hour ago Up About an hour dc02 b786166d80d7 chenzx/centos "/bin/sh -c /bin/bash" About an hour ago Up About an hour dc01 [root@t-docker chenzx]# [root@t-docker chenzx]# docker rm -f dc01 dc01 [root@t-docker chenzx]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 69c4c254cb0f chenzx/centos "/bin/sh -c /bin/bash" About an hour ago Up About an hour dc03 e71e1991a17b chenzx/centos "/bin/sh -c /bin/bash" About an hour ago Up About an hour dc02 [root@t-docker chenzx]# docker attach dc02 [root@e71e1991a17b dataVolumeContainer1]# ls dc01_add.txt dc02_add.txt dc03_add.txt [root@e71e1991a17b dataVolumeContainer1]# touch dc02_update.txt [root@e71e1991a17b dataVolumeContainer1]# ls dc01_add.txt dc02_add.txt dc02_update.txt dc03_add.txt
5)删除dc02后,dc03仍然可以访问
6)新建dc04继承dc03后再删除dc03
[root@t-docker chenzx]# docker run -it --name dc04 --volumes-from dc03 chenzx/centos [root@7b7f4dd0c965 /]# cd dataVolumeContainer1 [root@7b7f4dd0c965 dataVolumeContainer1]# ls dc01_add.txt dc02_add.txt dc02_update.txt dc03_add.txt
7)结论:容器之间配置信息的传递。数据卷的生命周期一直持续到没有容器使用它为止
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28916011/viewspace-2213253/,如需转载,请注明出处,否则将追究法律责任
原文地址:https://www.cnblogs.com/charon2/p/10428413.html