关于 Kubernetes CSI,现在的资料已经不少,但我仍希望有一篇文档能让人轻松但不失准确地理解 CSI。
本文不涉及代码分析和详细设计。但需要如下基础:
- 会使用至少一种容器,Docker,containerd,Kata 之类的都可以。
- protobuf 和 gRPC:会用并有少量的开发经验,会用某种语言(最好是 Go)开发简单的 client 和 server。
- k8s:懂得基本概念,会简单使用。
- 存储:会使用至少一种。如 Ceph、NFS、公有云的云盘,都可以。
什么是 CSI
CSI 是存储(如 Ceph、NFS)与 CO(如 k8s)之间的对接规范。
这里我们只考虑 k8s 这一种 CO。存储提供方可以通过实现 CSI 的方式接入 k8s 并让 Pod 使用存储。
k8s CSI 在形式上是一个 gRPC proto 定义再加上一些文档形式的约定。
https://github.com/container-storage-interface/spec
该仓库中,有文件 csi.proto
。实现了该文件中所定义 API 的程序就具备了成为 CSI 驱动的必要条件。
需要实现的 gRPC Service 有:
service Identity {//
}service Controller {//
}service GroupController {//
}service SnapshotMetadata {//
}service Node {//
}
CSI 在 k8s 中的位置
在形式上,CSI driver 常常由如下组成:
- 一两个 Deployment 或 StatefulSet:主要是 provisioner,attacher
- 一两个 DaemonSet:主要是 node-driver-registrar 和 node-plugin
其他组件暂不考虑,遇到了再去了解即可。
通过这里
https://www.cnblogs.com/jthmath/p/19029054
可以看到各个组件的作用。
provisioner 的每个 Pod 通常有 2 个容器,一个是 external-provisioner,一个是存储厂商提供的程序,记为 P。
attacher(有的存储没有此组件)的每个 Pod 通常有 2 个容器,一个是 external-attacher,一个是存储厂商提供的程序,记为 A。
external-provisioner 和 external-attacher 不是 k8s 组成部分,但它是由 k8s-sig 维护的。
它们监听 k8s 中特定的资源(如 PVC、PV),并通过 gRPC 调用 P 和 A。
node-driver-registrar 也是由 k8s-sig 维护,作用是告知它所在节点的 kubelet “这里有个 csi driver,名字是 xxx,其他信息是 xxx”。
kubelet 记住 node-driver-registrar 告知的信息后,适时调用 node-plugin。
这样一来,k8s 和存储就完成了对接。