CSI 协议规范

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: CSI 规范官方文档:https://github.com/container-storage-interface/spec/blob/master/spec.mdCSI目标定义API:自动化创建/删除数据卷;从一个节点挂载/卸载数据卷;在一个节点上Mount/Umount一个卷设备;使用可挂载/块 数据卷;本地存储供应者 - LVM创建、删除快照;从一个快照恢复数据卷;推荐细节:容器部署意见:CAP_SYS_ADMIN,mnt命名空间;CSI介绍CSI聚焦的中心是容器编排系统(CO)和Plugin之间的协议;插件应该是可以跨CO运行的。

CSI 规范

官方文档:https://github.com/container-storage-interface/spec/blob/master/spec.md

CSI目标

定义API:

自动化创建/删除数据卷;

从一个节点挂载/卸载数据卷;

在一个节点上Mount/Umount一个卷设备;

使用可挂载/块 数据卷;

本地存储供应者 - LVM

创建、删除快照;

从一个快照恢复数据卷;

推荐细节:

容器部署意见:CAP_SYS_ADMIN,mnt命名空间;

CSI介绍

CSI聚焦的中心是容器编排系统(CO)和Plugin之间的协议;插件应该是可以跨CO运行的。

部署模式

模式1:中心化控制器(Master节点) + 分布式插件(所有节点)

CO "Master" Host
+-------------------------------------------+
|                                           |
|  +------------+           +------------+  |
|  |     CO     |   gRPC    | Controller |  |
|  |            +----------->   Plugin   |  |
|  +------------+           +------------+  |
|                                           |
+-------------------------------------------+

                            CO "Node" Host(s)
+-------------------------------------------+
|                                           |
|  +------------+           +------------+  |
|  |     CO     |   gRPC    |    Node    |  |
|  |            +----------->   Plugin   |  |
|  +------------+           +------------+  |
|                                           |
+-------------------------------------------+

模式2:每个Worker节点部署 2个组件,分别是控制器、插件;

CO "Node" Host(s)
+-------------------------------------------+
|                                           |
|  +------------+           +------------+  |
|  |     CO     |   gRPC    | Controller |  |
|  |            +--+-------->   Plugin   |  |
|  +------------+  |        +------------+  |
|                  |                        |
|                  |                        |
|                  |        +------------+  |
|                  |        |    Node    |  |
|                  +-------->   Plugin   |  |
|                           +------------+  |
|                                           |
+-------------------------------------------+

模式3:每个Worker节点部署 一个组件(包含控制器 + 插件)

CO "Node" Host(s)
+-------------------------------------------+
|                                           |
|  +------------+           +------------+  |
|  |     CO     |   gRPC    | Controller |  |
|  |            +----------->    Node    |  |
|  +------------+           |   Plugin   |  |
|                           +------------+  |
|                                           |
+-------------------------------------------+

模式4:只有worker节点部署 一个组件,只包含插件

GetPluginCapabilities接口不能返回CONTROLLER_SERVICE;
CO "Node" Host(s)
+-------------------------------------------+
|                                           |
|  +------------+           +------------+  |
|  |     CO     |   gRPC    |    Node    |  |
|  |            +----------->   Plugin   |  |
|  +------------+           +------------+  |
|                                           |
+-------------------------------------------+

数据卷生命周期:

控制器插件应该实现所有 控制器 服务接口,不支持的接口要返回CALL_NOT_IMPLEMENTED;

插件提供的能力会列在ControllerGetCapabilities、NodeGetCapabilities接口中;

接口定义

容器编排系统通过RPC调用Plugin。

两种插件:

节点插件:每个节点上都会运行;

控制器插件:不确定那个节点运行,执行provider功能;

三种类型RPC:

身份服务:两种插件都要实现这个接口;
    GetPluginInfo:
    GetPluginCapabilities:
    Probe:
    
控制服务:
    CreateVolume:
    DeleteVolume:
    ControllerPublishVolume:
    ControllerUnpublishVolume:
    ValidateVolumeCapabilities:
    ListVolumes:
    GetCapacity:
    ControllerGetCapabilities:
    CreateSnapshot:
    DeleteSnapshot:
    ListSnapshots:

节点服务:
    NodeStageVolume:
    NodeUnstageVolume:
    NodePublishVolume:
    NodeUnpublishVolume:
    NodeGetId:
    NodeGetCapabilities:
    NodeGetInfo:

并发支持:

一般CO不会并发发送请求,在异常情况下收到一个volume的多个请求的时候要等幂处理;

返回:OPERATION_PENDING_FOR_VOLUME

校验 RPC

GetPluginInfo

# CO --(GetPluginInfo)--> Plugin
   request:
   response:
      name: org.foo.whizbang.super-plugin
      vendor_version: blue-green
      manifest:
        baz: qaz
