接口规范翻译

术语

词条 定义
Volume A unit of storage that will be made available inside of a CO-managed container, via the CSI.
Block Volume 在容器内以块设备形式存在的挂载卷。
Mounted Volume A volume that will be mounted using the specified file system and appear as a directory inside the container.
CO 容器编排系统(Container Orchestration system), 使用 CSI 的 RPC 和 插件通信.
SP 存储供应商(Storage Provider), CSI 的第三方实现
RPC Remote Procedure Call.
Node A host where the user workload will be running, uniquely identifiable from the perspective of a Plugin by a node ID.
Plugin Aka “plugin implementation”, a gRPC endpoint that implements the CSI Services.
Plugin Supervisor Process that governs the lifecycle of a Plugin, MAY be the CO.
Workload The atomic unit of “work” scheduled by a CO. This MAY be a container or a collection of containers.

设计目标

定义行业标准——“容器存储接口”(CSI),这将使存储供应商(SP)能够一次开发一个插件,并使它可在多个容器编排(CO)系统中工作。

MVP(最小/基本 可用产品)目标

CSI 须做到:

  1. 使存储提供商(SP)作者能够编写一个与CSI兼容的插件,该插件在实现了 CSI 的所有容器编配系统中“能用”。
  2. 需定义以下 API(RPC):
    1. 动态**调配(provisioning)和取消调配(deprovisioning)**卷。
    2. 向节点**附加(attaching)或分离(detaching)**卷。
    3. 向节点安装(mount)/卸载卷(unmount)
    4. 可使用(消费) 块和可挂载卷
    5. 本地存储(例如,设备映射器,lvm)。
    6. 创建和删除快照(快照的源是卷)。
    7. 从快照置备新卷(如果还原快照容量超出范围,还原快照将删除原始卷中的数据并用快照中的数据替换)。
  3. 定义插件协议推荐
    1. 描述Supervisor配置插件的过程。
    2. 容器部署注意事项(CAP_SYS_ADMIN,挂载名称空间等)。

MVP(最小/基本 可用产品)不用做的

容器存储接口(CSI)不会明确定义,提供或规定:

  1. Supervisor 插件程序用来管理插件生命周期的特定机制,包括:
    1. 如何维护状态(例如,已连接,已安装的设备等)。
    2. 如何部署,安装,升级,卸载,监视或重新生成(在意外终止的情况下)插件。
  2. 代表“存储等级”(又称“存储等级”)的一流消息结构/字段。
  3. 协议级身份验证和授权。
  4. 封装插件。
  5. 符合POSIX:CSI不保证所提供的卷是POSIX兼容的文件系统。遵从性由插件实现(及其依赖的任何后端存储系统)确定。CSI不会以与POSIX兼容的方式阻止插件管理程序或CO与插件管理的卷进行交互。

解决方案简述

该规范定义了一个接口,以及为实现CSI兼容插件而为存储提供商(SP)提供的最低操作和包装建议。该接口声明插件必须公开的RPC:这是CSI规范的主要重点。任何操作和包装建议均提供了其他指南,以促进跨CO兼容性。

架构

  • 本规范的主要重点是CO和插件之间的协议

  • 应该有可能为各种部署架构提供跨CO兼容的插件。

  • 应配备CO,以处理集中式插件和无头插件,以及拆分组件插件和统一插件。

  • 下图中说明了这些可能性中的几种。

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

图1:集群中的所有节点上都安装运行 插件:
编排系统的 master 节点上运行 中心化的控制插件,
工作节点上运行 Node 插件
                            CO "Node" Host(s)
+-------------------------------------------+
|                                           |
|  +------------+           +------------+  |
|  |     CO     |   gRPC    | Controller |  |
|  |            +--+-------->   Plugin   |  |
|  +------------+  |        +------------+  |
|                  |                        |
|                  |                        |
|                  |        +------------+  |
|                  |        |    Node    |  |
|                  +-------->   Plugin   |  |
|                           +------------+  |
|                                           |
+-------------------------------------------+
Figure 2: Headless Plugin deployment, only the CO Node hosts run
Plugins. Separate, split-component Plugins supply the Controller
Service and the Node Service respectively.

图2:无头插件部署,仅在编排系统的节点host上运行插件。
控制和工作节点服务分别
                            CO "Node" Host(s)
