docker设置devicemapper存储驱动

[TOC]

背景

在 Ubuntu/Debian 上有 UnionFS 可以使用,如 aufs 或者 overlay2,而 CentOS 和 RHEL 的内核中没有相关驱动。因此对于这类系统,一般使用 devicemapper 驱动利用 LVM 的一些机制来模拟分层存储。这样的做法除了性能比较差外,稳定性一般也不好,而且配置相对复杂。Docker 安装在 CentOS/RHEL 上后,会默认选择 devicemapper,但是为了简化配置,其 devicemapper 是跑在一个稀疏文件模拟的块设备上,也被称为 loop-lvm。这样的选择是因为不需要额外配置就可以运行 Docker,这是自动配置唯一能做到的事情。但是 loop-lvm 的做法非常不好,其稳定性、性能更差,无论是日志还是 docker info 中都会看到警告信息。官方文档有明确的文章讲解了如何配置块设备给 devicemapper 驱动做存储层的做法,这类做法也被称为配置 direct-lvm

除了前面说到的问题外,devicemapper + loop-lvm 还有一个缺陷,因为它是稀疏文件,所以它会不断增长。用户在使用过程中会注意到 /var/lib/docker/devicemapper/devicemapper/data 不断增长,而且无法控制。这个稀疏文件的空间释放后基本不进行垃圾回收的问题。因此往往会出现即使删除了文件内容,空间却无法回收,随着使用这个稀疏文件一直在不断增长。

所以对于 CentOS/RHEL 的用户来说,在没有办法使用 UnionFS 的情况下,一定要配置 direct-lvmdevicemapper,无论是为了性能、稳定性还是空间利用率。

配置过程

1.直接修改daemon.json

官方文档里面有两种方法,第一种就是直接修改/etc/docker/daemon.json 这个文档,然后重启docker即可.

1
2
3
4
5
6
7
8
9
10
11
{
"storage-driver": "devicemapper",
"storage-opts": [
"dm.directlvm_device=/dev/xdf", #这里修改成主机存储谁被,可以整个硬盘,或者一个分区
"dm.thinp_percent=95",
"dm.thinp_metapercent=1",
"dm.thinp_autoextend_threshold=80",
"dm.thinp_autoextend_percent=20",
"dm.directlvm_device_force=false"
]
}

修改完了之后,重启docker即可

1
2
3
4
5
6
7
8
9
10
11
sudo systemctl restart docker
docker info

Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 17.03.1-ce
Storage Driver: devicemapper #看这里
....

但是有些时候修改了配置,并不会生效.需要手动修改添加逻辑卷等.

2.手动修改配置

a.安装依赖包

1
yum install lvm2

b.创建逻辑卷,以官方的/dev/xvdf为例

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
$ sudo pvcreate /dev/xvdf  #创建物理卷
Physical volume "/dev/xvdf" successfully created.
$ sudo vgcreate docker /dev/xvdf #创建卷组
Volume group "docker" successfully created
$ sudo lvcreate --wipesignatures y -n thinpool docker -l 95%VG
Logical volume "thinpool" created.
$ sudo lvcreate --wipesignatures y -n thinpoolmeta docker -l 1%VG
Logical volume "thinpoolmeta" created.
$ sudo lvconvert -y \
--zero n \
-c 512K \
--thinpool docker/thinpool \
--poolmetadata docker/thinpoolmeta

WARNING: Converting logical volume docker/thinpool and docker/thinpoolmeta to
thin pool's data and metadata volumes with metadata wiping.
THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)
Converted docker/thinpool to thin pool.

$ sudo vi /etc/lvm/profile/docker-thinpool.profile #配置比例,其实不写也可以
activation {
thin_pool_autoextend_threshold=80
thin_pool_autoextend_percent=20
}

$ sudo lvchange --metadataprofile docker-thinpool docker/thinpool
Logical volume docker/thinpool changed.

$ sudo lvs -o+seg_monitor
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert Monitor
thinpool docker twi-a-t--- 95.00g 0.00 0.01 monitored

c.修改配置

1
2
3
4
5
6
7
8
9
10
11
$ mkdir /var/lib/docker.bk  #删除或备份/var/lib/docker
$ mv /var/lib/docker/* /var/lib/docker.bk
$ cat /etc/docker/daemon.json #手动创建了这些设备,启动docker的时候就按照这个配置自动挂在
{
"storage-driver": "devicemapper",
"storage-opts": [
"dm.thinpooldev=/dev/mapper/docker-thinpool",
"dm.use_deferred_removal=true",
"dm.use_deferred_deletion=true"
]
}

d.启动看效果

1
2
3
4
5
6
7
8
9
10
11
12
$ sudo systemctl start docker
$ docker info

Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 17.03.1-ce
Storage Driver: devicemapper
Pool Name: docker-thinpool