Docker 1.12 配置 direct-lvm
作者:佚名 来源:小影志 时间:2018-06-07
一、概念
Device Mapper
Docker 最先是跑在 Ubuntu 和 Debian 上的,使用 aufs 存储器。由于 Docker 越来越流行,许多公司希望在 RHEL 上使用,但是上游内核中没有包括 aufs,所以 RHEL 不能使用 aufs。最终开发者们开发了一个新的后端存储引擎 Device Mapper,基于已有的 Device Mapper 技术,并且使 Docker 支持可插拔,现在全世界有很多真实案例在生产环境使用 Device Mapper。
镜像层与共享
Device Mapper 存储每个镜像和容器在自己的虚拟设备上,也就是说这些设备是按需分配(copy-on-write snapshot devices),Device Mapper 技术是工作在 block 级别的而不是文件级别的。
Device Mapper 创建镜像的方式是:
- Device Mapper 基于块设备或 loop mounted sparse files 来创建一个虚拟池。
- 然后在上面创建一个有文件系统的基础设备(base device)。
- 每个镜像层就是基于这个基础设备的 COW 快照(snapshot),也就是说这些快照初始化时是空的,只有数据写入时才会占用池中的空间。
loop-lvm 和 direct-lvm 区别
因为上述的原因,对于 CentOS/RHEL 这类没有相关驱动的系统,一般使用 Device Mapper 驱动利用 LVM 的一些机制来模拟分层存储。这样的做法除了性能比较差之外,稳定性一般也不好,而且配置相对复杂。Docker 安装在 CentOS/RHEL 上后,会默认选择 Device Mapper,但是为了简化配置,其 Device Mapper 是跑在一个稀疏文件模拟的块设备上,也被称为 loop-lvm。这样的选择是因为不需要额外配置就可以运行 Docker,这是自动配置唯一能做到的事情。但是 loop-lvm 的做法非常不好,其稳定性、性能更差,无论是日志还是 docker info 中都会看到警告信息。官方文档有明确的文章讲解了如何配置块设备给 Device Mapper 驱动做存储层的做法,这类做法也被称为配置 direct-lvm。
除了前面说到的问题外,devicemapper + loop-lvm 还有一个缺陷,因为它是稀疏文件,所以它会不断增长。用户在使用过程中会注意到 /var/lib/docker/devicemapper/devicemapper/data
不断增长,而且无法控制。很多人会希望删除镜像或者可以解决这个问题,结果发现效果并不明显。原因就是这个稀疏文件的空间释放后基本不进行垃圾回收的问题。因此往往会出现即使删除了文件内容,空间却无法回收,随着使用这个稀疏文件一直在不断增长。
所以对于 CentOS/RHEL 的用户来说,在没有办法使用 UnionFS 的情况下,一定要配置 direct-lvm 给 devicemapper,无论是为了性能、稳定性还是空间利用率。
或许有人注意到了 CentOS 7 中存在被 backports 回来的 overlay 驱动,不过 CentOS 里的这个驱动达不到生产环境使用的稳定程度,所以不推荐使用。
Device Mapper: loop-lvm
默认 CentOS 7 下 Docker 使用的 Device Mapper 设备默认使用 loopback 设备,后端为自动生成的稀疏文件,如下:
[root@k8s01 ~]# ls -lsh /var/lib/docker/devicemapper/devicemapper/
total 2.4G
2.4G -rw------- 1 root root 100G Mar 20 18:34 data
4.0M -rw------- 1 root root 2.0G Mar 20 18:34 metadata
data(存放数据)和 metadata(存放元数据)的大小从输出可以看出初始化默认为 100G 和 2G 大小,都是稀疏文件,使用多少占用多少。
Device Mapper: direct-lvm
生产环境下应该使用 direct-lvm,如果之前有镜像在 loop-lvm 模式下创建,需要切换,则需要把镜像做备份(push 到 hub 或者私有 registry)。所以最好的做法,还是在刚刚给 CentOS 服务器安装 Docker 的时候,直接做好配置。
二、手动配置 DIRECT-LVM 模式
配置 LVM 及 thinpool
1. 挂载新的磁盘
[root@k8s01 ~]# fdisk /dev/sdb #创建LVM分区,创建过程省略
2. 停止 Docker 进程
[root@k8s01 ~]# systemctl stop docker
3. 安装软件包
- RHEL/CentOS: device-mapper-persistent-data, lvm2, and all dependencies
- Ubuntu/Debian: thin-provisioning-tools, lvm2, and all dependencies
4. 创建物理卷
[root@k8s01 ~]# pvcreate /dev/sdb1
Physical volume "/dev/sdb1" successfully created.
5. 创建卷组
[root@k8s01 ~]# vgcreate docker /dev/sdb1
6. 创建 2 个名为 thinpool 和 thinpoolmeta 的逻辑卷
[root@k8s01 ~]# lvcreate --wipesignatures y -n thinpool docker -l 95%VG
WARNING: xfs signature detected on /dev/docker/thinpool at offset 0. Wipe it? [y/n]: y
Wiping xfs signature on /dev/docker/thinpool.
Logical volume "thinpool" created.
[root@k8s01 ~]# lvcreate --wipesignatures y -n thinpoolmeta docker -l 1%VG
Logical volume "thinpoolmeta" created.
剩余的 4% 留给它们自动扩展
7. 转换成 thinpool
[root@k8s01 ~]# lvconvert -y \
--zero n \
-c 512K \
--thinpool docker/thinpool \
--poolmetadata docker/thinpoolmeta
8. 设置 thinpool 的自动扩展参数
[root@k8s01 ~]# vi /etc/lvm/profile/docker-thinpool.profile
activation {
thin_pool_autoextend_threshold=80
thin_pool_autoextend_percent=20
}
应用上述配置
[root@k8s01 ~]# lvchange --metadataprofile docker-thinpool docker/thinpool
Logical volume docker/thinpool changed.
当空间大于 80% 时进行扩展,扩展的大小是空闲空间的 20%。
9. 查看 thinpool 是否是已监视状态
[root@k8s01 ~]# 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
配置 Docker
1. 备份 /var/lib/docker
[root@k8s02 ~]# mkdir /var/lib/docker.bk
[root@k8s02 ~]# mv /var/lib/docker/* /var/lib/docker.bk
2. 编辑 /etc/docker/daemon.json
{
"storage-driver": "devicemapper",
"storage-opts": [
"dm.thinpooldev=/dev/mapper/docker-thinpool",
"dm.use_deferred_removal=true",
"dm.use_deferred_deletion=true"
]
}
3. 启动 Docker
systemctl start docker
4. 验证配置
[root@k8s01 ~]# docker info
Containers: 30
Running: 30
Paused: 0
Stopped: 0
Images: 15
Server Version: 18.02.0-ce
Storage Driver: devicemapper
Pool Name: docker-thinpool
Pool Blocksize: 524.3kB
Base Device Size: 10.74GB
Backing Filesystem: xfs
Udev Sync Supported: true
Data Space Used: 2.412GB
Data Space Total: 816GB
Data Space Available: 813.6GB
Metadata Space Used: 1.573MB
Metadata Space Total: 8.586GB
Metadata Space Available: 8.584GB
Thin Pool Minimum Free Space: 81.6GB
Deferred Removal Enabled: true
Deferred Deletion Enabled: true
Deferred Deleted Device Count: 0
Library Version: 1.02.107-RHEL7 (2015-10-14)
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 9b55aab90508bd389d7654c4baf173a981477d55
runc version: 9f9c96235cc97674e935002fc3d78361b696a69e
init version: 949e6fa
Security Options:
seccomp
Profile: default
Kernel Version: 3.10.0-327.28.3.el7.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 7.633GiB
Name: k8s01
ID: QY5Y:NSF5:DRG6:DFAF:WA53:WYSW:BKEA:FKY6:L3MS:5KU4:VJJL:3JUB
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
HTTP Proxy: http://127.0.0.1:8118/
No Proxy: localhost,127.0.0.1,gj7l88s1.mirror.aliyuncs.com,docker.io,registry.cn-hangzhou.aliyuncs.com,acs-cn-hangzhou-mirror.oss-cn-hangzhou.aliyuncs.com
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
如果 Data file 和 Metadata file 为空,Pool Name 是 docker-thinpool
,则配置完成。
确认没问题之后,删除 /var/lib/docker.bk
。
参考链接
参考命令
查看挂载信息
[root@k8s01 ~]# lsblk
?
?
P.S. 本文是帮朋友代为发表,非博主所写。