背景
rbd-nbd的挂载依赖内核的nbd模块,由于nbd模块默认支持16个nbd块设备(nbds_max=16),如果超过16个会挂载失败,在k8s中,我们通过cephcsi使用ceph rbd镜像作为块存储,当使用rbd-nbd挂载超过最大的16个之后,由于当前阶段已经过了k8s的调度计算,此失败会一直持续下去,这还是小问题,只是一个业务受到影响,可怕的是cephcsi的bug会在当前节点上死循环创建无效的nbd块,nbd17,nbd18,nbd19.......,导致服务器的块设备资源被占满,最终机器上的所有业务都受到影响。为了解决此问题,我们提出两个方案:一、扩展单节点支持的最大nbd块数,解决不够用的问题;二、自定义调度插件,在调度到节点之前对节点的可用nbd数进行判断及打分,保障调度到节点上的可用nbd块数是足够并且各节点的调度是均衡的;
本文主要介绍单节点nbd最大块数的调整操作,特别是把nbd编译到内核的修改方案,小编踩了不少坑,本来要放弃了,最后柳暗花明又一村,特此记录。
nbds_max调整
- 通过modprobe nbd命令以插件的方式动态加载
- 内核编译的时候指定CONFIG_BLK_DEV_NBD=y,直接把nbd模块编译到内核中
#方法1
zcat /proc/config.gz | grep CONFIG_BLK_DEV_NBD
#方法2
cat /boot/config-$(uname -r) | grep CONFIG_BLK_DEV_NBD
基于动态加载nbd模块的nbds_max调整
临时方案
永久方案
- max_part:块设备支持的最大分区数,默认值为0,不修改的话部分情况会无法显示分区
- nbds_max: nbd设备(即/dev/nbd*)的个数, 设备系统默认只有16个,请根据实际情况酌情修改,不能高于255
rbd-nbd命令行
rbd-nbd --help可以看到此命令是支持--nbds_max参数修改内核支持的最大块数,但是如果已经加载了nbd需要先modprobe -r nbd卸载nbd,否则会提示加载失败,细节可以看rbd-nbd源码。rbd-nbd --nbds_max 64 map rbdpool/images进行扩容挂载镜像,源码里此命令会自动调用modprobe rbd nbds_max=64
基于内置的nbd模块nbds_max调整
由于已经把nbd模块编译到了内核中,无法通过上述modprobe动态加载,需要修改内核启动加载参数,并重启生效
修改grub配置
修改/etc/default/grub在GRUB_CMDLINE_LINUX这行的最后加上nbd.nbds_max=64,修改完/etc/default/grub的配置如下
GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet ixgbe.allow_unsupported_sfp=1,1 vsyscall=emulate noibrs noibpb
nopti nospectre_v2 nospectre_v1 l1tf=off nospec_store_bypass_disable no_stf_barrier mds=off cgroup_no_v1=io nbd.
nbds_max=64"
更新grub配置
grub2-mkconfig -o /boot/gru
reboot生效
验证生效
重启之后通过cat /sys/module/nbd/parameters/nbds_max查看是否配置的值
参考
v4.14/drivers/block/nbd.c
rbd-nbd.cc
rbd-nbd挂载配置