Docker数据卷
一、数据卷介绍
容器持久化操作和同步操作,容器间的数据可以共享,使用 run命令的 -v (volume)参数来设置容器数据卷。
大白话就是:数据卷可以理解成,宿主机
可以共享容器
中的文件,具体哪些文件在启动容器的时候通过-v
来指定,而这些文件就可以在宿主机中直接修改,修改后容器中的文件也被更改了,是不是可以想到一些应用场景,如nginx,mysql的配置文件,还有一些日志等,都可以通过数据卷挂载出来,方便修改和查看。这种方式唯一的坏处是,系统中会多一份文件,占用些内存,总的来说,优点还是大于缺点的。
二、数据卷挂载
挂载分为三种方式,分别是匿名挂载,具名挂载,指定路径挂载
注意:容器数据卷挂载时,只能在创建容器时挂载,因为-v 是run命令的一个参数,启动之后就不能再挂载了。
并且,即使容器停止,只要容器还存在,这个关联就一直再,及在本地新增一个文件,容器中也会自动新增,在容器中更改一个文件,本地也会自动更改
2.1 匿名挂载
匿名挂载:-v 容器内路径
,匿名挂载只单独指定容器内路径,会在docker的默认工作目录下自动生成一个文件夹,以Centos镜像为例
-
为了测试方便先删除一下所有的容器和挂载卷,正式服务器请勿使用
#强制删除所有容器 docker rm -f $(docker ps -aq) #删除所有volume docker volume rm $(docker volume ls -q)
-
将centos的
/home
匿名挂载到docker工作目录,该容器名为centos01docker run -d -it --name centos01 -v /home centos:latest
-
启动之后镜像就创建好了,可以通过
docker volume ls
查看匿名的卷名,是一串IDdocker volume ls DRIVER VOLUME NAME local 36ebb5e8a88c5cd0814dafa19d366f10564353ed90661055badadec276c47246
-
然后通过这个卷名,可以通过
docker volume inspect 卷名
查看到卷的详细信息,比如它的路径docker volume inspect 36ebb5e8a88c5cd0814dafa19d366f10564353ed90661055badadec276c47246 [ { "CreatedAt": "2021-09-27T14:48:13+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/36ebb5e8a88c5cd0814dafa19d366f10564353ed90661055badadec276c47246/_data", "Name": "36ebb5e8a88c5cd0814dafa19d366f10564353ed90661055badadec276c47246", "Options": null, "Scope": "local" } ]
-
具体挂载效果和这里先不演示,放在指定路径挂载中
2.2 具名挂载
具名挂载:-v 卷名:容器内路径
,具名挂载就只是比匿名多了个卷名,将一长串的ID变成了指定名,当然我还可以通过dockerfile的方式挂载,dockerfile的方式本质还是具名挂载,后面讲到dockerfile时再讨论,这里还是以Centos为例
-
将centos的
/home
挂载到docker工作目录下的centosvolume目录下,该容器名为centos02docker run -d -it --name centos02 -v centosvolume:/home centos:latest
-
启动之后,查看卷信息
docker volume ls DRIVER VOLUME NAME local 36ebb5e8a88c5cd0814dafa19d366f10564353ed90661055badadec276c47246 local centosvolume
-
查看卷详细信息
docker volume inspect centosvolume [ { "CreatedAt": "2021-09-27T15:06:30+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/centosvolume/_data", "Name": "centosvolume", "Options": null, "Scope": "local" } ]
2.3 指定路径挂载
指定路径挂载:-v 宿主机目录:容器目录
,指定路径挂载比较常见,可以自定义路径,相对来说更方便一下,以Centos为例测试一下挂载效果
-
将centos的
/home
挂载到宿主机的/home/centostest
目录,该容器名为centos03docker run -d -it --name centos03 -v /home/centostest:/home centos:latest
-
启动之后,查看卷信息时发现,此时的卷已经不在此处了,而宿主机中/home目录下多了个centostest文件夹
docker volume ls DRIVER VOLUME NAME local 36ebb5e8a88c5cd0814dafa19d366f10564353ed90661055badadec276c47246 local centosvolume
这里没有,那他们之间是怎么关联的呢?可以用之前提到的查看容器的元信息命令
docker inspect 容器ID或名
docker inspect centos03 | grep Mounts -A 10 "Mounts": [ { "Type": "bind", "Source": "/home/centostest", "Destination": "/home", "Mode": "", "RW": true, "Propagation": "rprivate" } ],
-
进入
/home/centostest
测试一下挂载效果,测试挂载是否成功简单,在宿主机中创建一个test.java文件,进入容器,切换到home目录,查看是否存在test.java文件。[root@izuf67znusfv5r0k1fzac9z home]# cd centostest/ [root@izuf67znusfv5r0k1fzac9z centostest]# ls [root@izuf67znusfv5r0k1fzac9z centostest]# pwd /home/centostest [root@izuf67znusfv5r0k1fzac9z centostest]# touch test.java [root@izuf67znusfv5r0k1fzac9z centostest]# ls test.java [root@izuf67znusfv5r0k1fzac9z centostest]# docker exec -it centos03 /bin/bash [root@d1055f6874f6 /]# cd home [root@d1055f6874f6 home]# ls test.java [root@d1055f6874f6 home]# exit exit [root@izuf67znusfv5r0k1fzac9z centostest]#
-
注意事项
在使用数据卷挂载时,如果所挂载的宿主机中包含文件,不管容器中是否包含文件,宿主机都将覆盖容器中的文件;如果所挂载的宿主机中不包含文件,容器则将自己的文件复制到宿主机中;并且挂载时,宿主机和容器要么都是文件,要么都是文件夹,如果不同,将启动失败。
三、其他
3.1 数据卷读写权限
数据卷还可设置ro
只读和 rw
可读可写,一但设置了容器权限,容器文件就有限制了,这个限制是针对容器内的文件,加上ro,说明这个文件只能通过宿主机来修改。以Centos为例:
限制容器中/home目录的写入功能,
docker run -d -it --name centos04 -v /home/centostest:/home:ro centos:latest
如果在容器中修改,创建文件会失败,提示文件只读
[root@izuf67znusfv5r0k1fzac9z centostest]# docker exec -it centos04 /bin/bash
[root@32b4998b514d /]# cd home
[root@32b4998b514d home]# touch test2.java
touch: cannot touch 'test2.java': Read-only file system
[root@32b4998b514d home]# exit
exit
[root@izuf67znusfv5r0k1fzac9z centostest]#
3.2 数据卷同步
--volumes-from
,创建容器时,数据卷使用其他已经存在的数据卷,这样做的好处是,能使配置文件同步,不用每次都改
将centos的/home
挂载到宿主机的centos03的目录下,该容器名为centos05
docker run -d -it --name centos05 --volumes-from centos03 centos:latest
这里就不测试了,在centos03中新建的test.java,也出现在了centos05容器home目录下,home目录下新建一个test3.java文件,centos03中也会有。
3.3 手动创建数据卷
数据卷可以通过docker volume create 数据卷名
,这和这个数据卷默认是在docker的工作目录下,尝试一下
[root@izuf67znusfv5r0k1fzac9z work]# docker volume create volumecreate
volumecreate
[root@izuf67znusfv5r0k1fzac9z work]# docker inspect volumecreate
[
{
"CreatedAt": "2021-09-27T16:42:33+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/volumecreate/_data",
"Name": "volumecreate",
"Options": {},
"Scope": "local"
}
]
如果我们此时再次使用具名挂载,并且数据卷名为volumecreate
,那么此时docker将不会创建新的数据,如果此时文件夹下有文件,也将在容器被创建时一并同步到容器中。