devicemapper的功能就是根据逻辑设备和物理设备的映射关系处理逻辑设备收到的io请求。
docker的devicemapper存储驱动是使用device mapper的精简配置thin-provisioning和快照功能实现镜像分层,这个模块用了2个块设备,一个保存数据,一个保存元数据,2个块设备构成thin pool用于创建存储镜像的块设备。在资源池之上会创建有文件系统的基础设备,会在基础设备上创建快照创建新的设备用于存储镜像。新创建的设备在写入内容前不会分配空间,也就是copy on write。
官网有自动配置和手动配置2种方式,自动配置修改/etc/docker/daemon.json重启可以了
{
"storage-driver": "devicemapper",
"storage-opts": [
"dm.directlvm_device=/dev/sdb1",
"dm.thinp_percent=95",
"dm.thinp_metapercent=1",
"dm.thinp_autoextend_threshold=80",
"dm.thinp_autoextend_percent=20",
"dm.directlvm_device_force=false"
]
}
会自动创建一个docker的vg,和thinpool,然后通过lvs和lvs -a查看lv的使用空间情况,journalctl -fu dm-event.service查看lv日志,设置dm.min_free_space可以发出剩余空间告警。
扩容方面,先增加docker的vg大小,然后分配给docker/thinpool
lvextend -l+100%FREE -n docker/thinpool
在docker info中通过Data Space Available和Metadata Space Available可查看thinpool大小
重启机器后,如果docker无法启动并报Non existing device,则需要
lvchange -ay docker/thinpool
重新激活lv
当启动一个容器时,mount |grep devicemapper可以看到 thinpool会提供一个块设备挂载在/var/lib/docker/devicemapper/mnt下
mount |grep devicemapper
/dev/mapper/docker-8:1-2097416-c75b620555613a6db1e23ea65e6c1bda8d05da06ac9f6a8cca1f410b83fa5b77 on /var/lib/docker/devicemapper/mnt/c75b620555613a6db1e23ea65e6c1bda8d05da06ac9f6a8cca1f410b83fa5b77 type ext4 (rw,relatime,stripe=128,data=ordered)
/var/lib/docker/devicemapper/metadata/下保存devicemappper的配置,包括image和container,snapshot的配置,用json格式保存
snapshot作用是layers可以多个容器公用,只存储一份数据,只有写的时候才分配空间,每次分配64k一个块,因为是块级操作,可以在读写层同时修改,snapshot可以用os的备份工具,只要备份目录/var/lib/docker/devicemapper。
官网的devicemapper层级图
thinpool上面是一个base device,上面有一个文件系统,从base device创建snapshot生成新的层级
优化措施,可以用ssd做thinpool,devicemapper比其他存储驱动更占内容,当容器一个文件的多个块同时被修改时会加载到内存,所以不适合高密集的io操作。