CSI 協議規範

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.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章