Docker——Docker 容器数据卷(Volumes)
Posted Pakho`
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker——Docker 容器数据卷(Volumes)相关的知识,希望对你有一定的参考价值。
Docker 容器数据卷(Volumes)
容器数据卷(Volumes)
容器数据卷概述
Docker
的理念回顾- 将应用和环境打包成一个镜像
- 很多时候容器是需要保存数据,如果数据都保存在容器中,那么删除容器数据就会丢失, 需求:数据持久化
- 如现有mysql,将MySQL容器删除,删除容器,但MySQL中存储了数据,就等于删库跑路,需要:MySQL数据可以存储在本地
- 此时我们就需要一个容器共享的技术,Docker容器中产生的数据,同步到本地!
- 这就是
卷技术
,目录的挂载,将容器内的目录,挂载到Linux
上 - 同步机制,类似有点类似我们Redis里面的
RDB
和AOF
- 总结一句话,使用容器数据卷技术为了容器的持久化和同步操作
- 特点:
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷容器的生命周期一直持续到没有容器使用它为止 (–volumes from)
- 总结:
- 容器数据的持久化
- 容器间继承+共享数据
使用数据卷
方式一 直接使用命令挂载
Docker -v (Volumes)
docker run -it -v 主机目录:容器内目录
#启动一个容器不用提前创建test目录,启动容器后会自动创建
[root@docker ~]# docker run -it -v /home/test:/home/ centos /bin/bash
[root@d42da1fe7f0b /]#
#在主机查看容器挂载信息
[root@docker ~]# docker inspect d42da1fe7f0b
"Mounts": [
{
"Type": "bind", #绑定模式
"Source": "/home/test", #主机内地址
"Destination": "/home", #Docker容器内地址
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
测试数据共享
#在容器内创建文件在Linux查看是否同步
[root@d42da1fe7f0b home]# touch index.html
[root@docker test]# ls
index.html
#同理在主机上给文件中接入数据在容器中依旧可以查看
- 好处:我们以后修改文件只需在本地修改即可,容器会自动同步!
实战:MySQL同步数据
- 思考:MySQL的数据持久化问题
#获取MySQL镜像
[root@docker ~]# docker pull mysql:5.7
#运行容器,需要做数据卷挂载
#-d:后台运行 -p:端口映射 -v:数据卷挂载 两个-v挂载两个目录 -e:环境配置 --name:容器名字 通过MySQL5.7镜像启动
[root@docker ~]# 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,使用SQLyog
#进入容器创建数据库
[root@docker ~]# docker exec -it mysql01 /bin/bash
root@cfe440b11537:/# mysql -uroot -p
Enter password:
mysql> create database docker;
#退出容器查看主机数据卷挂载点
[root@docker data]# ll
drwxr-x--- 2 polkitd input 20 Jun 23 12:35 docker
#最后将MySQL容器干掉
[root@docker data]# docker rm -f mysql01
#再次查看主机容器卷挂载点,数据依旧没有丢失,这就实现了容器数据持久化功能!
具名挂载和匿名挂载
- 匿名挂载
-v
容器内路径
-P :随机映射端口 -v不指定路径直接选择容器内路径
[root@docker ~]# docker run -d -P --name nginx01 -v /etc/nginx nginx
Docker volume
[root@docker ~]# docker volume --help
Usage: docker volume COMMAND
Manage volumes
Commands:
create Create a volume #创建一个数据卷
inspect Display detailed information on one or more volumes #查看卷的详细信息
ls List volumes #查看当前所有的数据卷
prune Remove all unused local volumes #删除所有未使用的本地卷
rm Remove one or more volumes #删除一个或多个卷
#这种就是匿名挂载,我们在-v的时候只写了容器内的路径,没有写容器外的路径!
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local 6fd1e7ed2332934314d58bd10639dd8d8739440c2eccb571b5bce2bb451201a8
- 具名挂载
#通过 -v 卷名:容器内路径
[root@docker ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local juming-nginx
#查看一下这个卷
[root@docker ~]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2021-06-23T21:16:52+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
"Name": "juming-nginx",
"Options": null,
"Scope": "local"
}
]
- 所有的
Docker
容器内的卷,没有指定目录的情况下都是在/var.lib/docker/volumes/xxxx_data
- 我们通过具名挂载可以方便地找到我们的一个卷,大多数情况在使用具名挂载
- 如何区分具名挂载和匿名挂载,还是指定路径挂载
- 匿名:
-v
容器内的路径 - 具名:
-v
卷名:容器内路径 - 指定路径:
-v
/宿主机路径:容器内路径
- 匿名:
- 扩展
ro
readonly(只读)rw
readwrite(读写)
#一旦设置容器权限,容器对挂载出来的内容就有限定了!
#ro 只要看到ro就说明只能通过宿主机来操作,容器内部无法操作
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
数据卷之DockerFile
DockerFile
就是用来构建Docker镜像
的构建文件!命令脚本!- 通过脚本可以生成镜像!镜像是一层一层的,脚本就是一个个的命令,每个命令都是一层!
[root@docker docker-test-volume]# pwd #创建一个文件夹
/home/docker-test-volume
#创建一个dockerfile文件,名字可以随意,建议dockerfile
#文件中的指令(大写) 参数
[root@docker docker-test-volume]# vim dockerfile1 #编写一个测试文件
FROM centos #本镜像是用centos镜像作为基础
VOLUME ["/volume01","/volume02"]#通过volume挂载
CMD echo "----end----" #构建完成后输出end
CMD /bin/bash #构建完成后进入默认是/bin/bash控制台
#这里的每个命令就是镜像的一层
docker build -f /home/docker-test-volume/dockerfile1 -t pakho/centos:1.0 .
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
pakho/centos 1.0 7a249dc716f2 43 minutes ago 209MB
#启动自己生成的容器
[root@docker docker-test-volume]# docker run -it 7a249dc716f2 /bin/bash
[root@e79dc11945cb /]#
- 这两个目录就是我们生成镜像的时候自动挂载的,数据卷目录
- 这个卷和外部一定有一个同步的目录!
- 这个属于匿名挂载
#在容器内部创建一个文件
[root@82d2427d0d67 volume01]# touch volume.txt
#查看挂载信息
docker inspect 82d2427d0d67
#测试创建文件是否同步
[root@docker _data]# ls
volume.txt
数据卷容器
- 多个MySQL同步数据!容器与容器间同步!
启动3个容器,通过我们自己写的镜像启动
docker images
docker run -it --name docker01 7a249dc716f2
docker run -it --name docker02 --volumes-from docker01 7a249dc716f2
docker01 volumes创建测试文件,去docker02查看数据是否同步
[root@66c335f24239 volume01]# touch docker01.txt
[root@f5350f562104 volume01]# ls
docker01.txt
- docker01创建的数据同步到了docker02上
启动docker03依旧挂载至docker01
docker run -it --name docker03 --volumes-from docker01 7a249dc716f2
#存在docker01数据
[root@b827fdafb258 volume01]# ls
docker01.txt
#docker03创建文件
[root@b827fdafb258 volume01]# touch docker03.txt
#docker01查看数据,同步成功
[root@66c335f24239 volume01]# ls
docker01.txt docker03.txt
- 停止
docker01
并删除- 删除docker01,查看docker02和docker03是否还可以访问这个文件
测试依旧可以访问
拷贝的概念
docker rm -f 66c335f24239
#此时docker03查看数据,依旧存在,不会因为父容器kill而丢失数据
[root@b827fdafb258 volume01]# ls
docker01.txt docker03.txt
- 容器数据卷一般使用
- 多个MySQL实现数据共享
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
docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
#这个时候,可以实现两个容器数据同步!
容器数据卷(Volumes)的总结
- 容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
- 但是一旦持久化到了本地,
-v
,这个时候,本地的数据是不会删除的。
以上是关于Docker——Docker 容器数据卷(Volumes)的主要内容,如果未能解决你的问题,请参考以下文章