问题描述
当节点上的thinpool磁盘空间接近写满时,概率性出现以下异常:
在容器内创建文件或目录失败、容器内文件系统只读、节点被标记disk-pressure污点及节点不可用状态等。
用户可手动在节点上执行docker info查看当前thinpool空间使用及剩余量信息,从而定位该问题。如下图:
问题原理
docker devicemapper模式下,尽管可以通过配置basesize参数限制单个容器的主目录大小(默认为10GB),但节点上的所有容器还是共用节点的thinpool磁盘空间,并不是完全隔离,当一些容器使用大量thinpool空间且总和达到节点thinpool空间上限时,也会影响其他容器正常运行。
另外,在容器的主目录中创删文件后,其占用的thinpool空间不会立即释放,因此即使basesize已经配置为10GB,而容器中不断创删文件时,占用的thinpool空间会不断增加一直到10GB为止,后续才会复用这10GB空间。如果节点上的业务容器数*basesize > 节点thinpool空间大小,理论上有概率出现节点thinpool空间耗尽的场景。
解决方案
当节点已出现thinpool空间耗尽时,可将部分业务迁移至其他节点实现业务快速恢复。但对于此类问题,建议采用以下方案从根因上解决问题:
方案1:
合理规划业务分布及数据面磁盘空间,避免和减少出现业务容器数*basesize > 节点thinpool空间大小场景。如需对thinpool空间进行扩容,请参考以下步骤:
- 在EVS控制台扩容数据盘。详情请参见扩容云硬盘容量。
在EVS控制台扩容成功后,仅扩大了云硬盘的存储容量,还需要执行后续步骤扩容逻辑卷和文件系统。
- 登录CCE控制台,进入集群,在左侧选择“节点管理”,单击节点后的“同步云服务器”。
- 登录目标节点。
- 使用lsblk命令查看节点块设备信息。
这里存在两种情况,根据容器存储Rootfs而不同。
Overlayfs:没有单独划分thinpool,在dockersys空间下统一存储镜像相关数据。
- 查看设备的磁盘和分区大小。
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 50G 0 disk
└─sda1 8:1 0 50G 0 part /
sdb 8:16 0 150G 0 disk # 数据盘已扩容至150G,存在50G空间仍未分配
├─vgpaas-dockersys 253:0 0 90G 0 lvm /var/lib/containerd
└─vgpaas-kubernetes 253:1 0 10G 0 lvm /mnt/paas/kubernetes/kubelet
- 扩容磁盘。
将新增的磁盘容量加到容器引擎使用的dockersys逻辑卷上。
- 扩容物理卷PV,让LVM识别EVS新增的容量。其中/dev/sdb为dockersys逻辑卷所在的物理卷。
pvresize /dev/sdb
回显如下:
Physical volume "/dev/sdb" changed
1 physical volume(s) resized or updated / 0 physical volume(s) not resized
- 将空闲容量100%扩容到逻辑卷LV。其中vgpaas/dockersys为容器引擎使用的逻辑卷。
lvextend -l+100%FREE -n vgpaas/dockersys
回显如下:
Size of logical volume vgpaas/dockersys changed from <90.00 GiB (23039 extents) to 140.00 GiB (35840 extents).
Logical volume vgpaas/dockersys successfully resized.
- 调整文件系统的大小。其中/dev/vgpaas/dockersys为容器引擎的文件系统路径。
resize2fs /dev/vgpaas/dockersys
回显如下:
Filesystem at /dev/vgpaas/dockersys is mounted on /var/lib/containerd; on-line resizing required
old_desc_blocks = 12, new_desc_blocks = 18
The filesystem on /dev/vgpaas/dockersys is now 36700160 blocks long.
- 检查是否扩容成功。
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 50G 0 disk
└─sda1 8:1 0 50G 0 part /
sdb 8:16 0 150G 0 disk
├─vgpaas-dockersys 253:0 0 140G 0 lvm /var/lib/containerd
└─vgpaas-kubernetes 253:1 0 10G 0 lvm /mnt/paas/kubernetes/kubelet
Devicemapper:单独划分了thinpool存储镜像相关数据。
- 查看设备的磁盘和分区大小。
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 8:0 0 50G 0 disk
└─vda1 8:1 0 50G 0 part /
vdb 8:16 0 200G 0 disk
├─vgpaas-dockersys 253:0 0 18G 0 lvm /var/lib/docker
├─vgpaas-thinpool_tmeta 253:1 0 3G 0 lvm
│ └─vgpaas-thinpool 253:3 0 67G 0 lvm # thinpool空间
│ ...
├─vgpaas-thinpool_tdata 253:2 0 67G 0 lvm
│ └─vgpaas-thinpool 253:3 0 67G 0 lvm
│ ...
└─vgpaas-kubernetes 253:4 0 10G 0 lvm /mnt/paas/kubernetes/kubelet
- 扩容磁盘。
选项一:将新增的磁盘容量加到thinpool盘上。
- 扩容物理卷PV,让LVM识别EVS新增的容量。其中/dev/vdb为thinpool空间所在的物理卷。
pvresize /dev/vdb
回显如下:
Physical volume "/dev/vdb" changed
1 physical volume(s) resized or updated / 0 physical volume(s) not resized
- 将空闲容量100%扩容到逻辑卷LV。其中vgpaas/thinpool为容器引擎使用的逻辑卷。
lvextend -l+100%FREE -n vgpaas/thinpool
回显如下:
Size of logical volume vgpaas/thinpool changed from <67.00 GiB (23039 extents) to <167.00 GiB (48639 extents).
Logical volume vgpaas/thinpool successfully resized.
- 由于thinpool未挂载到设备,因此无需调整文件系统的大小。
- 检查是否扩容成功。使用lsblk命令查看设备的磁盘和分区大小,若新增的磁盘容量已经加到thinpool盘,则表示扩容成功。
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 8:0 0 50G 0 disk
└─vda1 8:1 0 50G 0 part /
vdb 8:16 0 200G 0 disk
├─vgpaas-dockersys 253:0 0 18G 0 lvm /var/lib/docker
├─vgpaas-thinpool_tmeta 253:1 0 3G 0 lvm
│ └─vgpaas-thinpool 253:3 0 167G 0 lvm # 扩容后的thinpool空间
│ ...
├─vgpaas-thinpool_tdata 253:2 0 67G 0 lvm
│ └─vgpaas-thinpool 253:3 0 67G 0 lvm
│ ...
└─vgpaas-kubernetes 253:4 0 10G 0 lvm /mnt/paas/kubernetes/kubelet
选项二:将新增的磁盘容量加到dockersys盘上。
- 扩容物理卷PV,让LVM识别EVS新增的容量。其中/dev/vdb为dockersys逻辑卷所在的物理卷。
pvresize /dev/vdb
回显如下:
Physical volume "/dev/vdb" changed
1 physical volume(s) resized or updated / 0 physical volume(s) not resized
- 将空闲容量100%扩容到逻辑卷LV。其中vgpaas/dockersys为容器引擎使用的逻辑卷。
lvextend -l+100%FREE -n vgpaas/dockersys
回显如下:
Size of logical volume vgpaas/dockersys changed from <18.00 GiB (4607 extents) to <118.00 GiB (30208 extents).
Logical volume vgpaas/dockersys successfully resized.
- 调整文件系统的大小。其中/dev/vgpaas/dockersys为容器引擎的文件系统路径。
resize2fs /dev/vgpaas/dockersys
回显如下:
Filesystem at /dev/vgpaas/dockersys is mounted on /var/lib/docker; on-line resizing required
old_desc_blocks = 3, new_desc_blocks = 15
The filesystem on /dev/vgpaas/dockersys is now 30932992 blocks long.
- 检查是否扩容成功。使用lsblk命令查看设备的磁盘和分区大小,若新增的磁盘容量已经加到dockersys盘,则表示扩容成功。
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 8:0 0 50G 0 disk
└─vda1 8:1 0 50G 0 part /
vdb 8:16 0 200G 0 disk
├─vgpaas-dockersys 253:0 0 118G 0 lvm /var/lib/docker # 扩容后的dockersys盘
├─vgpaas-thinpool_tmeta 253:1 0 3G 0 lvm
│ └─vgpaas-thinpool 253:3 0 67G 0 lvm
│ ...
├─vgpaas-thinpool_tdata 253:2 0 67G 0 lvm
│ └─vgpaas-thinpool 253:3 0 67G 0 lvm
│ ...
└─vgpaas-kubernetes 253:4 0 10G 0 lvm /mnt/paas/kubernetes/kubelet
方案2:
容器业务的创删文件操作建议在容器挂载的本地存储(如emptyDir、hostPath)或云存储的目录中进行,这样不会占用thinpool空间。
方案3:
使用overlayfs存储模式的操作系统,可将业务部署在此类节点上,避免容器内创删文件后占用的磁盘空间不立即释放问题。