5. 容器数据卷
实现容器中的数据同步到宿主机上的一中技术,数据卷技术。
将容器内的目录挂在到linux的目录上。
5.1 实现目录挂载 -v
-v 宿主机文件系统的路径:容器文件系统的路径
测试:创建centos容器,挂载目录,创建hello.volume文件
[root@ct7_1 ~]# docker run -it -v /home/centos_:/home centos bash
[root@5b8a92a9eb9b /]# cd home/
[root@5b8a92a9eb9b home]# ls
[root@5b8a92a9eb9b home]# touch hello.volume
[root@5b8a92a9eb9b home]# exit
exit
[root@ct7_1 ~]# cd /home/centos_/
[root@ct7_1 centos_]# ls
hello.volume
实现了数据卷的挂载。
此时查看此容器的系统信息:
docker inspect 5b8a92a9eb9b
# 省略了其它部分
......
"Mounts": [ # 挂载信息
{
"Type": "bind",
"Source": "/home/centos_", # 宿主机路径
"Destination": "/home", # 容器内的路径
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
......
5.2 具名和匿名挂载
实现数据卷有三种参数格式:
-v /宿主机路径:容器内路径 # 路径挂载
-v 容器内路径 # 匿名挂载
-v 数据卷名称:容器内路径 # 具名挂载
带有斜杠/ 表示路径,不带斜杠表示名称。
匿名挂载
指定容器内路径:/ect/nginx
docker run -d -P --name n1 -v /ect/nginx nginx
实际操作:
[root@ct7_1 /]# docker run -d -e MYSQL_ROOT_PASSWORD=123 --name m2 -v /val/mysql/data mysql:5.7
c293316f65ea5a748a54239d4972a521092b9c5aa69204f7fa2cbd93cca52b47
[root@ct7_1 /]# docker inspect m2
# 省略其他部分
# 使用匿名挂载,docker会自动判断需要挂载的文件夹,这里挂载mysql时则自动创建了两个劵:
......
"Mounts": [
{
"Type": "volume",
"Name": "873b58e3da0208f5a1cbf91cf6516fadc8c221a8c2b9751c50db9141052b9674",
"Source": "/var/lib/docker/volumes/873b58e3da0208f5a1cbf91cf6516fadc8c221a8c2b9751c50db9141052b9674/_data",
"Destination": "/val/mysql/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "09c72e4d7d2076a519d4252c0fc53198f2ecc1a4c4c015f23eabac7d4d81be7e",
"Source": "/var/lib/docker/volumes/09c72e4d7d2076a519d4252c0fc53198f2ecc1a4c4c015f23eabac7d4d81be7e/_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
]
......
Mounts #
Type # 数据卷
Source # 宿主机路径
Destination # 容器内路径
RW # 读写权限,相对于容器而言
具名挂载
使用卷名:nginx-v
docker run -d -P --name n2 -v nginx-v:/etc/nginx nginx
实际操作:
[root@ct7_1 data]# docker run -d -e MYSQL_ROOT_PASSWORD=123 --name m1 -v mysql-v:/val/mysql/data mysql:5.7
[root@ct7_1 data]# docker volume ls
DRIVER VOLUME NAME
local 0150a37e67573109ad401da2c203f9a7724414787bc7cdd8605eb4acb35c3401
local mysql-v
[root@ct7_1 data]# docker volume inspect mysql-v
[
{
"CreatedAt": "2020-10-19T05:14:10-07:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/mysql-v/_data",
"Name": "mysql-v",
"Options": null,
"Scope": "local"
}
]
Mountpoint:挂载宿主机的路径。
查看所有数据卷信息
docker volume ls
docker容器的数据卷,在没有指定目录的情况下,文件都挂载在:
/var/lib/docker/volume/xxx/_data
添加权限 ro rw
- or:readonly 只读
- rw:readwrite 读写
这个是对容器而言的权限控制。
# 对此容器设置只读劵,容器只可以读取挂载的劵的内容,不能修改和删除
docker run -d -p -v nginx-v:/ect/nginx:ro nginx
# 对此容器设置读写劵
docker run -d -p -v nginx-v:/ect/nginx:rw nginx
5.3 通过dockerfile构建镜像的时候挂载
第6.2标题中介绍。
5.4 容器之间实现数据同步 --volumes-from
这一步我学完的时候也是感觉很麻烦的,因为有很多种情况需要实际测试,,,中间我还想了docker搭应用的集群时,高并发下这个挂载会有一个怎样的同步操作,,,是否稳定。还是全部理解透在回来思考这个问题吧。
使用 --volumes-from 实际操作一下这两种情况:
-
docker01 <—— docker02 <—— docker03
docker02 挂载docker01,docker03挂载docker02;
-
docker01 <—— docker02,docker01 <—— docker03
docker02和docker03都挂载docker01;
测试1:docker01 <—— docker02 <—— docker03
# 创建容器
[root@ct7_1 /]# docker run -itd --name docker01 ssx-centos:1.0
[root@ct7_1 /]# docker run -itd --name docker02 --volumes-from docker01 ssx-centos:1.0
[root@ct7_1 /]# docker run -itd --name docker03 --volumes-from docker02 ssx-centos:1.0
# 通过inspect查看三个容器的挂载信息,name、source、destination都是一样的
"Name": "8d2b953edaaca284f4a4130052c28b2f906a53673191edc83cd7aa5fff973525",
"Source": "/var/lib/docker/volumes/8d2b953edaaca284f4a4130052c28b2f906a53673191edc83cd7aa5fff973525/_data",
"Destination": "volume01",
"Name": "e9e7f5f6621894afe49d90281386f719dfa053c8c075da9f35126c01862302e2",
"Source": "/var/lib/docker/volumes/e9e7f5f6621894afe49d90281386f719dfa053c8c075da9f35126c01862302e2/_data",
"Destination": "volume02",
-
在宿主机中的挂载目录创建文件:suzhu.java
查看docker01、docker02、docker03的volume01目录内都生成了suzhu.java
-
在docker03的volume02中创建文件:docker03.class
查看宿主机对应挂载目录和docker02的volume02中都生成了 docker03.class文件
-
删除docker01容器,在宿主机挂载目录创建:suzhu.javascript
查看docker02、docker03的volume01目录内都生成了suzhu.java
[root@ct7_1 _data]# docker rm -f docker01 docker01 [root@ct7_1 _data]# touch suzhu.javascript [root@ct7_1 ~]# docker attach docker03 [root@4cbcc87247ca volume01]# ls suzhu.java suzhu.javascript
本来还打算删除volume02的劵e9e7f5f6621894afe49d90281386f719dfa053c8c075da9f35126c01862302e2再进行测试,结果提示该劵被docker02、docker03容器使用着不能删除,需要先删除容器,才能删除被应用的具体劵。
测试2:docker01 <—— docker02,docker01 <—— docker03
# 创建容器
[root@ct7_1 /]# docker run -itd --name docker01 ssx-centos:1.0
[root@ct7_1 /]# docker run -itd --name docker02 --volumes-from docker01 ssx-centos:1.0
[root@ct7_1 /]# docker run -itd --name docker03 --volumes-from docker01 ssx-centos:1.0
# 通过inspect查看三个容器的挂载信息,name、source、destination都是一样的
"Name": "4d6cc4b485b8a9d00276ca5afbc8f92c70b4852fa1ac5b5b6c7f150cc76304ce",
"Source": "/var/lib/docker/volumes/4d6cc4b485b8a9d00276ca5afbc8f92c70b4852fa1ac5b5b6c7f150cc76304ce/_data",
"Destination": "volume01",
"Name": "d2e84c161cda0b84d98e87b1150dd226e174ef583a1c05aa39980d29c3bbcef5",
"Source": "/var/lib/docker/volumes/d2e84c161cda0b84d98e87b1150dd226e174ef583a1c05aa39980d29c3bbcef5/_data",
"Destination": "volume02",
-
在docker01/volume01创建文件:docker01.css
查看宿主挂载路径、docker02、docker03的volume01目录内都生成了docker01.css
-
删除docker01容器,在docker02/volume01中创建docker02.jar
查看docker03/volume01中,也生成了docker02.jar
数据卷小结:
-
通过两个小测试充分说明这个挂载虽然是通过 --volume-from docker01 创建的,但是创建完容器之后并不依赖具体容器,而是依赖具体的volume;
-
劵是一个独立于容器和镜像的存在;
-
即便全部挂载劵的容器都删除了,宿主机中的文件依然健在;
-
劵的生命周期也是在全部挂载容器都删除后,走进消亡。
6. DockerFile
6.1 DockerFile介绍
dockerfile是用来构建docker镜像的文件(命令脚本),通过这个文件生成镜像。
也就是说创建镜像的方法有两种:
-
<