1.什么是容器数据卷
很多时候,我们的程序都是要保存数据的,但是现在数据又都是保存在容器内的,只要把容器删除,数据也就跟着被删除了。那么这时候我们就想把数据进行一个持久化。
当我们使用数据库时,这时候我们就想把数据库中的数据存储在本地。
这时候docker就给我们提供一个容器间可以有一个数据共享的技术。Docker容器中产生的数据,会同步到本地。 这就是容器数据卷技术,也就是目录的挂载,将容器内的目录挂载在宿主机上。
为什么使用卷技术? 简单总结:就是为了实现容器内数据的持久化和同步操作,容器间也是可以数据共享的。
2.使用容器数据卷
2.1 直接使用命令来挂载 -v
docker run -it -v 主机目录地址:容器内目录地址 centos /bin/bash
查看下我们容器的挂载信息
docker inspect 容器ID
这时候就会发现宿主机的home目录下多了一个ceshi文件夹
我们在容器内创建一个test.java文件
这时候会发现宿主机的home/ceshi目录下也出现了一个test.java文件。
然后我们在宿主机上test.java 这个文件中加一些内容
然后我们看下容器内的test.java文件是否也有相同的内容
这时候可以看到容器内的test.java文件也出现了相同的内容。
简单来说就相当于双向绑定。
好处:我们以后修改只需要在本地修改即可,容器内会自动同步。
3. 实战:安装Mysql
3.1 获取mysql镜像
docker pull mysql:5.7
3.2 查看镜像
docker images
3.3 运行容器
# 注释
# -d 后台运行
# -p 端口映射
# -v 卷挂载
# -e 环境配置
# --name 容器名字
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
3.4 查看容器
3.5 使用Navicat连接测试
4. 具名挂载和匿名挂载
1.匿名挂载
# -v 容器内路径
# -P 随机端口
docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看所有卷(volume)
[root@iZuf6ecpsnuw5412vz7xhsZ /]# docker volume ls
DRIVER VOLUME NAME
local 04f70a30f9e5980adb4e6e61ee000a4b68020ea70493585f19100c433a602312
这里发现,匿名挂载就是我们在-v 只写了容器内路径,没有写容器外的路径。
2.具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
通过 -v 卷名:容器内路径
查看卷信息
docker volume inspect 卷名
[root@iZuf6ecpsnuw5412vz7xhsZ /]# docker volume inspect juming-nginx
[
{
"Driver": "local",
"Labels": null,
# 这里就是宿主机地址
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": {},
"Scope": "local"
}
]
所有docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/卷名/_data 下
我们通过具名挂载可以方便的找到我们的一个卷,大多数情况下使用的都是具名挂载
3.如何确定是具名挂载还是匿名挂载,还是指定路径挂载?
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
4. 扩展
# 通过 -v 容器内路径:ro rw 改变读写权限
# ro readonly 只读
# rw readwrite 可读可写
#一旦设置了容器权限,容器对挂载出来的内容就有限定了。
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx
# 默认是rw 只要看到ro就说明这个文件只能通过宿主机来操作,容器内部是无法操作的。
5. 初始Dockerfile
Dockerfile 就是用来构建 docker 镜像的构建文件。就是一个命令脚本。
先来体验一下。
5.1 首先我们来创建一个测试的文件夹
mkdir docker-test-volume
5.2 我们进入到刚刚创建的文件夹下
5.3 创建一个dockerfile文件,名字可以随机,建议用dockerfile。通过这个脚本来生成一个镜像,镜像是一层一层的,脚本的一个个命令,每个命令都是一层。
# 脚本内容
# 文件中的指令都是大写的
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
5.4 生成镜像
# 注意: 末尾有个点 . 表示当前位置
docker build -f /home/docker-test-volume/dockerfile1 -t test-centos .
5.5 查看是否镜像生成成功
5.6 运行一下容器
5.7 查看挂载信息
这种挂载方式以后我们会使用的非常多,因为我们通常会构建自己的镜像。
6.数据卷容器
接下来我们举例说明下
1. 我们先启动一个我们上边自己创建的镜像
2. 我们在启动一个我们上边创建的镜像
--volumes-from # docker02 挂载到 docker01上 相当于Java中的子类继承父类。
3. 接下来我们测试下看是否会实现数据同步
3.1 我们现在docker01这个容器中创建一个文件
3.2 我们到docker02容器中查看是否也有这个文件。
这时候我们发现docker01容器中的文件同步到了docker02容器中。
多个mysql 或者 redis 同步数据。
docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
#这个时候就可以实现两个容器间的数据同步
结论: 容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。但是一旦你持久化(-v)到了本地,这个时候,本地的数据是不会删除的。