一、容器数据卷
1.什么是容器数据卷
docker的理念回顾
# 将应用和环境打包成一个镜像,发布之后启动运行就成为容器了
数据?如果数据都在容器中,那么我们容器删除,数据会丢失!(需求:数据持久化)
MySQL,容器删除了,删库跑路!(需求:MySQL数据可以存储在本地)
容器之间可以有一个数据共享技术!
docker容器中产生的数据,同步到本地!
这就是卷技术,目录的挂载,将我们容器内的目录挂载到linux上面!
# 总结:容器的持久化和同步操作!容器间也是可以数据共享的!
2.使用数据卷
1.方法一:直接使用命令来挂载 -v
# 方法一:直接使用命令来挂载 -v
# docker run -it -v 主机目录,容器目录 命令
[root@docter home]# docker run -it -v /home/ceshi:/home centos:7 bash #也可以写/usr/bin 绝对路径
指定主机目录:容器挂载目录
[root@docker ~]# cd /home #切换到主机家目录查看挂载目录
[root@docter home]# ll
total 0
drwxr-xr-x 2 root root 6 Jun 23 23:16 ceshi
[root@docter home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6840f7eb41c2 centos:7 "bash" 3 minutes ago Up 3 minutes magical_blackburn
73abd32030e3 tomcat "catalina.sh run" 3 hours ago Up 3 hours 0.0.0.0:1111->8080/tcp, :::1111->8080/tcp elated_yonath
c959ab03c4b3 nginx "/docker-entrypoint.…" 4 hours ago Up 4 hours 0.0.0.0:1234->80/tcp, :::1234->80/tcp nginx1
[root@docter home]# docker inspect 6840f7eb41c2 #查看挂载详细信息
2.测试挂载
目录同步测试:容器到主机
#1.容器内部
[root@6840f7eb41c2 home]# cd /home/
[root@6840f7eb41c2 home]# touch linux.mm
[root@6840f7eb41c2 home]# ls
linux.mm
#2.主机上查看
[root@docker ~]# cd /home/ceshi/
[root@docter ceshi]# ls
linux.mm
#1.主机上修改内容测试:主机到容器
[root@92109883794f home]# exit #要先停掉容器
exit
[root@docker ~]# cd /home/ceshi/
[root@docker ceshi]# ll
总用量 0
[root@docker ceshi]# ls
test.java
[root@docker ceshi]# vim test.java
hello world 123
3、再次测试
1、停止容器
2、宿主机上修改文件
3、启动容器
4、容器内的数据依旧是同步的
# 1、宿主主机
[root@docter ceshi]# cat linux.mm
echo "hello world"
# 2.容器内部
[root@6840f7eb41c2 home]# exit #退出容器
exit
[root@docter home]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6840f7eb41c2 centos:7 "bash" 10 minutes ago Exited About a minute ago magical_blackn
[root@docter home]# docker start 6840f7eb41c2 #启动容器
6840f7eb41c2
[root@docter home]# docker attach 6840f7eb41c2 #进入容器
[root@6840f7eb41c2 /]# cd /home/
[root@6840f7eb41c2 home]# ls
linux.mm
[root@6840f7eb41c2 home]# cat linux.mm
echo "hello world"
2.具名和匿名挂载
#1.匿名挂载
-v 容器内路径
docker run -d -p --name nginx01 -v /etc/nginx #不指定主机路径直接是容器内部目录
#实例:
[root@docter ~]# docker run -d -P --name=nginx01 -v /etc/nginx nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
b4d181a07f80: Already exists
edb81c9bc1f5: Pull complete
b21fed559b9f: Pull complete
03e6a2452751: Pull complete
b82f7f888feb: Pull complete
5430e98eba64: Pull complete
Digest: sha256:47ae43cdfc7064d28800bc42e79a429540c7c80168e8c8952778c0d5af1c09db
Status: Downloaded newer image for nginx:latest
55762ddddfe1b39fbd7613a81aa79dc43bbca4e284da8e94c452506992ec5042
[root@docter ~]# docker volume ls #查看所有卷的情况(匿名卷)
DRIVER VOLUME NAME
local 99faa68ccf5f9e389db7027db9e007e89ed38f9116db26271922d10536ae05c8
#这种就是匿名挂载,我们在-v只写了容器内部的路径,没有写容器外的路径
#2.具名挂载
[root@docter ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
08a19b52c784ad3616cabfb826bdf2d5e908c635d5ef66ade74651864b039c80
# 通过 -v 卷名:容器内路径
[root@docter ~]# docker volume ls
DRIVER VOLUME NAME
local 99faa68ccf5f9e389db7027db9e007e89ed38f9116db26271922d10536ae05c8
local juming-nginx
[root@docker ~]# docker volume inspect juming-nginx #查看具名挂载的具体信息
[
{
"CreatedAt": "2021-06-24T00:07:13+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/xxx/_data
#我们通过具名挂载可以方便的找到我们的一个卷,大多数情况使用的具名挂载
[root@docter volumes]# cd /var/lib/docker/volumes/
[root@docter volumes]# ls
99faa68ccf5f9e389db7027db9e007e89ed38f9116db26271922d10536ae05c8 backingFsBlockDev juming-nginx metadata.db
[root@docter volumes]# ll
total 24
drwx-----x 3 root root 19 Jun 24 00:03 99faa68ccf5f9e389db7027db9e007e89ed38f9116db26271922d10536ae05c8
brw------- 1 root root 253, 0 Jun 23 18:27 backingFsBlockDev
drwx-----x 3 root root 19 Jun 24 00:07 juming-nginx
-rw------- 1 root root 32768 Jun 24 00:07 metadata.db
[root@docter volumes]# cd juming-nginx/_data/conf.d/
[root@docter conf.d]# ls
default.conf
3.如何确定具名挂载还是匿名挂载,还是指定路径挂载?
-v 容器内路径 #匿名挂载
-v 卷名:容器内部路径 #具名挂载
-v /宿主机路径:容器内部路径 #指定路径挂载
扩展:
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
# 通过-v 容器内部路径:ro/rw改变读写权限(默认权限rw)
#ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部无法操作!
二、实战MySQL同步数据
1、 Mysql数据持久化功能
#1.下载镜像
[root@docter home]# docker pull mysql:5.7
#运行容器,需要做数据挂载 #安装启动mysql,一定要配置密码!!!
#官方测试:
docker run --name some-mysql -e MYAQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
#2.运行容器,需要数据挂载(安装MySQL需要设置密码)
-d 后台运行
-p 端口印射
-v 卷挂载
-e 环境配置
--name 容器名字
[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=123 --name mysql01 mysql:5.7
d38c12610f66e46724964e4f3d7f0322b314119f0ae754e85f22bacb47759d31
#3.在主机查看映射路径
[root@docter home]# cd /home/
[root@docter home]# ll
total 0
drwxr-xr-x 2 root root 22 Jun 23 23:25 ceshi
drwxr-xr-x 4 root root 30 Jun 23 23:48 mysql
[root@docter home]# ll mysql/
total 0
drwxr-xr-x 2 root root 6 Jun 23 23:48 conf
drwxr-xr-x 5 polkitd root 328 Jun 23 23:48 data
[root@docter home]#
#启动成功后,我们使用mqlyog 来测试一下
#mqlyog 连接服务器3301 -3310和容器内的3306映射,这个时候就连接上了
#如果我们将容器删除,发现挂载到本地的数据卷依旧没有消失,这就实现了容器数据持久化功能!
2、方式二:dockerfile
Dockerfile就是构建docker镜像的构建文件,命令脚本
通过这个脚本可以生成镜像,镜像一层一层的,脚本一个个的命令,每个命令都是一层
# 1、创建dockerfile文件,名字可以随机,建议使用Dockerfile(文件中的内容指令大写)
# 构建镜像时没有挂着卷,要手动镜像挂载 -v卷名:容器路径
[root@docker ~]# cd /home
[root@docker home]# vim Dockerfile
FROM centos
VOLUME ["/volume01","/volume02" ] #匿名挂载
CMD echo "----linux-----"c
CMD /bin/bash
[root@docker1 ~]# docker build -t test/centos:v1 . #构建镜像 # 方式一
[root@docker1 ~]# docker build -f Dockerfile -t test/centos:v1 . #构建镜像 #方式二
Sending build context to Docker daemon 219.8MB
Step 1/4 : FROM centos
...
Successfully built 08e6d99cb73f
Successfully tagged test/centos:v1
[root@docker home]# docker images #查看构建镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
test/centos v1 08e6d99cb73f 39 seconds ago 209MB
# 注: 镜像前面不加 / 构建镜像
[root@docker1 ~]# docker build -t test/centos:v1 . #构建镜像 # 方式一
[root@docker1 ~]# docker build -f Dockerfile -t test/centos:v1 . #构建镜像 #方式二
# 如果报错: VOLUME ["/volume01","/volume02" ] #匿名挂载 volume01加一个/
#2.启动自己生成的容器
[root@docker home]# docker run -it 3850e269b94a /bin/bash
[root@383339684d3c /]#
[root@383339684d3c /]# ls -l #查看目录
total 0
lrwxrwxrwx 1 root root 7 Nov 3 15:22 bin -> usr/bin
drwxr-xr-x 5 root root 360 Mar 20 07:09 dev
drwxr-xr-x 1 root root 66 Mar 20 07:09 etc
drwxr-xr-x 2 root root 6 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 6 Dec 4 17:37 lost+found
drwxr-xr-x 2 root root 6 Nov 3 15:22 media
drwxr-xr-x 2 root root 6 Nov 3 15:22 mnt
drwxr-xr-x 2 root root 6 Nov 3 15:22 opt
dr-xr-xr-x 113 root root 0 Mar 20 07:09 proc
dr-xr-x--- 2 root root 162 Dec 4 17:37 root
drwxr-xr-x 11 root root 163 Dec 4 17:37 run
lrwxrwxrwx 1 root root 8 Nov 3 15:22 sbin -> usr/sbin
drwxr-xr-x 2 root root 6 Nov 3 15:22 srv
dr-xr-xr-x 13 root root 0 Mar 20 07:09 sys
drwxrwxrwt 7 root root 145 Dec 4 17:37 tmp
drwxr-xr-x 12 root root 144 Dec 4 17:37 usr
drwxr-xr-x 20 root root 262 Dec 4 17:37 var
drwxr-xr-x 2 root root 6 Mar 20 07:09 volume01 #自己挂载的目录(生成镜像自动挂载的数据卷目录)
drwxr-xr-x 2 root root 6 Mar 20 07:09 volume02 #自己挂载的目录(生成镜像自动挂载的数据卷目录)
注:这个卷一定和外部有一个同步目录
#3.在容器内挂载目录下创建测试文件
[root@383339684d3c /]# cd volume01
[root@383339684d3c volume01]# touch 1.txt
[root@383339684d3c volume01]# ls
1.txt
#4.查看容器的具体信息
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
383339684d3c 3850e269b94a "/bin/bash" 4 minutes ago Up 4 minutes
[root@docker ~]# docker inspect 383339684d3c
"Mounts": [
{
"Type": "volume",
"Name": "34bbc194a4ba7b7cdc424ba768f89d6437f6be9004ef91e89a205288cfa
"Source": "/var/lib/docker/volumes/34bbc194a4ba7b7cdc424ba768f89d643 #对应容器外目录路径
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "b4f2a3ca38131f0bc8fe55398a9759266f171e02fd8f3ad7813a6889712
"Source": "/var/lib/docker/volumes/b4f2a3ca38131f0bc8fe55398a9759266 #对应容器外目录路径
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
#5.去容器外看一下创建的测试文件是否同步
[root@docker ~]# cd /var/lib/docker/volumes/34bbc194a4ba7b7cdc424ba768f89d6437f6be9004ef91e89a205288cfa3aeba/_data
[root@docker _data]# ls
1.txt
数据卷容器
3.数据卷容器(父容器)
4、多个 MySQL同步数据
#1.先启动2个容器,通过上边自己写的镜像(centos:7)启动
[root@docter home]# docker run -it --name docker01 centos:7
[root@101afc646532 /]# ls
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
[root@docter home]# docker run -it --name docker02 --volumes-from docker01 centos:7
[root@f3e086c8ca0e /]# ls #docker01为docker02的数据卷容器即父容器
bin etc lib lost+found mnt proc run srv tmp var volume02
dev home lib64 media opt root sbin sys usr volume01
(做测试docker01和docker02是不是互通的)
[root@docter opt]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f3e086c8ca0e centos:7 "/bin/bash" 2 minutes ago Up 2 minutes docker02
101afc646532 centos:7 "/bin/bash" 5 minutes ago Up 5 minutes docker01
[root@docker home]# docker attach 101afc646532 #进入到docker01
[root@101afc646532 /]# cd volume01
[root@101afc646532 volume01]# ls
[root@101afc646532 volume01]# touch docker01.tst #创建测试文件
[root@docker ~]# docker attach f3e086c8ca0e #进入到docker02
[root@f3e086c8ca0e /]# cd volume01
[root@f3e086c8ca0e volume01]# ls #可以看到同步文件即为成功
docker01.tst
#2.以docker01为数据卷容器创建docker03
[root@docker home]# docker run -it --name=docker03 --volumes-from docker01 test/centos:v1
(做测试docker01和docker03是不是互通的)
[root@7bd6d5539a3e /]# cd volume01
[root@7bd6d5539a3e volume01]# touch docker03.txt #创建docker03.txt测试文件
[root@docker ~]# docker attach f8ad77730f83
[root@f8ad77730f83 volume01]# ls #docker01也是可以同步的
docker01.tst docker03.txt
注:如果删除掉docker01,所创建的测试文件也是不会消失的
# --volumes-from 实现数据之前共享
5.多个MySQL实现数据共享
[root@docker home]# docker run -d -p 3310:3306 -v /etc/mysql/cong.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 --name mysql01 mysql:5.7 #创建mysql01容器
[root@docker home]# docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123 --name mysql02 --volumes-from mysql01 mysql:5.7 #创建mysql02容器
这个时候就可以实现两个容器数据同步了
6、结论:
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止
但是一旦你持久到了本地,这个时候,本地的数据是不会删除的!