message GetPluginInfoResponse {
  string name = 1;
  string vendor_version = 2;

  // This field is OPTIONAL.
  map<string, string> manifest = 3;
}

GetPluginCapabilities

# CO --(GetPluginCapabilities)--> Plugin
   request:
   response:
     capabilities:
       - service:
           type: CONTROLLER_SERVICE
message PluginCapability {
  message Service {
    enum Type {
      UNKNOWN = 0;
      CONTROLLER_SERVICE = 1;
      ACCESSIBILITY_CONSTRAINTS = 2;
    }
    Type type = 1;
  }

  oneof type {
    Service service = 1;
  }
}

readiness:

# CO --(Probe)--> Plugin
   request:
   response: {}

控制服务 RPC

如果GetPluginCapabilities 包含CREATE_DELETE_VOLUME标签,则必须实现CreateVolume;

CreateVolume接口

message CreateVolumeRequest {
  // 必须项
  // 1) 幂等性 - 多次相同请求不会产生多个volume;
  // 2) 可以使用这个名字,来命名PV Name;
  string name = 1;

  // 可选项,定义volume的大小范围,最小值和最大值;
  CapacityRange capacity_range = 2;

  // 必须项
  // 定义AccessType:
  //    VolumeCapability_Block:块存储设备;
  //    VolumeCapability_Mount:可挂载文件系统;
  // 定义AccessMode:
  //    VolumeCapability_AccessMode_UNKNOWN
  //    VolumeCapability_AccessMode_SINGLE_NODE_WRITER:只能挂载单节点、读写模式
  //    VolumeCapability_AccessMode_SINGLE_NODE_READER_ONLY:只能挂载单节点、只读模式
  //    VolumeCapability_AccessMode_MULTI_NODE_READER_ONLY:多个节点、只读模式
  //    VolumeCapability_AccessMode_MULTI_NODE_SINGLE_WRITER:多个节点、一个节点是读写,其他节点只读;
  //    VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER:多个节点,都是读写;
  repeated VolumeCapability volume_capabilities = 3;

  // 可选
  // 键值对参数,plugin需要解析这个map;
  map<string, string> parameters = 4;

  // 加密信息,可以在plugin引用;
  map<string, string> controller_create_secrets = 5;

  // OPTIONAL.
  VolumeContentSource volume_content_source = 6;
  
  // 可选:
  TopologyRequirement accessibility_requirements = 7;
}

错误码:

ALREADY_EXISTS:名字存在,但是参数不同;

RESOURCE_EXHAUSTED:资源可用,但是权限不足,例如:quota问题;

ABORTED:Operation pending for volume;

OUT_OF_RANGE:Unsupported capacity_range

UNIMPLEMENTED:Call not implemented

DeleteVolume

支持幂等性;

如果删除的volume id不存在,则返回OK;

ControllerPublishVolume

如果声明了PUBLISH_UNPUBLISH_VOLUME Capability,则必须实现;

当工作负载调度到某个节点时,CO通过此接口实现volume挂载到相应的节点;

不能假设RPC接口与调度的节点相同;

必须是幂等的;

如果volume已经挂载到了相应节点,则返回OK;

如果CO没有收到挂载是否成功,CO可能重复发送ControllerPublishVolume或者发送ControllerUnpublishVolume;

message ControllerPublishVolumeRequest {
  // 必须项
  string volume_id = 1;

  // 必选项:NodeGetInfo里面可以查到的节点ID;
  string node_id = 2;

  // 必须项:
  VolumeCapability volume_capability = 3;

  // 必须项:
  bool readonly = 4;

  // 可选
  map<string, string> controller_publish_secrets = 5;

  // 可选
  map<string, string> volume_attributes = 6;
}

ControllerUnpublishVolume

必须在NodeUnstageVolume、NodeUnpublishVolume调用成功后执行;

同样,执行RPC不一样在volume所挂载的节点上;

这个接口是幂等的,如果CO不确定返回值,则再次调用ControllerUnpublishVolume;

ValidateVolumeCapabilities

必须实现的接口;

用于CO检查volume的功能;

message ValidateVolumeCapabilitiesRequest {
  // 必须
  string volume_id = 1;

  // 必须
  repeated VolumeCapability volume_capabilities = 2;

  // 可选
  map<string, string> volume_attributes = 3;

  repeated Topology accessible_topology = 4;
}

ListVolumes

如果Plugin有LIST_VOLUMES 能力,则必须实现这个接口;

返回volume列表;

GetCapacity

如果Plugin有GET_CAPACITY 能力,则必须实现这个接口;

返回存储池的能力;

ControllerGetCapabilities

必须实现;

