一个恢复CSI挂载信息的解决方法
问题描述
之前有做过一个华为OBS 的CSI插件,其基本运作原理如下图所示。CSI插件Pod挂载了主机的/var/lib/kubelet/pods目录,当创建挂载Pvc的业务Pod时,CSI插件会启动一个
s3fs
进程,该进程用于远程连接s3服务,将bucket(也即Pvc)挂载到/var/lib/kubelet/pods中的对应Pod目录下(一般为/var/lib/kubelet/pods/<pod-uuid>/volumes/<pod-uuid>kubernetes.io~csi/<pvc-name>/mount),然后由kubelet
挂载到业务Pod中。该插件有个问题,就是当CSI插件重启之后,会丢失掉内部负责远程连接s3服务的
s3fs
进程,因此会导致业务Pod内部挂载目录失效,访问/var/lib/kubelet/pods/<pod-uuid>/volumes/<pod-uuid>kubernetes.io~csi/<pvc-name>/mount目录会出现Transport endpoint is not connected
的问题。此时为了让业务Pod能够正常访问,需要重启业务Pod,但这种方式很不优雅。解决思路
为了解决
Transport endpoint is not connected
问题,首先需要恢复s3fs
进程,但恢复进程依赖几个数据:Pvc的名称、Pod的uid、s3服务的地址以及访问使用的AK/SK等。有两种方式可以保存这类数据:- 在CSI插件正常运行过程中,将元数据保存到s3服务,其实就是将s3服务作为一个元数据库使用。但这种方式可能存在元数据被误删以及元数据和系统不一致的情况
- 在CSI插件启动后使用client-go动态获取集群中的相关数据
此次采用了第二种方式,执行思路为:
- 获取所有命名空间下的Pvc(
allPvcs
) - 从
allPvcs
中找到Pvc的metadata.annotations.volume.beta.kubernetes.io/storage-provisioner 为目标storageclass的Pvc(targetPvcs
) - 获取挂载了上述
targetPvcs
的pod(targetPods
) - 找到
targetPods
的uid(targetUid
) - 拼接挂载路径
/var/lib/kubelet/pods/<targetUid>/volumes/<targetUid>kubernetes.io~csi/<targetPvc-name>/mount
- 找到
targetPvcs
的spec.storageClassName,进而找出负责该Pvc的storageclass(targetStorageclass
) - 在
targetStorageclass
的parameters
找到相关的信息,最主要的是保存访问s3服务的AK/SK的secret(targetSecret
) - 从
targetSecret
中找到AK/SK - 执行挂载
上述步骤的主要目的就是找出挂载路径以及s3服务的访问信息。
实施过程
在完成编码之后,经验证发现
/var/lib/kubelet/pods/<targetUid>/volumes/<targetUid>kubernetes.io~csi/<targetPvc-name>/mount
挂载成功,进入该目录之后可以看到bucket中的内容,但进入业务容器发现,目录并没有成功挂载。需要提出的一点是,由于CSI插件是被异常重启的,导致挂载失效,并没有执行标准的Unmounting 流程(即调用NodeUnpublishVolume
方法),因此在重新挂载之前首先需要umount
掉原来的挂载点。
业务容器没有挂载成功的原因是整个恢复流程并没有触发kubelet执行
umount
/mount
来将pvc重新挂载到业务容器。解决方式与CSI插件的/var/lib/kubelet/pods/<targetUid>/volumes/<targetUid>kubernetes.io~csi/<targetPvc-name>/mount
一样,执行umount
在mount
即可。但这么做首先要知道Pod映射到主机上的挂载路径,这样就比较麻烦了,因为pod映射到主机上的路径与使用的CRI相关,如果朝这一方向下去,难度比较大,在CSI Volume Plugins in Kubernetes Design Doc中也提过,正常情况下是由kubelet
执行的:
The volume manager component of kubelet, notices a mounted CSI volume, referenced by a pod that has been deleted or terminated, so it calls the in-tree CSI volume plugin’sUnmountDevice
method which is a no-op and returns immediately. Next kubelet calls the in-tree CSI volume plugin’s unmount (teardown) method, which causes the in-tree volume plugin to issue aNodeUnpublishVolume
call via the registered unix domain socket to the local CSI driver. If this call fails from any reason, kubelet re-tries the call periodically. Upon successful completion of theNodeUnpublishVolume
call the specified path is unmounted from the pod container.
那么怎么才能让容器重新挂载成功呢?
只要重新触发
kubelet
的挂载动作即可,可以采用livenessProbe
来触发该动作,方式如下:apiVersion:v1 kind:Pod metadata: name:csi-s3-test-nginx namespace:default spec: containers: -name:csi-s3-test-nginx image:nginx livenessProbe: failureThreshold:3 initialDelaySeconds:20 periodSeconds:5 timeoutSeconds:5 exec: command: -ls -/var/lib/www/html volumeMounts: -mountPath:/var/lib/www/html name:webroot -mountPath:/var/lib/www/html2 name:webroot2 volumes: -name:webroot persistentVolumeClaim: claimName:csi-s3-pvc readOnly:false -name:webroot2 persistentVolumeClaim: claimName:csi-s3-pvc2 readOnly:false
如果使用这种方式的话,还需要执行之前恢复
s3fs
进程的操作吗?答案是需要的,重启只会触发kubelet
的动作,但不会触发CSI重新挂载,因此恢复s3fs
进程和livenessProbe
都是同时需要的。链接:https://www.cnblogs.com/charlieroro/p/16323666.html#5223509
(版权归原作者所有,侵删)
阅读原文 最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。