+-------------------------------------------+
|                                           |
|  +------------+           +------------+  |
|  |     CO     |   gRPC    | Controller |  |
|  |            +----------->    Node    |  |
|  +------------+           |   Plugin   |  |
|                           +------------+  |
|                                           |
+-------------------------------------------+
Figure 3: Headless Plugin deployment, only the CO Node hosts run
Plugins. A unified Plugin component supplies both the Controller
Service and Node Service.
                            CO "Node" Host(s)
+-------------------------------------------+
|                                           |
|  +------------+           +------------+  |
|  |     CO     |   gRPC    |    Node    |  |
|  |            +----------->   Plugin   |  |
|  +------------+           +------------+  |
|                                           |
+-------------------------------------------+
Figure 4: Headless Plugin deployment, only the CO Node hosts run
Plugins. A Node-only Plugin component supplies only the Node Service.
Its GetPluginCapabilities RPC does not report the CONTROLLER_SERVICE
capability.

Volume Lifecycle

   CreateVolume +------------+ DeleteVolume
 +------------->|  CREATED   +--------------+
 |              +---+----+---+              |
 |       Controller |    | Controller       v
+++         Publish |    | Unpublish       +++
|X|          Volume |    | Volume          | |
+-+             +---v----+---+             +-+
                | NODE_READY |
                +---+----^---+
               Node |    | Node
            Publish |    | Unpublish
             Volume |    | Volume
                +---v----+---+
                | PUBLISHED  |
                +------------+
Figure 5: The lifecycle of a dynamically provisioned volume, from
creation to destruction.
   CreateVolume +------------+ DeleteVolume
 +------------->|  CREATED   +--------------+
 |              +---+----+---+              |
 |       Controller |    | Controller       v
+++         Publish |    | Unpublish       +++
|X|          Volume |    | Volume          | |
+-+             +---v----+---+             +-+
                | NODE_READY |
                +---+----^---+
               Node |    | Node
              Stage |    | Unstage
             Volume |    | Volume
                +---v----+---+
                |  VOL_READY |
                +------------+
               Node |    | Node
            Publish |    | Unpublish
             Volume |    | Volume
                +---v----+---+
                | PUBLISHED  |
                +------------+
Figure 6: The lifecycle of a dynamically provisioned volume, from
creation to destruction, when the Node Plugin advertises the
STAGE_UNSTAGE_VOLUME capability.
    Controller                  Controller
       Publish                  Unpublish
        Volume  +------------+  Volume
 +------------->+ NODE_READY +--------------+
 |              +---+----^---+              |
 |             Node |    | Node             v
+++         Publish |    | Unpublish       +++
|X| <-+      Volume |    | Volume          | |
+++   |         +---v----+---+             +-+
 |    |         | PUBLISHED  |
 |    |         +------------+
 +----+
   Validate
   Volume
   Capabilities
Figure 7: The lifecycle of a pre-provisioned volume that requires
controller to publish to a node (`ControllerPublishVolume`) prior to
publishing on the node (`NodePublishVolume`).
       +-+  +-+
       |X|  | |
       +++  +^+
        |    |
   Node |    | Node
Publish |    | Unpublish
 Volume |    | Volume
    +---v----+---+
    | PUBLISHED  |
    +------------+
Figure 8: Plugins MAY forego other lifecycle steps by contraindicating
them via the capabilities API. Interactions with the volumes of such
plugins is reduced to `NodePublishVolume` and `NodeUnpublishVolume`
calls.

The above diagrams illustrate a general expectation with respect to how a CO MAY manage the lifecycle of a volume via the API presented in this specification. Plugins SHOULD expose all RPCs for an interface: Controller plugins SHOULD implement all RPCs for the Controller service. Unsupported RPCs SHOULD return an appropriate error code that indicates such (e.g. CALL_NOT_IMPLEMENTED). The full list of plugin capabilities is documented in the ControllerGetCapabilities and NodeGetCapabilities RPCs.

上图说明了关于CO可以如何通过本规范中介绍的API管理卷的生命周期的一般期望。 插件应该公开接口的所有RPC:控制器插件应该为Controller服务实现所有RPC 。 不支持的RPC应该返回一个适当的错误代码来指示这种情况(例如CALL_NOT_IMPLEMENTED)。 插件功能的完整列表记录在ControllerGetCapabilitiesNodeGetCapabilities RPC中。

容器存储接口

本节描述了CO和插件之间的接口。

RPC接口

