乐趣区

关于kubernetes:Kubernetes-CSI-容器存储接口一结束及原理

本文已收录于 Kubernetes 笔记

容器存储接口(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 以尝试解决问题。

参考

  • kubernetes-csi-introduction
  • 详解 Kubernetes Volume 的实现原理
  • CSI 存储接口解释

关注公众号 < 学点程序 >,获取最新文章推送

退出移动版