转自)前,请先停止docker。
1.由于使用的是虚拟机,先创建个新的分区(或其他块设备):
$ fdisk /dev/sda
按提示创建一个新的分区: /dev/sda4
2.通过pvcreate
命令在 /dev/sda4块设备上创建物理卷pv:
$ pvcreate /dev/sda4
Physical volume "/dev/sda4" successfully created.
3.通过 vgcreate 命令在同一个设备上创建名为 docker的卷组vg:
$ vgcreate docker /dev/sda4
Volume group "docker" successfully created
4.通过 lvcreate 命令创建两个名为 thinpool 和 thinpoolmeta 的逻辑卷lv:
最后一个参数指定可用空间的大小,以便在空间不足时自动扩展数据或元数据。这些是推荐值。
$ lvcreate --wipesignatures y -n thinpool docker -l 95%VG
Logical volume "thinpool" created.
$ lvcreate --wipesignatures y -n thinpoolmeta docker -l 1%VG
Logical volume "thinpoolmeta" created.
5.通过 lvconvert 命令把thinpool
数据卷和thinpoolmeta
元数据卷换为精简池(Thin Pool):
$ lvconvert -y \
--zero n \
-c 512K \
--thinpool docker/thinpool \
--poolmetadata docker/thinpoolmeta
Thin pool volume with chunk size 512.00 KiB can address at most 126.50 TiB of data.
WARNING: Converting 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 and docker/thinpoolmeta to thin pool.
6.通过 lvm 配置文件配置精简池的自动扩展:
$ vi /etc/lvm/profile/docker-thinpool.profile
指定 thin_pool_autoextend_threshold 和 thin_pool_autoextend_percent 的值。
- thin_pool_autoextend_threshold 是触发 lvm 尝试自动扩展可用空间的空间使用率百分比(100 = 禁用,不推荐)。
- thin_pool_autoextend_percent 是触发自动扩展时会扩展的大小(0 = 禁用)。
下面的例子在磁盘使用率达到 80% 时自动增加 20% 的容量:
activation {
thin_pool_autoextend_threshold=80
thin_pool_autoextend_percent=20
}
7.使用 lvchange 命令应用 LVM 配置文件:
$ lvchange --metadataprofile docker-thinpool docker/thinpool
Logical volume docker/thinpool changed.
8.启用对主机上逻辑卷的监视:
没有这一步,即使存在 LVM 配置文件,也不会自动扩展。
$ lvs -o+seg_monitor
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert Monitor
thinpool docker twi-a-t--- <19.00g 0.00 0.03 monitored
9.如果之前在这个主机上运行过 Docker,或 /var/lib/docker/ 文件已经存在,移除文件以便让 Docker 使用新的 LVM pool 来存储镜像和容器:
$ mkdir /var/lib/docker.bk
$ mv /var/lib/docker/* /var/lib/docker.bk
10.编辑 /etc/docker/daemon.json 并配置 devicemapper存储驱动程序所需的选择。增加下面的内容:
{
"storage-driver": "devicemapper",
"storage-opts": [
"dm.thinpooldev=/dev/mapper/docker-thinpool",
"dm.use_deferred_removal=true",
"dm.use_deferred_deletion=true"
]
}
11.启动 Docker:
$ systemctl start docker
12.通过 docker info 命令验证 Docker 使用了新的配置:
$ docker info
Client:
Debug Mode: false
Server:
Containers: 0
Running: 0
Paused: 0
Stopped: 0
Images: 0
Server Version: 19.03.8
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: 20.45MB
Data Space Total: 20.4GB
Data Space Available: 20.38GB
Metadata Space Used: 61.44kB
Metadata Space Total: 213.9MB
Metadata Space Available: 213.8MB
Thin Pool Minimum Free Space: 2.039GB
......
如果 Docker 配置正确,Pool Name 应该是 docker-thinpool
。
13.可以使用lsblk命令从操作系统角度查看设备和对应的池:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 41G 0 disk
├─sda1 8:1 0 300M 0 part /boot
├─sda2 8:2 0 2G 0 part [SWAP]
├─sda3 8:3 0 17.7G 0 part /
└─sda4 8:4 0 20G 0 part
├─docker-thinpool_tmeta 253:0 0 204M 0 lvm
│ └─docker-thinpool 253:2 0 19G 0 lvm
└─docker-thinpool_tdata 253:1 0 19G 0 lvm
└─docker-thinpool 253:2 0 19G 0 lvm
sr0 11:0 1 1024M 0 rom
dmsetup 工具
命令参考:dmsetup - Unix, Linux Command
常用参数:
-
dmsetup info [device_name]
: 输出所有目前配置的 Device Mapper 设备信息 -
dmsetup ls
: 命令列出映射的设备的设备名称列表 -
dmsetup status [device_name]
: 输出结果是所有目前配置的设备映射器设备信息 -
dmsetup message device_name sector message
: 给设备发送消息 -
dmsetup create device_name --table "0 20971520 thin 253:3 185"
: 创建dm设备 -
dmsetup remove device_name
: 移除dm设备
dmsetup 工具的使用
查看运行容器、镜像的device信息
获取容器的DeviceName:
$ docker inspect ba3ee5be798c | grep DeviceName
"DeviceName": "docker-253:2-2016050192-752dc1a74ce95c22dae84e257aa02119bb1da1feb1a6ff372d4ad9db08cf7bd4",
其中docker-253:2-2016050192-752dc1a74ce95c22dae84e257aa02119bb1da1feb1a6ff372d4ad9db08cf7bd4
即为dm设备的名字。
查看Mapping Table:
$ dmsetup table | grep docker-253:2-2016050192-752dc1a74ce95c22dae84e257aa02119bb1da1feb1a6ff372d4ad9db08cf7bd4
docker-253:2-2016050192-752dc1a74ce95c22dae84e257aa02119bb1da1feb1a6ff372d4ad9db08cf7bd4: 0 20971520 thin 253:3 163
或
dmsetup table docker-253:2-2016050192-752dc1a74ce95c22dae84e257aa02119bb1da1feb1a6ff372d4ad9db08cf7bd4
0 20971520 thin 253:3 163
其中0 20971520 thin 253:3 163
的解释为:
logical_start_sector num_sectors target_type target_args
开始扇区 扇区数 设备类型 设备参数
0 20971520 thin 253:3 163
20971520
为扇区数,一个扇区大小为512kb,总共为10g
即:20971520个扇区 = 20971520*512kb = 10,737,418,240kb = 10 * 2^30 kb = 10g
取出镜像的文件
查看镜像的Device信息
$ docker inspect centos | grep Device
"DeviceId": "13",
"DeviceName": "docker-8:3-36654382-89b4c8a4c8d56fde69622bc6e8df5f402eebf4b0f026966b56c65de7cd4517c0",
"DeviceSize": "10737418240"
使用dmsetup ls
命令查看docker-thinpool
设备的主设备号和次设备号
$ dmsetup ls
centos-dm (253:4)
docker-thinpool_tdata (253:1)
docker-thinpool_tmeta (253:0)
docker-thinpool (253:2)
得到主设备号和次设备号为253:2
生成Mapping Table:0 20971520 thin 253:2 13
- 0 : 开始扇区
- 20971520 : 删除数,由DeviceSize除以每个扇区的大小得到,即 10737418240/512 = 20971520
- thin : 设备类型
- 253:2 13 : 设备参数,由
[主设备号]:[次设备号] [DeviceId]
组成
创建dm设备:dmsetup create centos-dm --table "0 20971520 thin 253:2 13"
再次使用dmsetup ls
命令,发现新增的名为centos-dm
的dm设备:
$ dmsetup ls
centos-dm (253:4)
docker-thinpool_tdata (253:1)
docker-thinpool_tmeta (253:0)
docker-thinpool (253:2)
查看/dev/mapper目录,发现新增了1个链接文件,链接到dm-4设备
$ ll /dev/mapper
lrwxrwxrwx. 1 root root 7 Apr 26 02:55 centos-dm -> ../dm-4
把dm-4设备挂载出来
$ mount /dev/dm-4 /tmp/test
查看挂载:
$ mount | grep centos-dm
/dev/mapper/centos-dm on /tmp/test type xfs (rw,relatime,seclabel,attr2,inode64,sunit=1024,swidth=1024,noquota)
查看镜像文件:
$ ll /tmp/test
total 8
-rw-------. 1 root root 64 Apr 23 01:05 id
drwxr-xr-x. 14 root root 4096 Apr 23 01:05 rootfs
rootfs目录中即为镜像里的文件:
$ ll /tmp/test/rootfs/
lrwxrwxrwx. 1 root root 7 Apr 6 2017 bin -> usr/bin
drwxr-xr-x. 47 root root 4096 Apr 6 2017 etc
drwxr-xr-x. 2 root root 6 Nov 5 2016 home
lrwxrwxrwx. 1 root root 7 Apr 6 2017 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Apr 6 2017 lib64 -> usr/lib64
drwx------. 2 root root 6 Apr 6 2017 lost+found
drwxr-xr-x. 2 root root 6 Nov 5 2016 media
drwxr-xr-x. 2 root root 6 Nov 5 2016 mnt
取出运行中/停掉的容器中的内容
使用docker inspect
命令查看容器的device信息:
$ docker inspect {containerId} | grep Device
"DeviceId": "21",
"DeviceName": "docker-8:3-36654382-804429bdfdec16a1a3d6f3e5fbbb3dcbc4494997b8d392c83a37aead924a398c",
"DeviceSize": "10737418240"
之后的步骤与取出镜像的文件
的方法相同。
给运行中的容器进行快照
使用docker inspect
命令查看容器的DeviceName和DeviceId:
$ docker inspect {containerId} | grep Device
"DeviceId": "21",
"DeviceName": "docker-8:3-36654382-804429bdfdec16a1a3d6f3e5fbbb3dcbc4494997b8d392c83a37aead924a398c",
"DeviceSize": "10737418240"
向dm设备发送create_snap
的消息:
dmsetup message /dev/mapper/docker-thinpool 0 "create_snap 22 21"
其中:
- 21 : 为容器的DeviceId
- 22 : 为自定的目标DeviceId
使用dmsetup create
命令创建dm设备:
$ dmsetup create dockersnap --table "0 20971520 thin /dev/mapper/docker-thinpool 22"
使用dmsetup ls
命令,发现新增的名为dockersnap
的dm设备:
$ dmsetup ls
centos-dm (253:4)
docker-thinpool_tdata (253:1)
docker-thinpool_tmeta (253:0)
docker-thinpool (253:2)
docker-8:3-36654382-804429bdfdec16a1a3d6f3e5fbbb3dcbc4494997b8d392c83a37aead924a398c (253:3)
dockersnap (253:5)
接下来即可使用之前的步骤mount出来。
devicemapper存储驱动下统计容器使用量
由于容器启动后会对镜像进行一次快照,并mount到一个挂载点(在/var/lib/docker/devicemapper/mnt
目录中),可以考虑使用df
命令结果里的Used
字段:
$ df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda3 xfs 18G 4.5G 14G 26% /
devtmpfs devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs tmpfs 1.9G 9.1M 1.9G 1% /run
tmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/sda1 xfs 297M 144M 154M 49% /boot
tmpfs tmpfs 378M 0 378M 0% /run/user/0
/dev/dm-3 xfs 10G 57M 10G 1% /var/lib/docker/devicemapper/mnt/804429bdfdec16a1a3d6f3e5fbbb3dcbc4494997b8d392c83a37aead924a398c
可以看到/dev/dm-3
对应的挂载点/var/lib/docker/devicemapper/mnt/804429bdfdec16a1a3d6f3e5fbbb3dcbc4494997b8d392c83a37aead924a398c
,其Used
值为57M。
挂载点路径中有一串很长的hash串,这个串与DeviceName
中hash串相对应:
$ docker inspect 17a65165d9b6 | grep DeviceName
"DeviceName": "docker-8:3-36654382-804429bdfdec16a1a3d6f3e5fbbb3dcbc4494997b8d392c83a37aead924a398c",
由于格式化后的xfs
文件系统自身的metadata也会占用一定空间,所以这个Used
值往往比mount出的目录要大(使用du
命令进行统计):
$ cd \
/var/lib/docker/devicemapper/mnt/804429bdfdec16a1a3d6f3e5fbbb3dcbc4494997b8d392c83a37aead924a398c
$ du -sh *
4.0K id
24M rootfs
可见mount出的目录的总大小为24M,并不与Used
值相同。
当然,这个差异也与df
与du
命令的统计方法有关。
注意:在启动容器时使用-v
参数挂载出来的目录或文件,都不包含在df
与du
命令的统计结果中。