1、什么是数据持久化

容器中的数据可以存储在容器层。但是将数据存放在容器层存在以下问题:

数据不是持久化。意思是如果容器删除了,这些数据也就没了

主机上的其它进程不方便访问这些数据

对这些数据的I/O会经过存储驱动,然后到达主机,引入了一层间接层,因此性能会有所下降

Docker 提供了3种持久化数据的方式:

volumes(具名挂载、匿名挂载):存于主机文件系统中的某个区域,由Docker管理(/var/lib/docker/volumes/ on linux)。非Docker进程不应该修改这些数据。卷是Docker中持久化数据的最好方式

bind mount(绑定挂载):存于主机文件系统中的任意位置。非Docker进程可以修改这些数据

tmpfs mount(Linux中):存于内存中(注意,并不是持久化到磁盘)。在容器的生命周期中,它能被容器用来存放非持久化的状态或敏感信息。

2、删除原有容器,创建新容器。新容器会继承之前的数据卷

  1. docker rm -f mysql // 删除mysql容器
  2. sudo docker run -p 3307:3306 --name mysql1 -v /mydata/mysql/log:/var/log/mysql -v /mydata/mysql/data:/var/lib/mysql -v /mydata/mysql/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
  3. //继续新建mysql1容器.不过这次我们把它映射宿主机的3307

PS:记得开放云服务器的3307端口哦~

连接navicat,查看之前的数据
image.png

会发现数据都还在,这个就是数据持久化的好处(不会因为删除容器,而数据丢失掉)

3、什么是数据卷:

当我们把应用和环境 打包成一个镜像。
并且以这个镜像 运行产生一个容器时,当这个容器被删除,容器中的数据也随之被删除。
于是便产生了需求:容器中的数据持久化。
容器之间 有一个数据共享技术,将docker 中产生的 数据 同步到本地。
这就是 卷技术,将容器的内目录挂载到 本地,也就是Linux 服务器上。
image.png

容器的持久化操作和同步操作,容器之间可以数据共享。

4、如何使用数据卷

1、指定路径挂载

我们先创建一个待挂载的文件夹: mkdir /home/test 
生成容器并挂载到/home/test目录里:docker run -it -v /home/test:/home centos /bin/bash

image.png

查看下这个容器的id:docker ps -a

image.png

使用 docker inspect 容器Id 命令 查看挂载的位置
查看centos挂载目录的位置:docker inspect 011c71f8bb89
也可以使用:docker inspect 容器id | grep Mounts -A 20

image.png

此时已经挂载成功

“Mounts”: [                     #-v 数据卷挂载
{
“Type”: “bind”,
“Source”: “/home/test”, #主机内地址
“Destination”: “/home”, #容器内地址
“Mode”: “”,
“RW”: true,
“Propagation”: “rprivate”
}
],



宿主机新建目录,centos容器中同步增加

宿主机:
image.png
容器:
image.png
centos容器中删除目录,挂载宿主机的内容同步删除

容器:
image.png

宿主机:
image.png

当 我们在 容器内创建了一个 aa文件夹时,文件被同步到了 Linux系统文件目录下。
同步的过程 类似与 双向绑定机制。
当容器停止 时,只要容器还存在,修改容器中挂载的 卷 的内容 也会被同步到 本地的Linux 系统文件目录下。

好处:当我们在本地修改文件的 时候,会自动的去修改容器中的文件。

补充:
当容器和宿主机挂载的目录被删掉,容器中被挂载的目录下不允许再新建文件了

举例;
宿主机中,挂载了/home/test下,我将test目录删掉
容器中,挂载了/home目录下,进入home目录中,无法新增目录

2、具名挂载 和 匿名挂载

1、匿名挂载

-v 容器内路径

docker run -d -P --name nginx01 -v /ect/nginx nginx

image.png

查看所有的 数据卷

docker volume ls

image.png
[root@iZm5e8wrubqdpew00wz524Z ~]# docker volume ls
DRIVER VOLUME NAME
local aee6d7a11ce212b068c8fca16c7d4a11bc08b929a49133997c39e4124c6a9a79
这种数据都是匿名挂载的,因为 我们在 -v 挂载数据卷的时候 没有指定 容器外的路径

2、具名挂载

docker -v 卷名:容器内路径

docker run -d -P --name nginx02 -v juming-nginx:/ect/nginx nginx

接着查看所有的数据卷:docker volume ls
image.png
DRIVER VOLUME NAME
local aee6d7a11ce212b068c8fca16c7d4a11bc08b929a49133997c39e4124c6a9a79
local juming-nginx(具名挂载)

1、查看卷的具体位置

docker volume inspect 卷名

docker volume inspect juming-nginx

image.png
所有为指定具体位置的卷 都会在 /var/lib/docker/volumes/xxxx 下的位置

5、总结

平时使用的时候 尽量使用 指定路径挂载和 具名挂载,
-v /容器内路径 匿名挂载
-v 卷名:/容器内路径 具名挂载
-v /宿主机路径:/容器内路径 指定路径挂载