6.docker存储

docker

docker存储

docker有两种存储资源,Data Volume、管理镜像层与容器层的 storage driver

storage driver

容器是由最上层可写容器层、下面若干的镜像层,这样会有一下特性。

  1. 新数据会保存在最上层的容器层中
  2. 修改原现有的数据会将镜像层中将数据复制到容器层中,修改后的数据保存在容器层中,镜像层保持不变
  3. 多层中有同名文件时,只能看到以及实际使用的是最上层中的文件

docker支持多种存储驱动,AUFS、Btrfs、Device mapper、OverlayFS、ZFS,没有哪个 driver 能够适应所有的场景,docker官方给出的建议是使用发行版默认的存储驱动,docker在安装时会根据当前系统选择默认的存储驱动。
存储驱动

1
2
3
#查看当前docker使用的~]Storage Driver
~]# docker info |grep "Storage Driver"
Storage Driver: overlay2

当然也可以手动进行修改

1
2
3
4
~]# vim /etc/docker/daemon.json    
{
"storage-driver": "overlay2"
}

Data Volume

对于有持久化存储需求的容器来说需要使用Data Volume来持久化存储数据。
docker volume实际是宿主机文件系统的一部分,volume可使用的容量取决于文件系统可用容量,不能设置volume容量。
docker volume有两种类型:bind mountdocker managed volume

bind mount

bind mount是宿主机上存在的一个文件文件夹。当容器中挂载点中原本有文件则会被隐藏,显示的为bind mount的内容,容器中默认对bind mount有可读可写权限
docker run -v <host path>:<container path>[:ro],加上:ro表示容器中只有可读权限,只有宿主机数据的修改权限。

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
# 将本地/root/test_volume文件夹挂载到容器中/root/test_volume
~]# docker run -it -d -v /root/test_volume:/root/test_volume --name="busybox1" busybox
4126231bdaaf1f04f3ae33d1d2259d996c69399aec9f04b1243508257ae4c8c4
~]# docker inspect busybox1
...
"Mounts": [
{
"Type": "bind",
"Source": "/root/test_volume",
"Destination": "/root/test_volume",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
...

~]# docker run -it -d -v /root/test_volume:/root/test_volume:ro --name="busybox2" busybox
705cc2de09e05da2bc72a8511c6130d63f2398b8c1e053f359e3ef2b45506d64
~]# docker inspect busybox2
...
"Mounts": [
{
"Type": "bind",
"Source": "/root/test_volume",
"Destination": "/root/test_volume",
"Mode": "ro",
"RW": false,
"Propagation": "rprivate"
}
],
...

docker managed volume

docker managed volume即为数据卷,创建的数据卷会保存在/var/lib/docker/volumes中。当容器需要数据卷时可以直接-v <container path>,此时会自动创建一个名字为一串数字的数据卷并挂载到指定容器路径。与bind mount不同的是,当容器挂载路径中有文件时,会将文件拷贝到数据卷中,即原有文件不会被隐藏。
docker run -v [<volume_name>:]<container path>[:ro],使用数据卷也可以将容器内的权限修改为只读,但必须使用提前创建的数据卷。
数据卷相关操作:
docker volume create <volume_name>:创建数据卷
docker volume inspect <volume_name>:查看数据卷信息
docker volume rm <volume_name>:删除指定数据卷
docker volume prune:删除空闲的数据卷
docker volume ls:查看所有的数据卷

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
~]#docker volume create testvolume
testvolume

~]# docker run -it -d -v testvolume:/root/test_volume:ro --name=test busybox
12851737a86ee205c918ba50529c486b326c7e620bd1d93206eebd7e4eaaeceb

~]# docker inspect testvolume
[
{
"CreatedAt": "2022-10-21T02:13:34+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/testvolume/_data",
"Name": "testvolume",
"Options": {},
"Scope": "local"
}
]

~]# docker inspect test
...
"Mounts": [
{
"Type": "volume",
"Name": "testvolume",
"Source": "/var/lib/docker/volumes/testvolume/_data",
"Destination": "/root/test_volume",
"Driver": "local",
"Mode": "ro",
"RW": false,
"Propagation": ""
}
],
...

数据卷容器

如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。
首先创建一个数据卷容器。

1
~]# docker run -it -v /dbdata --name dbdata ubuntu:18.04 

可以在其他容器中使用–volumes-from来挂载dbdata容器中的数据卷。
可以多次使用–volumes-from参数来从多个容器挂载多个数据卷,还可以从其他已经挂载了容器卷的容器来挂载数据卷。

1
2
docker run -it --volumes-from dbdata --name db1 ubuntu:18.04
docker run -it --volumes-from dbdata --name db2 ubuntu:18.04

这样三个容器任何一方在该目录下的写入,其他容器都可以看到。删除挂载数据卷的容器,数据卷不会被删除。

data-packed volume container

data-packed volume container就是将数据打包ADD到镜像中,并在dockerfile中使用VOLUME将数据卷挂载位置设置为镜像中文件位置,在容器启动时会自动创建一个数据卷,并将数据拷贝到数据卷中。再通过数据卷容器的方式共享给其他容器。