Docker进阶-容器数据卷使用
什么是容器数据卷
Docker的理念回顾:将应用和环境打包成一个镜像,发布之后运行启动变成一个容器。
我们很多时候需要不断的修改我们的应用,数据就会不断的修改,数据不应该放在容器里面,因为数据放在容器中,容器一删除,数据就丢失,这是我们不希望的,我们希望数据可以持久化!
例如Mysql的数据可以存储在本地,那么我们希望容器之间可以有一个数据共享的技术,因此容器数据卷就可以提供这样的技术!
Docker容器中产生的数据,同步到本地!容器删除,数据不会丢失,做到持久化,这就是卷技术,说白了就是一个目录挂载,将容器内的目录挂载到Linux上面!
由于我们容器是互相隔离的,因此我们希望容器的文件系统可以挂载到服务器上的文件系统,这样我们只需要修改服务器的文件系统就可以修改到容器的文件系统,并且删除容器,数据也不会丢失!
为什么要使用卷?
为了容器的持久化和同步操作!
并且容器间的数据可以共享,只需要挂载到同一个目录下就可以!
使用数据卷
方式一:使用命令来挂载
docker run -it -v 主机目录:容器内目录 容器名 /bin/bash
查看是否成功挂载
docker inspect 容器id
我们可以看到在Mounts
下面可以看到Source里面就是我们主机的地址,Destination就是容器内的地址。
"Mounts": [
{
"Type": "bind",
"Source": "/home/ceshi",
"Destination": "/home",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
测试
我们现在确定,挂载的文件夹里面都是空的
左边是容器内的,右边是本机的。
这个时候,我们在容器内添加一个文件,我们看看服务器是否会自动添加一个文件。
我们发现,成功同步了文件!
然后我们把服务停止掉,我们修改主机文件,看看是否可以同步。
然后重启我们的容器
发现也可以实现同步!
总结
只要我们挂载成功,这样只要我们的容器不删除,哪怕停止了容器,文件也可以同步,以后我们修改只需要修改本地即可,容器内会自动同步。
实战:实现同步MYSQL数据
解决MYSQL的数据持久化的问题
安装Mysql
docker pull mysql:5.7
启动容器并挂载数据文件
注意:首次启动需要配置mysql的密码
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
my-secret-pw
就是密码 some-mysql
就是容器名称
使用命令,我们密码设置为123456,容器名称设置为mysql01
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
并且我们把mysql的配置文件以及数据都挂载了出来。
-d 后台运行
-p 端口映射 主机端口:容器内端口
-v 卷挂载 主机目录:容器内目录
-e MYSQL_ROOT_PASSWORD=密码
--name 容器名称
这里的用户名默认是root!!
测试
这个时候,我们发现我们服务器已经和容器的文件挂载了。
我们可以通过SQLyog连接服务器的mysql,我们发现创建一个数据库,文件也可以同步过来,以后我们修改数据库的配置文件或者sql语句的时候,就可以直接修改我们本地的文件
这个时候,我们试试删除容器,看看本地文件是否会丢失
我们可以发现,本地文件原封不动
总结
我们删除容器,我们本地的数据也不会丢失,这就实现了我们容器数据持久化!
具名挂载和匿名挂载
什么是匿名挂载
不指定主机挂载地址的挂载方式:
docker run -d -P --name nginx -v /ect/nginx nginx
查看所有的volume情况
docker volume ls
local b710206272846fbedf83a07335b39584d576f5334b32b887732b35cf7db2f7d7
这种就是匿名挂载,它生成的名字是一串随机字符,由于我们只写了容器内的路径,没有写容器外的路径!
所有的Docker容器内的卷,没有指定目录情况下都是在/var/lib/docker/volumes/xxxx
相反就是具名挂载,我们建议使用具名挂载
docker run -d -P --name nginx02 -v jumping-nginx:/etc/nginx nginx
然后我们使用命令:即可查看文件所在路径
docker volume inspect jumping-nginx
如何区分具名和匿名,还是指定路径挂载
-v 容器内路径 #匿名挂载
-v 卷名:容器内路径 #具名挂载
-v 主机内路径(/xx/xxx):容器内路径 #指定路径挂载
拓展
通过 -v 容器内路径:ro rw 改变读写权限
ro readonly #只读
rw readwrite #可读可写
一旦设置了容器权限,容器对我们挂载出来的内容就有限定了!
只要看到ro就说明这个路径只能通过宿主机来操作,容器内是无法操作的!