数据卷
- 容器数据卷的使用
- 添加数据卷的方式有两种
- 匿名挂载和具名挂载
- 数据卷容器
容器数据卷的使用
容器数据卷概述
Docker 容器产生的数据,如果不通过 docker commit 生成新的镜像,使得数据作为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。那么如何在 Docker 容器中保证数据持久化呢?我们可以使用 Docker 容器数据卷。
PS: Docker 容器数据卷有点类似 Redis 里面的 rdb 和 aof 文件。
容器数据卷就是目录或文件,存在于一个或多个容器中,由 Docker 挂载到容器,但不属于联合文件系统,因此可以绕过联合文件系统提供一些用于持续存储或共享数据的特性。
其设计目的就是数据的持久化,完全独立于容器的生存周期,因此 Docker 不会在容器删除的时候删除其挂载的数据卷
特点:
1、数据卷可在容器之间共享或重用数据
2、数据卷中的更改可以直接生效
3、数据卷中的更改不会包含在镜像的更新中
4、数据卷的生命周期一直持续到没有容器使用它为止
添加数据卷的方式有两种
第一种:
直接通过命令挂载
docker run -it -v 主机目录:容器内目录
docker run -it -v /home/ceshi:/home centos /bin/bash
docker inspect b09697f6a8b3(容器id) #查看挂载信息
测试:
主机上操作
[root@localhost ~]# cd /home/ceshi/
[root@localhost ceshi]# touch yangzai.py
查看容器
然后我们在容器内创建文件:
[root@localhost ceshi]# ls
yangzai02.py yangzai.py
返回主机查看:
此时我们可以看出只要将目录挂载,那么我们的数据都是双向共享的。
那么我们将容器关闭,然后再主机里的yangzai.py中写入代码,再启动容器查看数据是都同步。
主机:
vim yangzai.py
hello world
容器:
第二种
通过dockerfile添加
mkdir /home/dockerfile/dockerfile1 #创建一个dockerfile1文件
vim dockerfile1
FROM centos
VOLUME ["volume01","volume02"] #匿名挂载
CMD echo "hello world"
CMD /bin/bash
通过dockerfile创建镜像
-f 是指定脚本文件
-t 是生成镜像 后面跟镜像名字
[root@localhost dockerfile]# docker build -f dockerfile1 -t maomao_cen
tos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 300e315adb2f
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in a008a94736b3
Removing intermediate container a008a94736b3
---> e1c3aaa1c146
Step 3/4 : CMD echo "hello world"
---> Running in dc172877fc6b
Removing intermediate container dc172877fc6b
---> b414cb83b033
Step 4/4 : CMD /bin/bash
---> Running in 716e78bf77ef
Removing intermediate container 716e78bf77ef
---> ddf57ae1a635
Successfully built ddf57ae1a635
Successfully tagged maomao_centos:1.0
查看左右镜像:
docker images
开启容器:
docker run -it --name ceshi1 ddf57ae1a635 /bin/bash
发现已经生成我们之前挂载的目录
查看一下卷挂载的路径:
docker inspect 87db60f4bf41
匿名挂载和具名挂载
匿名挂载:
所有的docker容器内的卷,没有指定目录的情况下都是在/var/lib/docker/volume/下以乱码的形式存在。通俗的讲就是匿名挂载的文件都是在/var/lib/docker/volume/目录下;
具名挂载
我们通过具名挂载的方式都是由我们自己决定存放文件的路径;(大多数情况我们都使用具名挂载)
实验:
#匿名挂载
-v 容器内的路径!
docker run -d -P --name nginx01 -v /etc/nginx nginx
#查看所有的volume
docker volume ls
DRIVER VOLUME NAME
local 1c7b7c9c7657facb6f24fa4a8138f349cdc1f62e3e29f9af94a0f1d03ab3
#这里发现,匿名挂载的,显示的一串乱码
#具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
#查看所有的volume
docker volume ls
DRIVER VOLUME NAME
local juming-nginx
#那么我们如何使用具名挂载和匿名挂载,还是指定路径挂载呢?
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
#另外,通过-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
数据卷容器
实验一:
创建两个容器 子容器挂载到父容器上面 查看数据是否同步
#启动父容器
docker run -it --name docker01 maomao_centos:1.0 /bin/bash
#启动子容器 挂载到父容器
docker run -it --name docker02 --volumes-from docker01 maomao_centos:1.0 /bin/bash
#在父容器的volume01里面创建文件
[root@8b03c7d68afd /]# cd volume01/
[root@8b03c7d68afd volume01]# ls
[root@8b03c7d68afd volume01]# touch docker01
#在子容器的volume01里会同步文件
[root@ca2db151b708 /]# cd volume01/
#docker01创建的内容同步到docker2上
[root@ca2db151b708 volume01]# ls
docker01
实验二:
创建第三个容器挂载到第1个容器上
#创建docker03挂载到docker02上
docker run -it --name docker03 --volumes-from docker01 maomao_centos:1.0 /bin/bash
[root@424d9d12c37e /]# cd volume01/
[root@424d9d12c37e volume01]# ls
docker01
[root@424d9d12c37e volume01]# touch docker03
[root@ca2db151b708 volume01]# ls
docker01 docker03
#在docker01容器中将docker01删除
docker rm -f docker01
docker02和docker03数据也跟着删除
#接着我们退出容器,在主机上将docker01容器删除
#我们返回容器docker02和docker03
#我们会发现docker02和docker03的数据依然存在
实验三:
使用具名挂载 然后实现两个容器的数据同步
docker run -it -P --name nginx01 -v nginx:/etc/nginx nginx /bin/bash
#查看具名挂载目录
docker inspect e1dd0b5ff9e5
cd /var/lib/docker/volumes/nginx/_data
#第二个容器挂载到第一个容器上
docker run -it -P --name nginx02 --volumes-from nginx01 nginx /bin/bash
#在具名挂载的目录里面修改nginx.conf配置文件
vim nginx.conf
events {
worker_connections 4096;
}
#查看两个容器的配置文件
root@e1dd0b5ff9e5:/etc/nginx# cat nginx.conf
events {
worker_connections 4096;
}
#两个容器配置文件都被改变 说明实现两个容器的数据同步
多个mysql实现数据共享
#开启第一个mysql容器 并挂载
docker run -d -p 3310:3306 -v conf:/etc/mysql/conf.d -v mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 --name mysql01 mysql:5.7
docker exec -it mysql01 /bin/bash
#开启第二个mysql容器 并挂载到第一个mysql上
docker run -d -p 3311:3307 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7