CO通过RPC与插件交互。 每个SP必须提供:

  • 节点插件:一个服务于CSI RPC的gRPC端点,该CSI RPC必须在该节点上运行,随后将发布SP设置的卷。
  • Controller Plugin:一个gCSI端点,它可以在任何地方运行CSI RPC。
  • 在某些情况下,单个gRPC端点可以为所有CSI RPC服务(请参见[ 体系结构 ](#architecture)中的图3 )。
syntax = "proto3";
package csi.v1;
import "google/protobuf/descriptor.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
option go_package = "csi";
extend google.protobuf.FieldOptions {
  // Indicates that a field MAY contain information that is sensitive
  // and MUST be treated as such (e.g. not logged).
  bool csi_secret = 1059;
}

There are three sets of RPCs:

  • Identity Service: Both the Node Plugin and the Controller Plugin MUST implement this sets of RPCs.
  • Controller Service: The Controller Plugin MUST implement this sets of RPCs.
  • Node Service: The Node Plugin MUST implement this sets of RPCs.
service Identity {
  rpc GetPluginInfo(GetPluginInfoRequest)
    returns (GetPluginInfoResponse) {}
  rpc GetPluginCapabilities(GetPluginCapabilitiesRequest)
    returns (GetPluginCapabilitiesResponse) {}
  rpc Probe (ProbeRequest)
    returns (ProbeResponse) {}
}
service Controller {
  rpc CreateVolume (CreateVolumeRequest)
    returns (CreateVolumeResponse) {}
  rpc DeleteVolume (DeleteVolumeRequest)
    returns (DeleteVolumeResponse) {}
  rpc ControllerPublishVolume (ControllerPublishVolumeRequest)
    returns (ControllerPublishVolumeResponse) {}
  rpc ControllerUnpublishVolume (ControllerUnpublishVolumeRequest)
    returns (ControllerUnpublishVolumeResponse) {}
  rpc ValidateVolumeCapabilities (ValidateVolumeCapabilitiesRequest)
    returns (ValidateVolumeCapabilitiesResponse) {}
  rpc ListVolumes (ListVolumesRequest)
    returns (ListVolumesResponse) {}
  rpc GetCapacity (GetCapacityRequest)
    returns (GetCapacityResponse) {}
  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) {}
}
service Node {
  rpc NodeStageVolume (NodeStageVolumeRequest)
    returns (NodeStageVolumeResponse) {}
  rpc NodeUnstageVolume (NodeUnstageVolumeRequest)
    returns (NodeUnstageVolumeResponse) {}
  rpc NodePublishVolume (NodePublishVolumeRequest)
    returns (NodePublishVolumeResponse) {}
  rpc NodeUnpublishVolume (NodeUnpublishVolumeRequest)
    returns (NodeUnpublishVolumeResponse) {}
  rpc NodeGetVolumeStats (NodeGetVolumeStatsRequest)
    returns (NodeGetVolumeStatsResponse) {}
  rpc NodeExpandVolume(NodeExpandVolumeRequest)
    returns (NodeExpandVolumeResponse) {}
  rpc NodeGetCapabilities (NodeGetCapabilitiesRequest)
    returns (NodeGetCapabilitiesResponse) {}
  rpc NodeGetInfo (NodeGetInfoRequest)
    returns (NodeGetInfoResponse) {}
}

并发

In general the Cluster Orchestrator (CO) is responsible for ensuring that there is no more than one call “in-flight” per volume at a given time. However, in some circumstances, the CO MAY lose state (for example when the CO crashes and restarts), and MAY issue multiple calls simultaneously for the same volume. The plugin SHOULD handle this as gracefully as possible. The error code ABORTED MAY be returned by the plugin in this case (see the Error Scheme section for details).

字段要求

The requirements documented herein apply equally and without exception, unless otherwise noted, for the fields of all protobuf message types defined by this specification. Violation of these requirements MAY result in RPC message data that is not compatible with all CO, Plugin, and/or CSI middleware implementations.

Size Limits

CSI defines general size limits for fields of various types (see table below). The general size limit for a particular field MAY be overridden by specifying a different size limit in said field’s description. Unless otherwise specified, fields SHALL NOT exceed the limits documented here. These limits apply for messages generated by both COs and plugins.

Size Field Type
128 bytes string
4 KiB map<string, string>

参考

接口规范 插件设计文档 CSI - Container Storage Interface(容器存储接口)·宋净超