Volume数据卷
Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume)。数据卷可以用来存储Docker应用的数据,也可以用来在Docker容器间进行数据共享。
数据卷呈现给Docker容器的形式就是一个目录,支持多个容器间共享,修改也不会影响镜像。使用Docker的数据卷,类似在系统中使用 mount 挂载一个文件系统。
1)一个数据卷是一个特别指定的目录,该目录利用容器的UFS文件系统可以为容器提供一些稳定的特性或者数据共享。数据卷可以在多个容器之间共享。
2)创建数据卷,只要在docker run命令后面跟上-v参数即可创建一个数据卷,当然也可以跟多个-v参数来创建多个数据卷,当创建好带有数据卷的容器后,
就可以在其他容器中通过–volumes-froms参数来挂载该数据卷了,而不管该容器是否运行。也可以在Dockerfile中通过VOLUME指令来增加一个或者多个数据卷。
3)如果有一些数据想在多个容器间共享,或者想在一些临时性的容器中使用该数据,那么最好的方案就是你创建一个数据卷容器,然后从该临时性的容器中挂载该数据卷容器的数据。
这样,即使删除了刚开始的第一个数据卷容器或者中间层的数据卷容器,只要有其他容器使用数据卷,数据卷都不会被删除的。
4)不能使用docker export、save、cp等命令来备份数据卷的内容,因为数据卷是存在于镜像之外的。备份的方法可以是创建一个新容器,挂载数据卷容器,同时挂载一个本地目录,
然后把远程数据卷容器的数据卷通过备份命令备份到映射的本地目录里面。如下:
#docker run -rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
5)也可以把一个本地主机的目录当做数据卷挂载在容器上,同样是在docker run后面跟-v参数,不过-v后面跟的不再是单独的目录了,它是[host-dir]:[container-dir]:[rw|ro]这样格式的,host-dir是一个绝对路径的地址,如果host-dir不存在,则docker会创建一个新的数据卷,如果host-dir存在,但是指向的是一个不存在的目录,则docker也会创建该目录,然后使用该目录做数据源。
Docker Volume数据卷可以实现:
1)绕过“拷贝写”系统,以达到本地磁盘IO的性能,(比如运行一个容器,在容器中对数据卷修改内容,会直接改变宿主机上的数据卷中的内容,所以是本地磁盘IO的性能,而不是先在容器中写一份,最后还要将容器中的修改的内容拷贝出来进行同步。
2)绕过“拷贝写”系统,有些文件不需要在docker commit打包进镜像文件。
3)数据卷可以在容器间共享和重用数据
4)数据卷可以在宿主和容器间共享数据
5)数据卷数据改变是直接修改的
6)数据卷是持续性的,直到没有容器使用它们。即便是初始的数据卷容器或中间层的数据卷容器删除了,只要还有其他的容器使用数据卷,那么里面的数据都不会丢失。
Docker数据持久化:
容器在运行期间产生的数据是不会写在镜像里面的,重新用此镜像启动新的容器就会初始化镜像,会加一个全新的读写入层来保存数据。
如果想做到数据持久化,Docker提供数据卷(Data volume)或者数据容器卷来解决问题,另外还可以通过commit提交一个新的镜像来保存产生的数据。
一、创建一个数据卷
创建一个容器名为volume_1,这个数据卷在容器的目录是/usr/share/nginx/html
docker run -p 8811:80 -d --name volume_1 -v /usr/share/nginx/html nginx #这里启动nginx容器指定将nginx的80端口映射到本地的8811端口 以守护进程运行
查看数据卷的信息
docker inspect volume_1 #docker inspect 容器名
"Mounts": [
{
"Type": "volume",
"Name": "1e29729735ec5efa44ed5095e8af884bb1a00e8e976f7778ee0c3a286c9ba3b2",
"Source": "/var/lib/docker/volumes/1e29729735ec5efa44ed5095e8af884bb1a00e8e976f7778ee0c3a286c9ba3b2/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
该路径目录为宿主机与容器目录共
享"/var/lib/docker/volumes/1e29729735ec5efa44ed5095e8af884bb1a00e8e976f7778ee0c3a286c9ba3b2/_data"
本地进入该目录查看文件
[root@iZwz917v57iioljd7xhprwZ ~]# cd /var/lib/docker/volumes/1e29729735ec5efa44ed5095e8af884bb1a00e8e976f7778ee0c3a286c9ba3b2/_data
[root@iZwz917v57iioljd7xhprwZ _data]# ls
50x.html index.html
[root@iZwz917v57iioljd7xhprwZ _data]# vim index.html
[root@iZwz917v57iioljd7xhprwZ _data]# echo “it’s volume” > index.html
进入容器中查看
下面的命令中,需加-t和-i参数,才能登陆这个容器
-i:表示以“交互模式”运行容器
-t:表示容器启动后会进入其命令行
docker exec -it volume_1 /bin/bash
root@98816a1abb06:/# cd /usr/share/nginx/html/
root@98816a1abb06:/usr/share/nginx/html# ls
50x.html index.html
root@98816a1abb06:/usr/share/nginx/html# cat index.html
it’s volume
root@98816a1abb06:/usr/share/nginx/html# exit
通过浏览器访问(宿主机与容器之间文件已共享文件,自动同步文件)
二、挂载宿主机文件或目录到容器数据卷
可以直接挂载宿主机文件或目录到容器里,可以理解为目录映射,这样就可以让所有的容器共享宿主机数据,从而只需要改变宿主机的数据源就能够影响到所有的容器数据
注意:
-v后面的映射关系是"宿主机文件/目录:容器里对应的文件/目录",其中,宿主机上的文件/目录是要提前存在的,容器里对应的文件/目录会自动创建。
数据卷权限:
挂载的数据默认为可读写权限。
但也可以根据自己的需求,将容器里挂载共享的数据设置为只读,这样数据修改就只能在宿主机上操作。如下实例:
[root@iZwz917v57iioljd7xhprwZ docker_file]# ls
Dockerfile index.html volume
[root@iZwz917v57iioljd7xhprwZ docker_file]# cd volume/
[root@iZwz917v57iioljd7xhprwZ volume]# touch index.html
[root@iZwz917v57iioljd7xhprwZ volume]# echo “hello docker nginx volume” > index.html
[root@iZwz917v57iioljd7xhprwZ volume]# cd …
[root@iZwz917v57iioljd7xhprwZ docker_file]# ls
Dockerfile index.html volume
[root@iZwz917v57iioljd7xhprwZ docker_file]# docker run -p 8811:80 -d --name volume_2 -v $PWD/volume:/usr/share/nginx/html nginx #这里的美金符号PWD代表当前目录
783d86ae954599cd998bfe891b54a290e715dd5e5fce7ec1a2b29b1c7734c85c
在宿主机上修改index.html文件内容
[root@iZwz917v57iioljd7xhprwZ docker_file]# cd volume/
[root@iZwz917v57iioljd7xhprwZ volume]# ls
index.html
[root@iZwz917v57iioljd7xhprwZ volume]# echo “hellow volume2” > index.html
登陆到容器上修改文件内容
[root@iZwz917v57iioljd7xhprwZ _data]# docker exec -it volume_2 /bin/bash
root@783d86ae9545:/# cd /usr/share/nginx/html/
root@783d86ae9545:/usr/share/nginx/html# ls
index.html
root@783d86ae9545:/usr/share/nginx/html# echo “hello volume3” > index.html
root@783d86ae9545:/usr/share/nginx/html# exit
本地宿主机文件同样同步修改
三、创建数据卷容器
创建一个数据卷容器data_container,指定宿主机的data目录与容器的var/data共享
[root@iZwz917v57iioljd7xhprwZ docker_file]# ls
Dockerfile index.html volume
[root@iZwz917v57iioljd7xhprwZ docker_file]# mkdir data
[root@iZwz917v57iioljd7xhprwZ docker_file]# ls
data Dockerfile index.html volume
[root@iZwz917v57iioljd7xhprwZ docker_file]# docker create -v $PWD/data:/var/data --name data_container ubuntu #docker create -v是创建数据卷容器
99d5c0449e2b7b8771f58a81758db84680d3f0d283d6ce86ed075b06b19e3845
创建one_container容器挂载data_containter容器中的数据卷
[root@iZwz917v57iioljd7xhprwZ docker_file]# docker run -it --name one_container --volumes-from data_container ubuntu /bin/bash
创建two_container容器挂载one_container容器中的数据卷,也可以挂载data_containter容器中的数据卷
[root@iZwz917v57iioljd7xhprwZ ~]# docker run -it --volumes-from one_container --name two_container ubuntu /bin/bash
root@891519a54b3f:/# cd /var/data/
root@891519a54b3f:/var/data# ls
whatever.txt
root@891519a54b3f:/var/data# echo “it’s two_container write” > whatever.txt
在one_container中创建文件whatever.txt文件
root@ad27cd319e04:/# cd /var/data/
root@ad27cd319e04:/var/data# ls
root@ad27cd319e04:/var/data# touch whatever.txt
在two_container容器中修改文件
root@891519a54b3f:/# cd /var/data/
root@891519a54b3f:/var/data# ls
whatever.txt
root@891519a54b3f:/var/data# echo “it’s two_container write” > whatever.txt
宿主机查看
one_container容器中查看
知识点:即便是删除了初始的数据卷容器data_container,或是删除了其它容器,但只要是有容器在使用该数据卷,那么它里面的数据就不会丢失!(除非是没有容器在使用它们)