CO检查plugin所支持的能力;

CreateSnapshot

如果Plugin有CREATE_DELETE_SNAPSHOT 能力,则必须实现这个接口;

必须是幂等的;

[](#p7y7sk)DeleteSnapshot

如果Plugin有CREATE_DELETE_SNAPSHOT 能力,则必须实现这个接口;

ListSnapshots

如果Plugin有LIST_SNAPSHOTS 能力,则必须实现这个接口;

SnapShot状态

有些provider会上传到云存储;

节点服务 RPC

NodeStageVolume

如果Plugin有STAGE_UNSTAGE_VOLUME 能力,则必须实现这个接口;

CO会保证在ControllerPublishVolume 调用后再调用NodeStageVolume;并保证在NodePublishVolume调用前调用;

会在期望挂载节点上调用这个接口;

NodeUnstageVolume

如果Plugin有STAGE_UNSTAGE_VOLUME 能力,则必须实现这个接口;

保证在NodeUnpublishVolume之后调用;

NodePublishVolume

必须有的接口;

与RPC调用节点相同;

NodeUnpublishVolume

必须有的接口;

NodeGetCapabilities

必须实现的接口;

返回Node支持的能力;

NodeGetInfo

plugin必须实现这个接口,如果:PUBLISH_UNPUBLISH_VOLUME被配置;

协议

Identity:必须的接口类型;

Controller:可选的;

Node:必须的;

配置&操作

Plugin服务尽可能多的使用环境变量做配置;

CSI_ENDPOINT:Plugin的监听地址;

启动实例:

Supervisor -> Plugin: CSI_ENDPOINT=unix:///path/to/unix/domain/socket.sock.
Operator -> CO: use plugin at endpoint unix:///path/to/unix/domain/socket.sock.
CO: monitor /path/to/unix/domain/socket.sock.
Plugin: read CSI_ENDPOINT, create UNIX socket at specified path, bind and listen.
CO: observe that socket now exists, establish connection.
CO: invoke GetPluginCapabilities.
相关实践学习
巧用云服务器ECS制作节日贺卡
本场景带您体验如何在一台CentOS 7操作系统的ECS实例上,通过搭建web服务器,上传源码到web容器,制作节日贺卡网页。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
算法 调度 芯片
NR CSI(二) the workflow of CSI report
本篇内容是对CSI report相关流程的整理,其描述主要集中在R16 38.331 38.321 38.214中,以实网中的一个配置开始,看下相关定义。
|
存储 Kubernetes API
kubernetes【存储】1. 共享存储pv、pvc、StorageClass使用详解(1)
kubernetes【存储】1. 共享存储pv、pvc、StorageClass使用详解(1)
kubernetes【存储】1. 共享存储pv、pvc、StorageClass使用详解(1)
|
存储 Kubernetes 数据可视化
|
4月前
|
存储 Kubernetes 容器
在k8S中,CSI模型是什么?
在k8S中,CSI模型是什么?
|
4月前
|
存储 Kubernetes API
使用 Kubeadm 部署 Kubernetes(K8S) 安装 -- 持久化存储(PV&PVC)
使用 Kubeadm 部署 Kubernetes(K8S) 安装 -- 持久化存储(PV&PVC)
57 0
|
存储 Kubernetes 调度
Kubernetes 中存储使用介绍(PV、PVC和StorageClass)
在 Kubernetes 中的应用,都是以 Pod 的形式运行的,当我们要是在 Kubernetes 上运行一些需要存放数据的应用时,便需要关注应用存放的数据是否安全可靠。因为 Pod 是有生命周期的,那么也就是说当 Pod 被删除或重启后,Pod 里面所运行的数据也会随之消失。
2164 0
Kubernetes 中存储使用介绍(PV、PVC和StorageClass)
|
存储 Kubernetes 应用服务中间件
k8s初探(7)-kubernetes volume(1)
k8s初探(7)-kubernetes volume(1)
162 0
|
存储 Kubernetes Perl
【kubernetes】PVC
【kubernetes】PVC
163 0
|
存储 运维 Kubernetes
kubernetes【存储】1. 共享存储pv、pvc、StorageClass使用详解(2)
kubernetes【存储】1. 共享存储pv、pvc、StorageClass使用详解(2)
kubernetes【存储】1. 共享存储pv、pvc、StorageClass使用详解(2)
|
存储 Kubernetes Unix
浅析 CSI 工作原理
CSI 的 cloud providers 有两种类型,一种为 in-tree 类型,一种为 out-of-tree 类型。前者是指运行在 k8s 核心组件内部的存储插件;后者是指独立在 k8s 组件之外运行的存储插件。本文主要介绍 out-of-tree 类型的插件。
1045 0
下一篇
DataWorks