1、什么是容器数据卷?
docker的理念回顾
将应用和环境打包成一个镜像!
但现在有个问题,我们有很多容器都是用来保存数据的,那么数据就不应该放在容器里,如果数据都在容器里,那么容器一删除,数据就会丢失。需求:数据可持久化
例如,把mysql放在容器里,容器删了,数据也被删除了。需求:Mysql数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!说白了这就是目录的挂载,将容器内的目录挂载到Linux上。
挂载:将宿主机的一部分空间共享给容器一起用

总结:容器的持久化和同步操作!容器间也是可以数据共享的。
2、使用数据卷
方式一:直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
#测试
[root@izbp1191gh7vw5p1u5ru50z ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
启动之后,我们可以通过 docker inspect 容器id 查看挂载信息
再进行一次测试:
- 停止容器
- 宿主机上修改文件
- 启动容器
- 容器内的数据依然是同步的

好处:我们以后修改只需要在本地修改即可,容器内会自动同步!
3、实战——安装MySQL
思考:MySQL的数据持久化的问题!
安装MySQL时,建议参考官方文档:https://hub.docker.com/_/mysql
#获取镜像
[root@izbp1191gh7vw5p1u5ru50z ~]# docker pull mysql:5.7
#启动mysql
[root@izbp1191gh7vw5p1u5ru50z ~]# 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
aa850de7f2c4a185f9adcc8b09c5c360f7f6dc7be421b1b45fc3aafc07ac6372
在本地使用Navicat连接阿里云的mysql成功,证明docker部署mysql已经成功。
navicat连接到服务器的3310端口,3310端口和容器的3306端口映射,这个时候我们就可以连接上了。

[root@izbp1191gh7vw5p1u5ru50z ~]# cd /home
[root@izbp1191gh7vw5p1u5ru50z home]# ls
admin ceshi mysql
[root@izbp1191gh7vw5p1u5ru50z home]# cd mysql
[root@izbp1191gh7vw5p1u5ru50z mysql]# ls
conf data
[root@izbp1191gh7vw5p1u5ru50z mysql]# cd data
[root@izbp1191gh7vw5p1u5ru50z data]# ls
auto.cnf client-key.pem ib_logfile1 private_key.pem sys
ca-key.pem ib_buffer_pool ibtmp1 public_key.pem
ca.pem ibdata1 mysql server-cert.pem
client-cert.pem ib_logfile0 performance_schema server-key.pem
[root@izbp1191gh7vw5p1u5ru50z data]#
在本地新建一个数据库,查看一下映射的路径。

在映射的路径中发现了数据库“db_test”。
[root@izbp1191gh7vw5p1u5ru50z data]# ls
auto.cnf db_test ibtmp1 server-cert.pem
ca-key.pem ib_buffer_pool mysql server-key.pem
ca.pem ibdata1 performance_schema sys
client-cert.pem ib_logfile0 private_key.pem
client-key.pem ib_logfile1 public_key.pem
[root@izbp1191gh7vw5p1u5ru50z data]#
当我们将容器删除
[root@izbp1191gh7vw5p1u5ru50z data]# docker rm -f mysql01
mysql01
[root@izbp1191gh7vw5p1u5ru50z data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ed573a3581bd portainer/portainer-ce "/portainer" 5 days ago Up 5 days 0.0.0.0:8000->8000/tcp, 0.0.0.0:9000->9000/tcp portainer
我们挂载到本地的数据卷依然没有丢失,这就实现了容器数据的持久化功能。
[root@izbp1191gh7vw5p1u5ru50z home]# ls
admin ceshi mysql
4、具名和匿名挂载
#匿名挂载
-v 容器内路径
docker run -d -p --name nginx01 -v /etc/nginx nginx
#查看所有卷(volume)的情况
docker volume ls
[root@izbp1191gh7vw5p1u5ru50z /]# docker volume ls
DRIVER VOLUME NAME
local a91169c017f3cd71bcb15d1f7fcd353ed797bd71047e886847e28bd0bd229c31 #匿名挂载,我们在-v时只写容器内的路径,没写容器外的路径
local portainer_data
#具名挂载
#通过 -v 卷名:容器内路径
[root@izbp1191gh7vw5p1u5ru50z home]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
2d5fb869a4eef679a6f91bdf74ce2cd4d1dbdceef4cf42c8982f637643cfefc4
[root@izbp1191gh7vw5p1u5ru50z home]# docker volume ls
DRIVER VOLUME NAME
local a91169c017f3cd71bcb15d1f7fcd353ed797bd71047e886847e28bd0bd229c31
local juming-nginx #具名挂载
local portainer_data
#查看一下这个卷
[root@izbp1191gh7vw5p1u5ru50z home]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2021-03-24T21:30:59+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data", #卷的路径
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
所有的docker容器内的卷,没有指定目录的情况下都是在 /var/lib/docker/volumes/xxx/_data路径下。
通过具名挂载可以方便的找到卷,大多数情况在使用的是具名挂载。
如何确定是具名挂载还是匿名挂载,还是指定路径挂载?
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径::容器内路径 #指定路径挂载
5、知识拓展
有时候我们用docker run的时候,后面存在一个“ro”或者“rw”。
#通过 -v 容器内路径:ro rw 改变读写权限
ro #只读,说明这个路径只能通过宿主机来操作,容器内部是无法操作的。
rw #可读可写,默认情况
#一旦使用了这个则设置了容器权限,容器对我们挂载出来的内容就有限定了!
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
6、数据卷容器
使两个容器之间数据同步,如多个mysql同步。
#启动3个容器,通过我们刚才自己写的镜像启动
docker run -it --name docker01 2aa80bd7d039
docker run -it --name docker02 --volumes-from docker01 2aa80bd7d039
docker run -it --name docker03 --volumes-from docker01 2aa80bd7d039
创建docker03容器,该容器目录下也有volume01目录
在该目录下,也有docker01文件。
并且在删除了docker01容器之后,该目录依然存在。
结论
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的。