环境
挂载自定义数据盘当kubelet目录的集群
现象
当使用EBS PV的Pod被删除并重新调度到另一个节点时,EBS盘从原节点解绑,并绑定到新节点的时间很长,在6分钟左右,也堵塞了新Pod启动的时间。
原因分析
背景
当前我们挂载自定义数据盘vdb当/var/lib/kubelet目录的方式为:
- 将vdb mount 到 /mnt/vdb目录下
- 创建 /mnt/vdb/containerd 、/mnt/vdb/kubelet、 /mnt/vdb/containerd/log/pods目录,分别shared bind mount 到 /var/lib/containerd 、 /var/lib/kubelet、/var/log/pods目录下
当节点上的Pod需要使用EBS PV的时候,ebs盘会被CSI挂载到/var/lib/kubelet/plugins/kubernetes.io/csi/pv/{pvcName}/globalmount 目录下,在上述情况下,因为bind mount默认使用的shared传播(原始挂载的子挂载公开给副本挂载,副本挂载的子挂载也传播给原始挂载。),因此,在/proc/self/mountinfo里会有如下两个Item:
问题
当EBS PV从一个节点被调度到另一个节点,需要在旧节点上经历UmountVolume、UmountDevice,DetachVolume,在新节点上经历AttachVolume,MountDevice、MountVolume这六个流程。
在kubelet执行UmountDevice前,会调用GetDeviceMountRefs("/var/lib/kubelet/plugins/kubernetes.io/csi/pv/{pvcName}/globalmount")方法,查看该挂载点是否存在相关的另一个挂载点,在上述例子中就会返回"/mnt/vdb/kubelet/plugins/kubernetes.io/csi/pv/pvc-2c1845ae-fc5f-426d-a802-a0bdc47e942c/globalmount",导致kubelet报错 "xxx is still mounted by other references",从而不会执行UmountDevice,堵塞中PV调度流程,在失败并超时6分钟以后,会跳过UmountDevice,强制执行DetachVolume。同时,会导致节点上残留了旧的无效挂载点。
我观察到阿里云的ACK服务,同样使用了该方式挂载自定义数据盘当kubelet目录,但并没有发现kubelet有如上无法UmountDevice的现象,所以想请教下,ACK中的kubelet是做了什么优化改动吗?比如修改了GetDeviceMountRefs相关方法?