写点什么

K8S CSI 容器存储接口 (一):介绍以及原理

用户头像
silenceper
关注
发布于: 2020 年 11 月 26 日
K8S CSI容器存储接口(一):介绍以及原理

容器存储接口(CSI)是用于将任意块和文件存储系统暴露给诸如 Kubernetes 之类的容器编排系统(CO)上的容器化工作负载的标准。 使用 CSI 的第三方存储提供商可以编写和部署在 Kubernetes 中公开新存储系统的插件,而无需接触核心的 Kubernetes 代码。


具体来说,Kubernetes 针对 CSI 规定了以下内容:


  • Kubelet 到 CSI 驱动程序的通信

- Kubelet 通过 Unix 域套接字直接向 CSI 驱动程序发起 CSI 调用(例如NodeStageVolumeNodePublishVolume等),以挂载和卸载卷。

- Kubelet 通过 kubelet 插件注册机制发现 CSI 驱动程序(以及用于与 CSI 驱动程序进行交互的 Unix 域套接字)。

- 因此,部署在 Kubernetes 上的所有 CSI 驱动程序必须在每个受支持的节点上使用 kubelet 插件注册机制进行注册。

  • Master 到 CSI 驱动程序的通信

- Kubernetes master 组件不会直接(通过 Unix 域套接字或其他方式)与 CSI 驱动程序通信。

- Kubernetes master 组件仅与 Kubernetes API 交互。

- 因此,需要依赖于 Kubernetes API 的操作的 CSI 驱动程序(例如卷创建,卷 attach,卷快照等)必须监听 Kubernetes API 并针对它触发适当的 CSI 操作(例如下面的一系列的 external 组件)。


组件



CSI 实现中的组件分为两部分:


  • 由 k8s 官方维护的一系列 external 组件负责注册 CSI driver 或监听 k8s 对象资源,从而发起 csi driver 调用,比如(node-driver-registrar,external-attacher,external-provisioner,external-resizer,external-snapshotter,livenessprobe)

  • 各云厂商 or 开发者自行开发的组件(需要实现 CSI Identity,CSI Controller,CSI Node 接口)


RPC 接口(开发商实现)


Identity Service


