Docker 容器数据卷
一、什么是容器数据卷
docker将应用和运行环境打包成容器运行,应用是运行在容器中的,如果容器被删除了,应用也就不存在了,但是我们希望能够保存应用运行当中产生的数据;或者在容器之间,我们希望进行数据共享,怎么办呢?
容器数据卷能够解决上述问题。
容器数据卷将数据挂载在宿主机本地,卷就是容器当中的目录或者文件,存在于一个和多个容器中,有docker挂载在容器当中,但是不属于联合文件系统。因此能够绕过 Union File System ,提供一些用于持续存储或共享数据的特性。
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
特点:
1、数据卷可在容器之间共享或重用数据
2、卷中的更改可以直接生效
3、数据卷中的更改不会包含在镜像的更新中
4、数据卷的生命周期一直持续到没有容器使用它为止
总结一句话:容器数据卷就是容器的持久化,以及容器间的继承和数据共享!
二、如何使用容器数据卷
方式一:容器中直接使用命令来添加
# 命令 docker run -it -v 宿主机绝对路径目录:容器内目录 镜像名 # 测试 docker run -it -v /home/ceshi:/home centos /bin/bash
方式二:通过Docker File 来添加
DockerFile 是用来构建Docker镜像的构建文件,是由一些列命令和参数构成的脚本。
测试:
# 1、我们在宿主机 /home 目录下新建一个 docker-test-volume文件夹 [root@alway home]# mkdir docker-test-volume # 说明:在编写DockerFile文件中使用 VOLUME 指令来给镜像添加一个或多个数据卷 VOLUME["/dataVolumeContainer1","/dataVolumeContainer2","/dataVolumeContainer3"] # 出于可移植和分享的考虑,我们之前使用的 -v 主机目录:容器目录 这种方式不能够直接在DockerFile中实现。 # 由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有宿主机上都存在这样的特定目录. # 2、编写DockerFile文件 [root@alway docker-test-volume]# pwd /home/docker-test-volume [root@alway docker-test-volume]# vim dockerfile1 [root@alway docker-test-volume]# cat dockerfile1 # volume test FROM centos VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"] CMD echo "-------end------" CMD /bin/bash # 3、build后生成镜像,获得一个新镜像 alway/centos docker build -f /home/docker-test-volume/dockerfile1 -t alway/centos . # 注意最后有个. # 4、启动容器 [root@alway docker-test-volume]# docker run -it 0e97e1891a3d /bin/bash # 启动容器 [root@f5824970eefc /]# ls -l total 56 lrwxrwxrwx 1 root root 7 May 11 2019 bin -> usr/bin drwxr-xr-x 2 root root 4096 May 11 11:55 dataVolumeContainer1 # 数据卷目录 drwxr-xr-x 2 root root 4096 May 11 11:55 dataVolumeContainer2 # 数据卷目录 drwxr-xr-x 5 root root 360 May 11 11:55 dev drwxr-xr-x 1 root root 4096 May 11 11:55 etc drwxr-xr-x 2 root root 4096 May 11 2019 home ..... # 问题:通过上述步骤,容器内的卷目录地址就已经知道了,但是对应的主机目录地址在哪里呢? # 5、我们在数据卷中新建一个文件 [root@f5824970eefc dataVolumeContainer1]# pwd /dataVolumeContainer1 [root@f5824970eefc dataVolumeContainer1]# touch container.txt [root@f5824970eefc dataVolumeContainer1]# ls -l total 0 -rw-r--r-- 1 root root 0 May 11 11:58 container.txt # 6、查看下这个容器的信息 [root@alway ~]# docker inspect 0e97e1891a3d # 查看输出的Volumes "Volumes": { "/dataVolumeContainer1": {}, "/dataVolumeContainer2": {} }, # 7、这个卷在主机对应的默认位置
注意:如果访问出现了 cannot open directory: Permission denied
解决办法:在挂载目录后多加一个 --privileged=true参数即可
三、匿名挂载和具名挂载
匿名挂载:在挂载数据卷时只指定容器内路径,不指定数据卷名。
所有的docker容器内的卷、没有指定目录的请况下是在:/var/lib/docker/volumes/下
-v 容器内路径
docker run -d -p 3344:3344 --name nginx02 -v /etc/nginx nginx
具名挂载:在挂载数据卷时同时指定数据卷名和容器内路径。
-v 数据卷名:容器内路径
docker run -d -p 3344:3344 --name nginx02 -v jumingnginx:/etc/nginx nginx
指定路径挂载:在挂载数据卷时同时指定宿主机路径和容器内路径。
-v /宿主机路径:容器内路径
docker run -d -v /home/ceshi:/home centos /bin/bash
怎么判断挂载的是卷名而不是本机目录名?
不是/开始就是卷名,是/开始就是目录名
改变读写权限
-v 容器内路径:ro/rw
ro readonly #只读
rw readwrite #可读可写
四、数据卷容器
命名的容器挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为
数据卷容器。
我们使用上一步的镜像:alway/centos 为模板,运行容器 docker01,docker02,docker03,他
们都会具有容器卷
"/dataVolumeContainer1" "/dataVolumeContainer2"
我们来测试下,容器间传递共享
1、先启动一个父容器docker01,然后在dataVolumeContainer2新增文件
退出不停止:ctrl+P+Q
2、创建docker02,docker03 让他们继承docker01 --volumes-from
[root@alway docker-test-volume]# docker run -it --name docker02 -- volumes-from docker01 alway/centos [root@ea4c82779077 /]# cd /dataVolumeContainer2 [root@ea4c82779077 dataVolumeContainer2]# ls docker01.txt [root@95164598b306 dataVolumeContainer2]# touch docker02.txt [root@95164598b306 dataVolumeContainer2]# ls docker01.txt docker02.txt [root@alway docker-test-volume]# docker run -it --name docker03 -- volumes-from docker01 alway/centos [root@ea4c82779077 /]# cd /dataVolumeContainer2 [root@ea4c82779077 dataVolumeContainer2]# ls docker01.txt docker02.txt [root@95164598b306 dataVolumeContainer2]# touch docker03.txt [root@95164598b306 dataVolumeContainer2]# ls docker01.txt docker02.txt docker03.txt
3、回到docker01发现可以看到 02 和 03 添加的共享文件
[root@alway docker-test-volume]# docker attach docker01 [root@799b6ea5db7c dataVolumeContainer2]# ls -l total 0 -rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt -rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt -rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt
4、删除docker01,docker02 修改后docker03还能不能访问
[root@alway docker-test-volume]# docker rm -f docker01 docker01 [root@alway docker-test-volume]# docker attach docker02 [root@ea4c82779077 dataVolumeContainer2]# ls -l total 0 -rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt -rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt -rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt [root@ea4c82779077 dataVolumeContainer2]# touch docker02-update.txt [root@ea4c82779077 dataVolumeContainer2]# ls -a . .. docker01.txt docker02.txt docker02-update.txt docker03.txt [root@ea4c82779077 dataVolumeContainer2]# Ctrl+P+Q 退出容器 [root@alway docker-test-volume]# docker attach docker03 [root@95164598b306 dataVolumeContainer2]# ls -l total 0 -rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt -rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt -rw-r--r-- 1 root root 0 May 11 13:29 docker02-update.txt -rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt
5、删除docker02 ,docker03还能不能访问
[root@alway docker-test-volume]# docker ps CONTAINER ID IMAGE 95164598b306 alway/centos ea4c82779077 alway/centos [root@alway docker-test-volume]# docker rm -f docker02 docker02 [root@alway docker-test-volume]# docker attach docker03 [root@95164598b306 dataVolumeContainer2]# ls -l total 0 -rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt -rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt -rw-r--r-- 1 root root 0 May 11 13:29 docker02-update.txt -rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt [root@95164598b306 dataVolumeContainer2]# touch docker03-update.txt
6、新建docker04继承docker03,然后再删除docker03,看下是否可以访问!
[root@2119f4f23a92 /]# cd dataVolumeContainer2 [root@2119f4f23a92 dataVolumeContainer2]# ls -l total 0 -rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt -rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt -rw-r--r-- 1 root root 0 May 11 13:29 docker02-update.txt -rw-r--r-- 1 root root 0 May 11 13:32 docker03-update.txt -rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt # 查看当前运行的容器 [root@alway docker-test-volume]# docker ps CONTAINER ID IMAGE NAMES 2119f4f23a92 alway/centos docker04 95164598b306 alway/centos docker03 # 继续删除docker03 [root@alway docker-test-volume]# docker rm -f docker03 docker03 [root@alway docker-test-volume]# docker attach docker04 [root@2119f4f23a92 dataVolumeContainer2]# ls -l total 0 -rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt -rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt -rw-r--r-- 1 root root 0 May 11 13:29 docker02-update.txt -rw-r--r-- 1 root root 0 May 11 13:32 docker03-update.txt -rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt
得出结论:
容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。
存储在本机的文件则会一直保留!