Docker基础Part4——数据卷

[TOC]

数据卷是什么

docker镜像是为了打包应用和环境。

  • 要防止容器的销毁造成数据的丢失。
  • 减少不必要进入容器修改配置文件。

docker容器中产生的数据不应当被存储在容器中,数据应当被同步共享到本机。

在docker容器中存放数据的文件目录(如:/usr/mysql/)可以挂载到本机的指定目录(如:/home/mysql/),实现数据同步共享。

多个容器之间依然可以通过上述相同的方式,实现多个容器的数据共享。

image-20210424140857577

数据卷使用

指定路径挂载

1
docker run -it -v 主机目录:容器内目录  -p 主机端口:容器内端口

demo:

1
2
3
4
5
6
7
[root@VM-1-14-centos ~]# docker run -it -v /home/volume:/home centos
[root@287b41b8e1eb /]# cd home
[root@287b41b8e1eb home]# touch test.txt
[root@287b41b8e1eb home]# ls
test.txt
[root@VM-1-14-centos volume]# ls
test.txt

容器内与主机内挂载的目录下,所有操作都相互等效。

即使容器停止、重启、删除,目录、数据依然同步。

MySQL实战

1
2
3
4
5
6
7
8
9
10
11
12
[root@VM-1-14-centos ~]# docker pull mysql:5.7
[root@VM-1-14-centos ~]# 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
67a1b52b307b59d14029fee48ae553b9334c57037ad001d914e2e87ba96fa6cb
# -d 后台运行 -p 端口映射 -v 卷挂载 -e 环境配置 -- name 容器名字
[root@VM-1-14-centos mysql]# ls data/
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 mysql private_key.pem server-cert.pem sys
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 ibtmp1 performance_schema public_key.pem server-key.pem
[root@VM-1-14-centos ~]# docker rm -f 67a1b52b307b
67a1b52b307b
[root@VM-1-14-centos mysql]# ls data/
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 mysql private_key.pem server-cert.pem sys
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 ibtmp1 performance_schema public_key.pem server-key.pem

具名和匿名挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 挂载方式
docker run -d -P --name xxx -v (str1:)str2 image
# str1 不加/为具名,加/为主机根目录下地址
# str2 容器内路径
# 匿名挂载: -v 容器内路径
# 具名挂载: -v 卷名:容器内路径
# 指定路径挂载: -v /宿主机路径:容器内路径

# 数据卷操作
docker volume [ options ]

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

demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 匿名挂载
[root@VM-1-14-centos mysql]# docker run -d -P --name nginx01 -v /etc/nginx nginx
# 查看所有的volume的情况
[root@VM-1-14-centos mysql]# docker volume ls
DRIVER VOLUME NAME
local 33ae588fae6d34f511a769948f0d3d123c9d45c442ac7728cb85599c2657e50d
......
# 具名挂载
[root@VM-1-14-centos mysql]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx
[root@VM-1-14-centos mysql]# docker volume ls
DRIVER VOLUME NAME
local juming-nginx
......
# 查看详细信息
[root@VM-1-14-centos mysql]# docker volume inspect juming-nginx
[
{
"CreatedAt": "2021-04-24T19:42:24+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
  • 如果指定了目录,docker volume ls 是查看不到的

通过具名挂载可以很容易地找到数据卷,因此通常使用具名挂载。

ro/rw

1
2
3
4
5
# -v 容器内路径:ro/rw 改变读写权限
ro #readonly 只读(只能通过宿主机操作)
rw #readwrite 可读可写
docker run -d -P --name nginx05 -v juming:/etc/nginx:ro nginx
docker run -d -P --name nginx05 -v juming:/etc/nginx:rw nginx

Dockerfile中设置挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
[root@VM-1-14-centos ~]# mkdir docker_test
[root@VM-1-14-centos ~]# cd docker_test/
[root@VM-1-14-centos docker_test]# vim dockerfile1
[root@VM-1-14-centos docker_test]# cat dockerfile1
FROM centos # 设置基础镜像
VOLUME ["volume01","volume02"] # 设置挂载,新建两个匿名卷
CMD echo "----end----" # 写出内部命令end
CMD /bin/bash # 进入bin/bash
[root@VM-1-14-centos docker_test]# docker build -f /root/docker_test/dockerfile1 -t nephrencake/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 40898156bffb
Removing intermediate container 40898156bffb
---> f7982a2145cb
Step 3/4 : CMD echo "----end----"
---> Running in cd21a00b4b6e
Removing intermediate container cd21a00b4b6e
---> dc3c858b0b01
Step 4/4 : CMD /bin/bash
---> Running in d6937914df26
Removing intermediate container d6937914df26
---> 706bb05073c4
Successfully built 706bb05073c4
Successfully tagged nephrencake/centos:1.0
[root@VM-1-14-centos docker_test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nephrencake/centos 1.0 706bb05073c4 2 minutes ago 209MB
[root@VM-1-14-centos docker_test]# docker run -it 706bb05073c4
[root@f42ba8b35f43 /]# ls -l
total 56
......
drwxr-xr-x 2 root root 4096 Apr 24 13:23 volume01 # 发现设置的挂载数据卷
drwxr-xr-x 2 root root 4096 Apr 24 13:23 volume02
[root@VM-1-14-centos ~]# docker inspect f42ba8b35f43
......
"Mounts": [
{
"Type": "volume",
"Name": "646d7481a3762934113020b27f86b43c980b3d76bddd15072b327785bc9672fc",
"Source": "/var/lib/docker/volumes/646d7481a3762934113020b27f86b43c980b3d76bddd15072b327785bc9672fc/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "860d1d86119aca1e8f1022c5588542608ce116e0530a758b7ba5e590cc7545ce",
"Source": "/var/lib/docker/volumes/860d1d86119aca1e8f1022c5588542608ce116e0530a758b7ba5e590cc7545ce/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
......

docker run xxx 等效于 docker run xxx:latest

因此 docker run xxx:latest 是找不到 docker run xxx:1.0 的

多容器同步数据卷

1
docker run -it --name container2 --volumes-from container1 image

demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 创建docker01容器并在挂载数据卷中创建文件
[root@VM-1-14-centos ~]# docker run -it --name docker01 706bb05073c4
[root@fc4ad8c3e129 /]# ls -l
total 56
......
drwxr-xr-x 2 root root 4096 Apr 25 00:22 volume01
drwxr-xr-x 2 root root 4096 Apr 25 00:22 volume02
[root@fc4ad8c3e129 /]# cd volume01
[root@fc4ad8c3e129 volume01]# touch docker01.txt

# 创建docker02并查看同步的数据卷
[root@VM-1-14-centos ~]# docker run -it --name docker02 --volumes-from docker01 706bb05073c4
[root@1f84a808b9bb /]# ls -l
total 56
......
drwxr-xr-x 2 root root 4096 Apr 25 00:22 volume01
drwxr-xr-x 2 root root 4096 Apr 25 00:22 volume02
[root@1f84a808b9bb /]# cd volume01
[root@1f84a808b9bb volume01]# ls
docker01.txt # docker01创建的文件在docker02中被同步

# 删除docker01并查看docker02的数据仍然存在
[root@VM-1-14-centos ~]# docker rm -f docker01
docker01
[root@1f84a808b9bb volume01]# ls
docker01.txt

container2和container1共享的数据卷互相共享但双向拷贝

多个MySQL数据共享

1
2
3
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
# -v 设置的挂载路径只需要设置一次,后来的继承即可

小结

便于集群建配置的同步共享。

数据卷的生命周期一直持续到所有容器被消灭为止(高可用)。

持久化到本地时,即使容器删除,本地数据依然保留。