最初的存储插件都需要集成到k8s内部去使用,也就是编译并随核心 kubernetes 二进制文件一起提供。这意味着,如果他们希望添加对新存储系统的支持,则需要存储提供商将其签入核心 k8s 代码库。
为了对其进行解耦,所以采用Out-tree模式开发了Flexvolume
基于插件的解决方案 flex-volume 试图通过为外部插件公开基于 exec 的 API 来解决这个问题。尽管它也尝试处理与 k8s 二进制分离的类似概念,但这种方法存在几个主要问题。Flexvolume 是在 host 空间一个二进制文件,执行 Flexvolum 时相当于执行了本地的一个 shell 命令,这使得我们在安装 Flexvolume 的时候需要同时安装某些依赖,而这些依赖可能会对客户的应用产生一些影响。因此在安全性上、环境依赖上,就会有一个不好的影响。同时对于丰富插件功能这一点,我们在 Kubernetes 生态中实现 operator 的时候,经常会通过RBAC 这种方式去调用 Kubernetes 的一些接口来实现某些功能,而这些功能必须要在容器内部实现,因此像 Flexvolume 这种环境,由于它是 host 空间中的二进制程序,就没法实现这些功能。
而 CSI 这种容器化部署的方式,可以通过 RBAC 的方式来实现这些功能。
(Container Storage Interface), 旨在能为容器编排引擎和存储系统间建立一套标准的存储调用接口,通过该接口能为容器编排引擎提供存储服务。
CSI 采用的 grpc 调用,grpc 调用的一个优势就是可以将 grpc 服务运行在 socket 上,这样服务端就可以运行在 socket 端点的任何地方,换句话说就是可以被隔离单独运行,这样就可以实现扩展,然后通过标准 rpc 接口,完成本地原生模式的控制。CSI 提供了一套标准的接口集成在 k8s 的源码(kube-controller-manager,kubelet)中,第三方存储插件只需要实现这些接口并注册就可以调用对应的函数进行 pv 和 pvc 的自动创建,提供了可扩展的机会。
容器卷的创建有两种情况,一种是静态pv的创建,一种是动态pv的创建
apiVersion: v1
kind: PersistentVolume
metadata:name: pv001labels:name: pv001
spec:nfs:path: /data/volumes/v1server: nfsaccessModes: ["ReadWriteMany", "ReadWriteOnce"]capacity:storage: 2Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mypvc
spec:accessModes: ["ReadWriteMany"]volumeName: pv001resources:requests:storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:name: pv-pvc
spec:containers:- name: myappimage: nginxvolumeMounts:- name: htmlmountPath: /usr/share/nginx/htmlvolumes:- name: htmlpersistentVolumeClaim:claimName: mypvc
基本上的容器卷的创建逻辑已经清晰,下面我们看看k8s是如何对存储插件从in -> out的!

CSI有以下几个组件
这里面的组件有些不是必须的,k8s因为兼容性以及历史遗留的问题,对于一些组件已经实现了相应的逻辑,比如External Attacher,所以即使我们不部署External Attacher也可以实现
csi核心组件有三个
让我们看一下它的接口规范

与csi对应的有三个资源,这三个资源都有自己的功能

https://blog.csdn.net/qq_34556414/article/details/120004267
https://blog.csdn.net/chenhongloves/article/details/124670842