html,body { font-size: 12pt }
body { font-family: Helvetica, "Hiragino Sans GB", "微软雅黑", "Microsoft YaHei UI", SimSun, SimHei, arial, sans-serif; line-height: 1.6; margin: 0 auto; padding: 1.25rem 1rem }
h1,h2,h3,h4,h5,h6 { margin: 1.25rem 0 0.625rem; padding: 0; font-weight: bold }
h1 { font-size: 1.67rem }
h2 { font-size: 1.5rem }
h3 { font-size: 1.25rem }
h4 { font-size: 1.17rem }
h5 { font-size: 1rem }
h6 { font-size: 1rem; color: #777777; margin: 1rem 0 }
div,p,ul,ol,dl,li { margin: 0 }
blockquote,table,pre,code { margin: 8px 0 }
ul,ol { padding-left: 2rem }
ol.wiz-list-level1>li { list-style-type: decimal }
ol.wiz-list-level2>li { list-style-type: lower-latin }
ol.wiz-list-level3>li { list-style-type: lower-roman }
blockquote { padding: 0 0.75rem }
blockquote>:first-child { margin-top: 0 }
blockquote>:last-child { margin-bottom: 0 }
img { border: 0; max-width: 100%; height: auto !important; margin: 2px 0 }
table { border-collapse: collapse; border: 1px solid #bbbbbb }
td,th { padding: 4px 8px; border-collapse: collapse; border: 1px solid #bbbbbb; min-height: 28px }
.wiz-hide { display: none !important }
应用背景:
Docker最先就是跑在Ubuntu和Debian上的,使用的就是aufs存储器.因为docker越来越流行,许多公司希望在rhel上使用,但是上游内核中并没有包括aufs,所以rhel不能使用aufs. 最终,开发者们开发了一个新的后端存储引擎devicemapper,基于已有的Device Mapper技术,并且使docker 支持可插拔,现在全世界有很多真实案例在生产环境中使用devicemapper.
因为上述的原因,对于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-lvm 给 devicemapper,无论是为了性能、稳定性还是空间利用率。
配置环境:
centos 7
docker 1.12
配置步骤:
1.停止 docker daemon(root)
#> systemctl stop docker
2.创建相关逻辑卷以及 thinpool(root)
(1).分配磁盘
分配磁盘予服务器,利用 fdisk 进行分区。
(2).创建 PV
例如:已分配磁盘 /dev/sdb1
#> pvcreate /dev/sdb1
(3).创建 VG
#> vgcreate dockervg /dev/sdb1
(4).创建 thinpool 逻辑卷
#> lvcreate --wipesignatures y -n thinpool -l 50%VG dockervg
lvcreate --wipesignatures y -n thinpoolmeta -l 1%VG dockervg
可通过如下命令检验
#> lvscan
(5).转换成 thinpool
#> lvconvert -y --zero n -c 512K --thinpool dockervg/thinpool --poolmetadata dockervg/thinpoolmeta
输出结果类似如下。
可以通过如下命令查看 thinpool 状态
#> lvs -o lv_name,data_percent,metadata_percent,lv_size,lv_metadata_size,data_lv,metadata_lv
输出结果类似如下。
注意:其中 LSize 即为 Data 的空间大小,Msize 即为 MetaData 的空间大小,Data 为 Data 对应逻辑卷,Meta 为 MetaData 对应逻辑卷。
(6).扩展 thinpool(选做)
该步骤选做,用于 MetaData 或 Data 空间不足时的扩容。
例如:MetaData 对应逻辑卷路径为 /dev/mapper/dockervg-thinpool_tmeta,则扩容命令如下。
#> lvresize -L +1G /dev/mapper/dockervg-thinpool_tmeta
例如:thinpool 整体对应逻辑卷路径为 dockervg-thinpool,则扩容命令如下。
#> lvresize -L +5G /dev/mapper/dockervg-thinpool
3.备份并删除 Docker 存储目录(root)
(1).备份
#> mkdir /var/lib/docker.bk
mv /var/lib/docker/* /var/lib/docker.bk
(2).删除原存储目录
#> rm -rf /var/lib/docker/*
4.修改 Docker 启动参数并启动(root)
修改 daemon.json 配置文件
#> vi /etc/docker/daemon.json
修改为如下内容。
{
"storage-driver": "devicemapper",
"storage-opts": [
"dm.thinpooldev=/dev/mapper/dockervg-thinpool",
"dm.use_deferred_removal=true",
"dm.use_deferred_deletion=true",
"dm.basesize=25G"
]
}
注意:dm.basesize 指定了 images 以及 container 可以扩展到的最大空间。
5.重启 Docker 服务(root)
#> systemctl daemon-reload
systemctl start docker
6.验证(root)
a.docker info 检查
#> docker info
结果类似如下。
其中,方框内信息表明以使用了 direct_lvm 的 Docker 存储模式,同时images 以及 container 可以扩展到的最大空间已修改所需大小。
b.试运行 hello-world
#> docker pull hello-world
docker run hello-world
结果类似如下,即表明运行正常。
参考资料:
https://docs.docker.com/engine/userguide/storagedriver/device-mapper-driver/#configure-direct-lvm-mode-for-production