什么是容器数据卷
docker回顾
将应用和环境打包成一个镜像!
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术! Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Linux上面!
总结:容器的持久化和同步操作!容器间也是可以数据共享的!
使用数据卷
直接使用命令来挂载 -v
docker run -it -v 主机目录:容器内目录
# 测试1
[hekai@localhost test_local]$ docker run -it -v /home/hekai/test_local:/home centos /bin/bash
# 启动之后,可以在新终端通过docker inspect 容器id 查看详细信息
# 下图右边是容器内部home目录,左边是主机的test_local位置,可以看到文件是同步的!
# 测试2
1、停止容器
2、宿主机上修改文件
3、启动容器
4、容器内的数据依旧是同步的!
卷的技术的好处:以后修改只需要在本地修改即可,容器内会自动同步!
实战:安装MySQL
思考:MySQL的数据持久化问题
# 搜索下载
[hekai@localhost test_local]$ docker search mysql
...
[hekai@localhost test_local]$ docker pull mysql:5.7
# 运行容器,需要做数据挂载! 第一次启动需要配置密码,这个要注意!
# 官方测试代码:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动我们的
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
--name 容器名字
[hekai@localhost ~]$ 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
# 启动成功之后,我们在本地使用sqlyog来测试连接一下
# sqlyog(没有安装一个)--连接到服务器的3310--3310和容器内的3306映射 完成连接!
# 在本地测试创建一个数据库,查看一下我们映射的路径是否ok
# 右键root@xxx.xxx-->创建数据库-->取名为test
# 测试删除容器,数据是否还在
[hekai@localhost test]$ docker rm -f mysql01
# 下图可以看到,数据依然还在
具名和匿名挂载
# 匿名挂载
-v 容器内路径
[hekai@localhost data]$ docker run -d -P --name nginx02 -v /etc/nginx nginx
b2130e752ad8ecd3bc24c99b79c3a4b7b3b34dcb2ebb1016eeb38984241c49f0
[hekai@localhost data]$
# 查看所有的volume的情况
[hekai@localhost data]$ docker volume ls
DRIVER VOLUME NAME
local 8d6a651ab088a378b9057e9cd0e4db3365c19b03a5168d942c32450f8e11cb59
local a4f803ca8e6d1f43e4d6aac8eaf01c2fdd0c3cc2d3b67073f2fe3f064555b24e
[hekai@localhost data]$
# 这种就是匿名挂载, 我们再 -v 时只写了容器内的路径,没有写容器外的路径
# 下面是具名挂载,通过 -v 卷名:容器内路径 的方式
[hekai@localhost data]$ docker run -d -P --name nginx03 -v juming-nginx:/etc/nginx nginx
ba9fa84d15f6fb5e68ea7aa9a54430480186c8980d8e013c0df7574ffa81747e
[hekai@localhost data]$ docker volume ls
DRIVER VOLUME NAME
local 8d6a651ab088a378b9057e9cd0e4db3365c19b03a5168d942c32450f8e11cb59
local a4f803ca8e6d1f43e4d6aac8eaf01c2fdd0c3cc2d3b67073f2fe3f064555b24e
local juming-nginx
[hekai@localhost data]$
# 查看卷的路径
[hekai@localhost data]$ docker volume inspect juming-nginx
[
{
"CreatedAt": "2021-03-10T15:21:58+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
[hekai@localhost data]$
所有docker容器内的卷,在没有指定目录的情况下都是在 /var/lib/docker/volumes
目录下(需要根用户权限)
我们通过具名挂载可以方便找到卷
# 如何确定具名挂载和匿名挂载,还是指定路径挂载?
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
拓展
# 通过 -v 容器内路径 ro rw 改变读写权限
ro readonly # 只读
rw readwrite # 可读可写
# 一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
[hekai@localhost data]$ docker run -d -P --name nginx02 -v /etc/nginx:ro nginx
[hekai@localhost data]$ docker run -d -P --name nginx02 -v /etc/nginx:rw nginx
# 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部无法操作!
初识Dockerfile
Dockerfile就是用来构建docker镜像的构建文件!命令脚本!先体验一下!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本中一个个命令,每个命令都是一层!
# 创建一个dockerfle文件,名字可以随机,建议dockerfile
# 文件中的内容:指令(大写) 参数
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "-----end-----"
CMD /bin/bash
# 这里的每一行命令,就是镜像的一层
[hekai@localhost docker_test_volume]$ docker build -f /home/hekai/test_local/docker_test_volume/dockerfile1 -t yinbinqiu/centos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 300e315adb2f
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in 774ab1ddd50b
Removing intermediate container 774ab1ddd50b
---> 4c2aeb64a32c
Step 3/4 : CMD echo "-----end-----"
---> Running in 6161f7bd78bf
Removing intermediate container 6161f7bd78bf
---> bdc6bcefa7b0
Step 4/4 : CMD /bin/bash
---> Running in 3e7777fbce0f
Removing intermediate container 3e7777fbce0f
---> 972d79cb13bd
Successfully built 972d79cb13bd
Successfully tagged yinbinqiu/centos:1.0
[hekai@localhost docker_test_volume]$
# 启动自己生成的镜像
[hekai@localhost docker_test_volume]$ docker run -it 972d79cb13bd /bin/bash
[root@13689c89c17c /]# ls -l
total 56
lrwxrwxrwx 1 root root 7 Nov 3 15:22 bin -> usr/bin
drwxr-xr-x 5 root root 360 Mar 10 07:51 dev
drwxr-xr-x 1 root root 4096 Mar 10 07:51 etc
drwxr-xr-x 2 root root 4096 Nov 3 15:22 home
lrwxrwxrwx 1 root root 7 Nov 3 15:22 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 17:37 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 15:22 media
drwxr-xr-x 2 root root 4096 Nov 3 15:22 mnt
drwxr-xr-x 2 root root 4096 Nov 3 15:22 opt
dr-xr-xr-x 437 root root 0 Mar 10 07:51 proc
dr-xr-x--- 2 root root 4096 Dec 4 17:37 root
drwxr-xr-x 11 root root 4096 Dec 4 17:37 run
lrwxrwxrwx 1 root root 8 Nov 3 15:22 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 15:22 srv
dr-xr-xr-x 13 root root 0 Mar 10 07:51 sys
drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp
drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr
drwxr-xr-x 20 root root 4096 Dec 4 17:37 var
drwxr-xr-x 2 root root 4096 Mar 10 07:51 volume01
drwxr-xr-x 2 root root 4096 Mar 10 07:51 volume02
# 可以看到,volume01和volume02已经挂载上去了,并且两个卷在外部一定有一个同步的目录
查看卷挂载的位置
# 首先在新的终端查看容器id,并用inspect查看具体信息
[hekai@localhost test_local]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27f7aa0bd14e 972d79cb13bd "/bin/bash" 3 minutes ago Up 3 minutes modest_williamson
[hekai@localhost test_local]$ docker inspect 27f7aa0bd14e
# 测试文件是否同步
# 1、在volume01中touch一个文件test01
# 2、在volume01卷映射的本地路径/var/lib/docker/volumes/30ed09c3fed240dfd328561a5ced58b1da1bd90201e212714f85e16edc870713/_data查看文件是否存在
发现的确同步了!
以后会自己构建镜像,这种方式使用较多!
假设构建镜像时没有挂载卷,要手动镜像挂载:-v 卷名:容器内路径!
数据卷容器
多个mysql同步数据!
# 启动三个容器测试
[hekai@localhost docker_test_volume]$ docker run -it --name docker01 yinbinqiu/centos:1.0
启动docker02,并将其--volume-from docker01
在docker01上也就是父容器中修改文件,在目录docker01中touch文件docker01
然后Ctrl+P+Q退出,并attach docker02查看volume01文件夹是否有docker01文件
再启动一个docker03,同样的方式挂载docker01,并创建一个文件docker03,然后进入docker01查看,发现文件存在
将docker01容器停止并删除,在docker02查看文件依旧存在
数据共享只要有一个容器存在,数据就存在
# 多个mysql数据共享实现
[hekai@localhost ~]$ 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
[hekai@localhost ~]$ docker run -d -p 3310:3306 -v -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volume-from mysql01 mysql:5.7
# 这个时候,可以实现两个容器数据同步!
结论:容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!