Docker数据持久化简介

我们创建的容器里面是可以写数据的,image是只读的,但是container是可以写数据的,但是我们在container里面写的数据仅限于存在于这个容器,如果我们将这个容器停掉或者删除掉,那么我们创建的文件或存储的数据就都没了,所以容器的存储是临时的.

但是有的时候我们就需要将一些数据保存起来,必须我们的数据库容器,这个我们就需要利用Docker的数据持久化技术.

Docker持久化数据的方案

  • 基于本地文件系统的Volume:可以在执行docker create 或者 docker run时,通过 -v 参数将主机的目录作为容器的数据卷.这部分功能便是基于本地文件系统的voloum管理.

  • 基于plugin的Volume:支持第三方的存储方案,比如NAS,aws

Volume的类型:

  1. 受管理的Volume(data Volume):它是受管理的data volume,由docker后台自动创建,不需要我们通过 -v 参数指定,它的位置是固定的,但是名字是随机的

  2. 绑定挂载的Volume(bind Volume):具体的挂载位置可以由用户来指定,这样的好处是方便用户来管理

Data Volume

这节主要讲述第一种的数据持久化方案,通过指定主机的目录作为容器的数据卷,我们主要是使用-v参数来指定volume的名称,然后发现不同的容器是可以复用一个volume

我们通过安装一个MySQL容器并且指定数据持久化的位置(MySQL的Dockerfile中是有指定Volume的,我们只是通过 -v 参数来指定一个Volume名称),然后在此MySQL中创建一个表,然后删除此容器,重新创建一个新的MySQL容器,然后指定Volume是上一次创建的那个Volume,通过进入容器,发现上个容器中创建的表还是存在的,来说明数据持久化的方案是生效的.

主要命令:

  • -v 指定容器的数据存储位置及位置名称: docker run -d -v [volume名称]:[具体宿主机文件位置绝对路径] –name [容器名称] [image名称]

  • 查看所有的Volume: docker volume ls

  • 查看指定Volume的具体信息: docker volume inspect [volume名称]

  • 删除指定的Volume: docker volume rm [volume名称]

下面是演示示例:

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# 1.docker hub上下载MySQL5.7版本的Image

# 2.查看Dockerfile发现由如下代码,表明指定了MySQL数据存储的具体宿主机位置
VOLUME /var/lib/mysql

# 3.启动此Docker容器, -e 指定了环境变量,设置此MySQL的ROOT用户密码. -v 指定了volume的名称地址
jjw@jjw-PC:~$ docker run -d -v mysql:/var/lib/mysql --name mysql01 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
28e8bb72065bb5417936b098952dc741969420e80de22d177c3cb50cfe538101

# 4.查看我们创建的mysql Volume是否创建成功
jjw@jjw-PC:~$ docker volume ls
DRIVER VOLUME NAME
local mysql

# 5.查看此volume的具体信息
docker volume inspect [volume名称]
jjw@jjw-PC:~$ docker volume inspect mysql
[
{
"CreatedAt": "2020-06-02T21:34:14+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/mysql/_data",
"Name": "mysql",
"Options": null,
"Scope": "local"
}
]

# 6.我们进入此MySQL容器中
docker exec -it mysql01 /bin/bash
jjw@jjw-PC:~$ docker exec -it mysql01 /bin/bash
root@28e8bb72065b:/#

# 7.查看当前数据库中的表并创建一个新的表叫docker
root@c1afa5e97468:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.30 MySQL Community Server (GPL)

show databases
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)

create database docker
mysql> create database docker;
Query OK, 1 row affected (0.00 sec)

show database
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| docker |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)

# 8.退出容器并删除此容器
jjw@jjw-PC:~$ docker rm -f mysql01
mysql01

# 9.查看volume,发现容器创建的volume还是在的
jjw@jjw-PC:~$ docker volume ls
DRIVER VOLUME NAME
local mysql


# 10.我们重新去创建一个MySQL的容器,指定Volume还是上一次的那个Volume
docker run -d -v mysql:/var/lib/mysql --name mysql02 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql

# 11.创建完成我们进入此新的容器中,并查看数据库总所有的表,发现我们之前mysql01创建的表还在,说明我们的数据持久化是成功的
jjw@jjw-PC:~$ docker run -d -v mysql:/var/lib/mysql --name mysql02 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
881ba147a8b1804edab835d268fd70bb6974a1e643f595d9ff98fff684868e3d

jjw@jjw-PC:~$ docker exec -it mysql02 /bin/bash

root@881ba147a8b1:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.30 MySQL Community Server (GPL)

show databases;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| docker |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)

bind volume

上一种方式我们创建的Volume需要在Dockerfile中使用 VOLUME 参数指定具体的位置,我们虽然可以通过-v参数修改volume的名称,但是不能修改具体位置.而这一节的这种方式我们是通过绑定的方式,不需要在Dockerfile中去定义,我们只需要在启动docker容器时指定容器的存储目录和本地的目录做一个绑定关系,这样我们当容器的目录中数据发生变化时,会同步到本地的目录中,因为其实它们使用的是同一个目录文件.

以下我们通过示例来演示,示例内容主要是利用一个Dockerfile,然后在Dockerfile中使用 WORKDIR 指定工作目录,我们不使用 VOLUME 参数指定数据存储目录,然后我们启动容器时使用-v参数绑定一个本机目录,然后再容器中创建文件及修改文件,我们发现在本地的目录中也会创建这样的文件并跟随修改,并且我们在本机修改次文件内容,进入容器发现容器中的文件也跟随修改,因为它们是同一个文件

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1.修改Dockerfile,添加WORKDIR参数
WORKDIR /usr/share/test

# 2.根据此Dockerfile构建image

# 3.启动容器并指定绑定的目录
docker run -d -v [本机目录绝对路径]:[容器中需要映射的目录] --name [容器名称] [image名称]

# 4.进入容器内部在被bind的目录下创建一个文件

# 5.退出容器进入本机绑定的目录发现由我们刚才在容器中创建的目录

# 6.在本机修改此文件,然后进入容器内部,发现容器内的文件也被修改(因为他们是同一个文件)

最后更新: 2020年06月02日 22:08

原始链接: https://jjw-story.github.io/2020/05/23/Docker数据持久化/

× 请我吃糖~
打赏二维码