文章目录
1.什么是容器数据卷
问题1: 如果数据在容器中,那么我们容器删除之后,数据就会丢失;
需求1: 数据可以持久化;
问题2: 例如MySQL数据库容器化,当容器删除了,删库跑路,数据也就丢失了;
需求2: MySQL数据可以存储在本地;
宿主机和容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地宿主机。
这就是卷技术,目录的挂载,将我们容器内的目录,挂载到Linux宿主机上面。
总结:容器的持久化和同步操作,容器间也是可以数据共享的。
2.使用数据卷
2.1 直接使用命令来挂载
docker run -it -v 主机目录:容器目录
测试:
- 下载镜像:
docker pull centos
-
检查镜像和服务器 /home 空目录
-
启动容器
docker run -it -v /home/ceshi:/home centos /bin/bash
- 启动之后,我们可以再打开一个新窗口,通过 docker inspect 容器id 来查看挂载情况
docker inspect 824508c3232e
- 测试目录的同步
5.1 在容器中挂载目录 /home 创建、修改文件、目录,会同步到宿主机挂载目录下
5.2 同理,在宿主机上的操作,都同步到容器中
- 测试停止容器同步
6.1 停止容器
6.2 宿主机修改文件
6.3 启动容器
docker ps -a
docker start 824508c3232e
6.4 容器内的数据仍然是同步的
docker exec -it 824508c3232e /bin/bash
优点:只需要修改本地配置,容器中会自动同步。
3.实战:MySQL
思考:MySQL数据持久化问题?
下载镜像:
docker pull mysql:5.7
- 运行容器需要数据卷挂载;
- 安装mysql,需要配置密码;
- 启动mysql容器参数:
-d 后台运行
-p 端口映射 宿主机端口:容器端口
-v 挂载卷
-e 环境配置参数
--name 容器名称
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
- 启动成功,测试连接
- 假设将容器删除
- 发现挂载到本地的数据卷依旧没有丢失,这就实现了容器数据持久化功能
4.具名和匿名挂载
下载nginx镜像:
docker pull nginx
4.1 匿名挂载
-v 容器内路径
-P 随机映射一个 49000~49900 的宿主机端口到容器内部开放的网络端口
docker run -d -P --name nginx01 -v /etc/nginx nginx
查看所有卷的情况
这里发现,这种就是匿名挂载,在 -v 之后只写了容器内的路径,没有写容器外的路径。
4.2 具名挂载
-v 卷名:容器内路径
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
docker volume ls
查看该卷
docker volume inspect juming-nginx
注:所有 Docker 容器的卷,没有指定目录的情况下,都是在 /var/lib/docker/volumes/xxxxxx/_data
目录下,通过具名挂载可以方便的找到对应的卷,大多数情况下使用 具名挂载
。
总结:如何确定是匿名挂载,还是具名挂载,还是指定路径挂载?
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
4.3 拓展(权限)
通过 -v 容器内路径:ro 或 rw 改变读写权限
ro # readonly 只读
rw # readwrite 可读可写
一旦创建容器时设置了容器权限,容器对挂载出来的内容就有了限定
docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
docker run -d -P --name nginx06 -v juming:/etc/nginx:rw nginx
默认是:rw
ro 只要看到 ro 就说明这个路径只能通过宿主机来操作,容器内是无法操作的。
5.初始 Dockerfile
Dockerfile 就是用来构建 docker镜像的构建文件!命令脚本!
通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是最终镜像的一 层!
- 创建一个dockerfile文件,名字可以随机,建议 dockerfile
vim dockerfile
#文件中的内容:指令(大写) 参数 FROM centos
VOLUME ["volume01","volume02"]
CMD echo"----end----"
CMD /bin/bash
- 制作镜像
docker build -f dokerfile -t tgm/centos .
- 查看镜像
- 查看数据卷
docker run -it 6985939560f3 /bin/bash
ls -l
- 这两个卷和外部一定有两个同步的目录
- 查看一下卷挂载在主机上的路径
docker inspect c2e2b139a3f4
6.数据卷容器
例:多个MySQL 同步数据
- Docker01
docker run -it --name docker01 tgm/centos /bin/bash
- Docker02
docker run -it --name docker02 --volumes-from docker01 tgm/centos /bin/bash
在Docker01上创建的目录,可以同步到Docker02上
- Docker03
docker run -it --name docker03 --volumes-from docker01 tgm/centos /bin/bash
新创建的Docker03依然会同步docker01数据卷的内容
在docker03下创建docker03文件后,进入docker01发现也依旧会同步过来
测试1: 删除docker01后,docker02和docker03是否还可以访问原来docker01下创建的的文件? 测试1的结果为:依旧可以访问!!!
测试2: 删除docker01后,docker02和docker03之间是否可以相互同步文件?
测试2的结果为:docket02和docker03之间依旧可以完成同步!!!
6.1 多个MySQL实现数据共享
docker run -d -p 3306: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
docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
这个时候,可以实现两个容器数据同步!
结论:
容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦持久化到了本地,这个时候,本地的数据是不会删除的!