Kubernetes 相容 CSI 做的工作_Kubernetes中文社群
他有兩個模式,一個模式是自己給 node 打上這個 annotation,並且在退出的時候把這個 annotation 去掉。
另一個模式是交給 kubelet 的 pluginswatcher 來管理, kubelet 自己會根據 device-driver-registrar 提供的 unix domain socket 然後呼叫 gRPC 從 registrar 獲取 NodeId 和 DriverName 自己把 annotation 打上。
搜尋這條路徑下的 socket/var/lib/kubelet/plugins/[SanitizedCSIDriverName]/csi.sock
,然後就可以自動連線 registrar 拿到 NodeId 和 DriverName。
所以 device-driver-registar 主要是註冊 Node annotation 的。
external-attacher
監聽 VolumeAttachments 和 PersistentVolumes 兩個物件,這是和 kube-controller-manager 之間的橋樑。
實現中最後會呼叫 SyncNewOrUpdatedVolumeAttachment
來同步,呼叫 csi dirver 的 Attach 函式。
in-tree 的 attach/detach-controller
在 CSI 中扮演的角色是建立 VolumeAttachment,然後等待他的 VolumeAttachment 的 attached 的狀態。
attach-controller 會建立 VolumeAttatchment.Spec.Attacher
指向的是 external-attacher
external-provisoner
Static Volume
和 Dynamic Volume
的區別是,有一個 PersistentVolumeClaim 這個會根據 claim 自動分配 PersistentVolume,不然就要自己手動建立,然後 pod 要指定這個手動建立的 volume。
external-provisoner 就是提供支援 PersistentVolumeClaim 的,一般的 provisioner 要實現 Provision 和 Delete 的介面。主要是根據 PVC 建立 PV,這是 Provisioner 的介面的定義了,不是 CSI spec 裡的,這裡順帶介紹一下。
external-provisoner 看到 pvc 呼叫 driver
的 CreateVolume,完成以後就會建立 PersistenVolume,並且繫結到 pvc。
kubelet volume manager
kubelet 有一個 volume manager 來管理 volume 的 mount/attach 操作。
desiredStateOfWorld
是從 podManager 同步的理想狀態。
actualStateOfWorld
是目前 kubelet 的上執行的 pod 的狀態。
每次 volume manager 需要把 actualStateOfWorld
中 volume 的狀態同步到 desired 指定的狀態。
volume Manager 有兩個 goroutine 一個是同步狀態,一個 reconciler.reconcile
rc.operationExecutor.MountVolume 會執行 MountVolume 的操作。
-> oe.operationGenerator.GenerateMountVolumeFunc
-> 首先根據 og.volumePluginMgr.FindPluginBySpec 找到對應的 VolumePlugin
-> 然後呼叫 volumePlugin.NewMounter
-> 然後拿到 og.volumePluginMgr.FindAttachablePluginBySpec attachableplugin
-> volumeMounter.SetUp(fsGroup) 做 mount
volume plugin
csi volume plugin 是一個 in-tree volume,以後應該會逐步遷移到都使用 csi,而不會再有 in-tree volume plugin 了。
func (c *csiMountMgr) SetUp(fsGroup *int64) error { return c.SetUpAt(c.GetPath(), fsGroup) }