k8s CSI

CSI:Container Storage Interface (CSI)

Volume 的三个阶段:

  1. Provision and Delete:负责卷的创建以及销毁。
  2. Attaching and Detaching:将卷设备挂载到本地或者从本地卸载。
  3. Mount and Umount:将 Attaching 的块设备以目录形式挂载到 pod中,或者从 pod 中卸载块设备。

开发

CSI 插件分为三个部分:

  1. CSI Identity:用来获取 CSI 的身份信息
  2. CSI Controller
  3. CSI Node

参考 k8s 官方的 hostpath 项目:https://github.com/kubernetes-csi/csi-driver-host-path

为了方便开发,在每个阶段 k8s 官方均实现了对应的 SideCarSet 容器。要想研发,仅需要实现 grpc server,又 SideCarSet 容器调用自研的容器。

自研的容器需要实现如下的接口即可。

CSI Identity

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
service Identity {
  // 返回插件名字以及版本号
  rpc GetPluginInfo(GetPluginInfoRequest) returns (GetPluginInfoResponse) {}

  // 返回插件的包含的功能
  rpc GetPluginCapabilities(GetPluginCapabilitiesRequest) returns (GetPluginCapabilitiesResponse) {}

  rpc Probe (ProbeRequest)
    returns (ProbeResponse) {}
}

External provisioner 会调用该接口。

CSI Controller

实现 Volume 中的 Provisioning and Deleting 和 Attaching and Detaching 两个阶段的功能。只有块存储 CSI 插件才需要 Attach 功能。 该部分以中心化组件的方式部署,比如 Deployment。Provision 功能对应的 SidecarSet 为 external-provisioner,Attach 对应的 SidecarSet 为 external-attacher

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
service Controller {
  // Provisioning, External provisioner调用
  // hostPath 实现中会调用 fallocate 实现
  rpc CreateVolume (CreateVolumeRequest)
    returns (CreateVolumeResponse) {}

  // Deleting, External provisioner调用
  rpc DeleteVolume (DeleteVolumeRequest)
    returns (DeleteVolumeResponse) {}

  // Attaching, 只有块设备才需要实现,比如云盘,由External attach 调用
  rpc ControllerPublishVolume (ControllerPublishVolumeRequest)
    returns (ControllerPublishVolumeResponse) {}

  // Detaching,External attach 调用
  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) {}

  rpc ControllerGetVolume (ControllerGetVolumeRequest)
    returns (ControllerGetVolumeResponse) {
        option (alpha_method) = true;
    }

  rpc ControllerModifyVolume (ControllerModifyVolumeRequest)
    returns (ControllerModifyVolumeResponse) {
        option (alpha_method) = true;
    }
}

CSI Node

实现 Volume 中的Mount 和 Umount 阶段,由 kubelet 负责调用。 该部分以 DaemonSet 的形式部署在每个 k8s node 上,对应的 SidecarSet 容器为 node-driver-registrer

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
service Node {
  // 针对块存储类型,将块设备格式化后先挂载到一个临时全局目录
  rpc NodeStageVolume (NodeStageVolumeRequest)
    returns (NodeStageVolumeResponse) {}

  rpc NodeUnstageVolume (NodeUnstageVolumeRequest)
    returns (NodeUnstageVolumeResponse) {}

  // 如果是块存储设备,在执行完 NodeStageVolume 后,使用 linux 的 bind mount 技术将全局目录挂载到pod 中的对应目录
  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) {}
}

资料

协议:https://github.com/container-storage-interface/spec/blob/master/spec.md