Docker数据持久化总结
Docker的数据持久化即数据不随着container(容器)的结束而结束,如果要想达成此目的,则数据必须得持久化存储在host(宿主机)上,依据存储的数据的管理方式不同,Docker上有两种数据持久化方式:
- 存在于host的某个指定目录中(使用bind mount)
- 使用docker自己管理的volume(/var/lib/docker/volumes下)
# bind mount
bind mount自docker早期便开始为人们使用了,用于将host机器的目录mount到container中。
# 将host机器上当前目录下的host-data目录mount到container中的/container-data目录
docker run -it -v $(pwd)/host-dava:/container-data alpine sh
2
有几点需要注意:
- 如果host机器上的目录不存在,docker会自动创建该目录
- 如果container中的目录不存在,docker会自动创建该目录
- 如果container中的目录已经有内容,那么docker会使用host上的目录将其覆盖掉
# volume
volume(卷)也是绕过container的文件系统,直接将数据写到host机器上,只是volume是被docker管理的,docker下所有的volume都在host机器上的指定目录下/var/lib/docker/volumes。
dev@devops:~$ sudo ls -al /var/lib/docker/volumes
total 220
drwx------ 5 root root 45056 Apr 15 23:09 .
drwx--x--x 14 root root 4096 Apr 10 15:03 ..
drwxr-xr-x 3 root root 4096 Jan 30 11:46 4f5936b11140b7664aa4dcb5f7043fdef96b80d76b23b0410da8ee9e7caa653d
drwxr-xr-x 3 root root 4096 Jan 30 11:46 c501e25d1cde249a7fbd7f2e2c3155ca2fd876b7a28df1b8eddbaa7175ab3d00
-rw------- 1 root root 262144 Apr 15 23:09 metadata.db
drwxr-xr-x 3 root root 4096 Apr 15 23:09 my-volume
2
3
4
5
6
7
8
可以查看到my-volume的信息:
dev@devops:~$ docker volume ls
DRIVER VOLUME NAME
local 4f5936b11140b7664aa4dcb5f7043fdef96b80d76b23b0410da8ee9e7caa653d
local c501e25d1cde249a7fbd7f2e2c3155ca2fd876b7a28df1b8eddbaa7175ab3d00
local my-volume
dev@devops:~$ docker volume inspect my-volume
[
{
"CreatedAt": "2021-04-15T23:09:18+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-volume/_data",
"Name": "my-volume",
"Options": {},
"Scope": "local"
}
]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
可以看到,volume在host机器的目录为/var/lib/docker/volumes/my-volume/_data
。此时,如果my-volume不存在,那么docker会自动创建my-volume,然后再挂载。
也可以不指定host上的volume:
docker run -it -v /mydata alpine sh
此时docker将自动创建一个匿名的volume,并将其挂载到container中的/mydata目录。匿名volume在host机器上的目录路径类似于:/var/lib/docker/volumes/4f5936b11140b7664aa4dcb5f7043fdef96b80d76b23b0410da8ee9e7caa653d/_data
。
除了让docker帮我们自动创建volume,我们也可以自行创建:
docker volume create my-volume-2
然后将这个已有的my-volume-2挂载到container中:
docker run -it -v my-volume-2:/mydata alpine sh
需要注意的是,与bind mount不同的是,如果volume是空的而container中的目录有内容,那么docker会将container目录中的内容拷贝到volume中,但是如果volume中已经有内容,则会将container中的目录覆盖。