CSI 协议规范

简介: 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.
相关实践学习
使用ACS算力快速搭建生成式会话应用
阿里云容器计算服务 ACS(Container Compute Service)以Kubernetes为使用界面,采用Serverless形态提供弹性的算力资源,使您轻松高效运行容器应用。本文将指导您如何通过ACS控制台及ACS集群证书在ACS集群中快速部署并公开一个容器化生成式AI会话应用,并监控应用的运行情况。
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
Kubernetes API 调度
【k8s系列5】KubernetesClientException: too old resource version 原因分析
【k8s系列5】KubernetesClientException: too old resource version 原因分析
2134 0
|
缓存 大数据 应用服务中间件
什么是http状态码?常见的有哪些(3个)?分别代表什么含义?
什么是http状态码?常见的有哪些(3个)?分别代表什么含义?
620 0
|
关系型数据库 MySQL Docker
6. 修改docker端口 (映射宿主机和docker容器中的端口)
6. 修改docker端口 (映射宿主机和docker容器中的端口)
4117 0
6. 修改docker端口 (映射宿主机和docker容器中的端口)
|
4月前
|
Linux 开发工具 iOS开发
IDA Pro 9.3sp1 发布,主要针对 V850 反编译器的改进与问题修复
IDA Pro 9.3sp1 (macOS, Linux, Windows) - 强大的反汇编程序、反编译器和多功能调试器
431 0
IDA Pro 9.3sp1 发布,主要针对 V850 反编译器的改进与问题修复
|
数据采集 机器学习/深度学习 分布式计算
客户老是流失?可能是你没用好大数据!
客户老是流失?可能是你没用好大数据!
306 2
|
12月前
|
监控 前端开发 BI
如何开发项目管理系统中的项目收支板块?(附架构图+流程图+代码参考)
本文深入讲解项目管理系统中项目收支模块的设计与实现,涵盖预算、收入与支出管理,以及报表分析功能。内容包括模块功能概述、业务流程、开发技巧与实现方法,并提供数据库设计及前后端代码示例,助力企业打造高效的项目财务管控系统。
|
存储 Kubernetes 对象存储
基于openshift+华为对象存储的CSI开发
基于openshift+华为对象存储的CSI开发
492 0
|
开发工具 Android开发 iOS开发
Android与iOS生态差异深度剖析:技术架构、开发体验与市场影响####
本文旨在深入探讨Android与iOS两大移动操作系统在技术架构、开发环境及市场表现上的核心差异,为开发者和技术爱好者提供全面的视角。通过对比分析,揭示两者如何塑造了当今多样化的移动应用生态,并对未来发展趋势进行了展望。 ####
1015 27
|
安全 网络安全 数据处理
防火墙设置难倒你?这两种组网模式轻松解决网络安全难题!
【8月更文挑战第23天】在网络安全日益重要的今天,防火墙作为关键防护设备扮演着重要角色。本文重点分析两种核心组网模式:三层路由网关模式与二层透明网桥模式。前者通过IP层处理实现内外网隔离及丰富的策略配置,增强安全性;后者以MAC地址转发,部署简便,不影响现有网络结构,适合服务不可中断的情况。通过企业升级安全防护的实际案例,展示了不同模式的应用场景及优势,并提供了三层路由网关模式的配置示例。正确选择和配置防火墙组网模式对于提高网络安全性和保证业务连续性至关重要。
1057 0
|
缓存 前端开发 API
【第51期】一文读懂React表格框架
【第51期】一文读懂React表格框架
1003 0