service Identity {  //返回driver的信息,比如名字,版本  rpc GetPluginInfo(GetPluginInfoRequest)    returns (GetPluginInfoResponse) {}  //返回driver提供的能力,比如是否提供Controller Service,volume 访问能能力  rpc GetPluginCapabilities(GetPluginCapabilitiesRequest)    returns (GetPluginCapabilitiesResponse) {}  //探针  rpc Probe (ProbeRequest)    returns (ProbeResponse) {}}
复制代码


Controller service


service Controller {  //创建卷  rpc CreateVolume (CreateVolumeRequest)    returns (CreateVolumeResponse) {}  //删除卷  rpc DeleteVolume (DeleteVolumeRequest)    returns (DeleteVolumeResponse) {}  //attach 卷  rpc ControllerPublishVolume (ControllerPublishVolumeRequest)    returns (ControllerPublishVolumeResponse) {}  //unattach卷  rpc ControllerUnpublishVolume (ControllerUnpublishVolumeRequest)    returns (ControllerUnpublishVolumeResponse) {}  //返回存储卷的功能点,如是否支持挂载到多个节点上,是否支持多个节点同时读写  rpc ValidateVolumeCapabilities (ValidateVolumeCapabilitiesRequest)    returns (ValidateVolumeCapabilitiesResponse) {}  //列出所有卷  rpc ListVolumes (ListVolumesRequest)    returns (ListVolumesResponse) {}  //返回存储资源池的可用空间大小  rpc GetCapacity (GetCapacityRequest)    returns (GetCapacityResponse) {}  //返回controller插件的功能点,如是否支持GetCapacity接口,是否支持snapshot功能等  rpc ControllerGetCapabilities (ControllerGetCapabilitiesRequest)    returns (ControllerGetCapabilitiesResponse) {}  //创建快照  rpc CreateSnapshot (CreateSnapshotRequest)    returns (CreateSnapshotResponse) {}  //删除快照  rpc DeleteSnapshot (DeleteSnapshotRequest)    returns (DeleteSnapshotResponse) {}  //列出快照  rpc ListSnapshots (ListSnapshotsRequest)    returns (ListSnapshotsResponse) {}  //扩容  rpc ControllerExpandVolume (ControllerExpandVolumeRequest)    returns (ControllerExpandVolumeResponse) {}  //获得卷  rpc ControllerGetVolume (ControllerGetVolumeRequest)    returns (ControllerGetVolumeResponse) {        option (alpha_method) = true;    }}
复制代码


Node Service


service Node {  //如果存储卷没有格式化,首先要格式化。然后把存储卷mount到一个临时的目录(这个目录通常是节点上的一个全局目录)。再通过NodePublishVolume将存储卷mount到pod的目录中。mount过程分为2步,原因是为了支持多个pod共享同一个volume(如NFS)。  rpc NodeStageVolume (NodeStageVolumeRequest)    returns (NodeStageVolumeResponse) {}  //NodeStageVolume的逆操作,将一个存储卷从临时目录umount掉  rpc NodeUnstageVolume (NodeUnstageVolumeRequest)    returns (NodeUnstageVolumeResponse) {}  //将存储卷从临时目录mount到目标目录(pod目录)  rpc NodePublishVolume (NodePublishVolumeRequest)    returns (NodePublishVolumeResponse) {}  //将存储卷从pod目录umount掉  rpc NodeUnpublishVolume (NodeUnpublishVolumeRequest)    returns (NodeUnpublishVolumeResponse) {}  //返回可用于该卷的卷容量统计信息。  rpc NodeGetVolumeStats (NodeGetVolumeStatsRequest)    returns (NodeGetVolumeStatsResponse) {}
//noe上执行卷扩容 rpc NodeExpandVolume(NodeExpandVolumeRequest) returns (NodeExpandVolumeResponse) {}
//返回Node插件的功能点,如是否支持stage/unstage功能 rpc NodeGetCapabilities (NodeGetCapabilitiesRequest) returns (NodeGetCapabilitiesResponse) {} //返回节点信息 rpc NodeGetInfo (NodeGetInfoRequest) returns (NodeGetInfoResponse) {}}
复制代码


External 组件(k8s Team)


这部分组件是由 k8s 官方提供的,作为 k8s api 跟 csi driver 的桥梁:


  • node-driver-registrar


CSI node-driver-registrar 是一个 sidecar 容器,可从 CSI driver 获取驱动程序信息(使用 NodeGetInfo),并使用 kubelet 插件注册机制在该节点上的 kubelet 中对其进行注册。


  • external-attacher


它是一个 sidecar 容器,用于监视 Kubernetes VolumeAttachment 对象并针对驱动程序端点触发 CSI ControllerPublish 和 ControllerUnpublish 操作


  • external-provisioner


它是一个 sidecar 容器,用于监视 Kubernetes PersistentVolumeClaim 对象并针对驱动程序端点触发 CSI CreateVolume 和 DeleteVolume 操作。

external-attacher 还支持快照数据源。 如果将快照 CRD 资源指定为 PVC 对象上的数据源,则此 sidecar 容器通过获取 SnapshotContent 对象获取有关快照的信息,并填充数据源字段,该字段向存储系统指示应使用指定的快照填充新卷 。


  • external-resizer


它是一个 sidecar 容器,用于监视 Kubernetes API 服务器上的 PersistentVolumeClaim 对象的改动,如果用户请求在 PersistentVolumeClaim 对象上请求更多存储,则会针对 CSI 端点触发 ControllerExpandVolume 操作。


  • external-snapshotter


它是一个 sidecar 容器,用于监视 Kubernetes API 服务器上的 VolumeSnapshot 和 VolumeSnapshotContent CRD 对象。创建新的 VolumeSnapshot 对象(引用与此驱动程序对应的 SnapshotClass CRD 对象)将导致 sidecar 容器提供新的快照。

该 Sidecar 侦听指示成功创建 VolumeSnapshot 的服务,并立即创建 VolumeSnapshotContent 资源。


  • livenessprobe


它是一个 sidecar 容器,用于监视 CSI 驱动程序的运行状况,并通过Liveness Probe机制将其报告给 Kubernetes。 这使 Kubernetes 能够自动检测驱动程序问题并重新启动 Pod 以尝试解决问题。

参考



关注公众号,获取最新文章推送:



发布于: 2020 年 11 月 26 日阅读数: 498
用户头像

silenceper

关注

公众号:学点程序 2017.10.27 加入

关注Go,Kubernetes

评论

发布
暂无评论
K8S CSI容器存储接口(一):介绍以及原理