解决自研CSI启动后无法使用且CSINode无驱动信息的问题
环境信息
此处对一些信息做了模糊处理,不想因此导致一些信息泄露。
A环境:跑在kata容器中的 OS;
B环境:跑在虚拟机中的Ubuntu系统;
X CSI
:开发中的 CSI,目标是跑在 A 环境的 Kubernetes 中。
问题描述
当 X CSI
的服务在 A 环境中启动后,在宿主机的 /var/lib/kubelet/plugins
和 /var/lib/kubelet/plugins_registry
目录中,生成对应的 sock 文件后,CSINode 中 driver 栏没有刚启动的 X CSI
。结果如下:
问题影响
无法使用 X CSI
来挂载 PV
WorkAround
- kill kubelet 进程
1 | kill `ps -ef | grep -v grep | grep "/usr/bin/kubelet" | awk '{print $2}'` |
- kubelet 重启后,会填充 CSINode 信息,如下
可能的原因
kubelet 命令是否存在对应的配置参数,来对控制扫描
/var/lib/kubelet/plugins_registry
目录?是否由于文件系统的原因导致?
排查过程
排查 X CSI
的配置问题
找了这张图来看 /var/lib/kubelet/plugins_registry
和 /var/lib/kubelet/csi-plugins/xxx.sock
目录有啥命名规范,会不会是命名不规范,导致 PluginWwatcher watch 不到对应的 sock 文件,从而引起 X CSI
无法顺利注册。
修改成上图中的规范之后,问题依然存在。
对比 B 环境中kubelet参数
① A 环境中
kubelet 启动参数为:
1 | /usr/bin/kubelet |
其中 kubelet.config 中的配置信息如下:
1 | kind: KubeletConfiguration |
② 在 B 环境中用 kubeadm 自建 Kubernetes 集群
kubelet 启动参数:
1 | /usr/bin/kubelet |
其中 kubelet.config 配置文件如下:
1 | apiVersion: kubelet.config.k8s.io/v1beta1 |
没有明显的配置差异,跳过对这方面的怀疑。
在 A 环境中部署其他CSI
将官方的 nfs-csi 部署 A 环境的 K8s 中,发现在部署完成后,无法立即使用;
极大可能是 A 的环境问题
将 X CSI
部署到 B 环境的 K8s 中
发现部署完成后,可立即使用(CSIDriver 显示正常,说明被 kubelet 正确加载了);
排除
X CSI
配置问题
阅读 kubelet 加载 CSI 定义的代码
经过前面的尝试与分析,初步确定是 kubelet 加载 CSI 时,出现了问题,但具体是哪里的问题,需要先了解 kubelet 是如何加载 CSI 的,从其中寻找答案。
初步了解 CSI Driver 注册流程,在关键点添加日志、修改 kubelet 的日志级别,看日志,未发现文件监听相关的日志;
修改 kubelet 源码(添加 & 修改 kubelet 中相关的日志级别)后,发现当
/var/lib/kubelet/plugins_registry
目录下新增 sock 文件、删除 sock 文件后,没有相应日志打印,即监听文件系统的事件出现异常。
定位到问题为 kubelet 监听本地文件变更存在问题后,单独将 kubelet 使用的相关库提出,并单独验证。
- 将 kubelet 中用于监听文件变更的库单拎出来,写一个监听某文件夹下文件变更的二进制。
- 经过测试发现,在 A 环境的
/var/lib/kubelet/plugins_registry
目录下,就是极大概率无法监听到文件变更;更换目录,一些已存在的目录可以、一些新增的目录不行,讲道理,这不是一个正常的表现。 - 将二进制移到 B 环境中,监听相同目录,表现正常,进一步判定为 A 环境问题。
查看挂载信息
1 | root@<hostname>:/# df -h | grep -i katashared |
所以问题是否会跟这个 kataSahred 文件系统有关?
问题的原因
kata 容器中默认的文件系统为 kataShare
,在这种文件系统下,监听某个目录下的文件变更时,会有一定的概率收不到 CREATE
、DELETE
、UPDATE
事件。因为收不到变更事件,从而无法触发 kubelet 注册 CSI Driver 的后续流程,导致部署完 CSI 后,不能立即使用。
解决方案
将 /var/lib/kubelet
目录挂载成其他文件系统后,安装 CSI 后,可立即使用,即可纵享丝滑。
1 | root@<hostname>:/# df -h | grep -i /var/lib/kubelet |
One More Question
- 为什么重启 kubelet 能 workaround?
kubelet 启动时,会主动扫描 plugins_registry
目录下所有的文件,当扫描到文件后,会立即手动触发 CREATE
事件,从而完成 CSI Driver 的注册,达到 CSI 可用的目的。
Reference
解决自研CSI启动后无法使用且CSINode无驱动信息的问题