Container Storage Interface

Container Storage Interface (CSI) 是从 v1.9 引入的容器存储接口,并于 v1.13 版本正式 GA。实际上,CSI 是整个容器生态的标准存储接口,同样适用于 Mesos、Cloud Foundry 等其他的容器集群调度系统。

版本信息

Kubernetes CSI Spec Status
v1.9 v0.1.0 Alpha
v1.10 v0.2.0 Beta
v1.11-v1.12 v0.3.0 Beta
v1.13 v0.3.0, v1.0.0 GA

Sidecar 容器版本

Container Name Description CSI spec Latest Release Tag
external-provisioner Watch PVC and create PV v1.0.0 v1.0.1
external-attacher Operate VolumeAttachment v1.0.0 v1.0.1
external-snapshotter Operate VolumeSnapshot v1.0.0 v1.0.1
node-driver-registrar Register kubelet plugin v1.0.0 v1.0.2
cluster-driver-registrar Register CSIDriver Object v1.0.0 v1.0.1
livenessprobe Monitors health of CSI driver v1.0.0 v1.0.2

原理

类似于 CRI,CSI 也是基于 gRPC 实现。详细的 CSI SPEC 可以参考 这里,它要求插件开发者要实现三个 gRPC 服务:

  • Identity Service:用于 Kubernetes 与 CSI 插件协调版本信息
  • Controller Service:用于创建、删除以及管理 Volume 存储卷
  • Node Service:用于将 Volume 存储卷挂载到指定的目录中以便 Kubelet 创建容器时使用(需要监听在 /var/lib/kubelet/plugins/[SanitizedCSIDriverName]/csi.sock

由于 CSI 监听在 unix socket 文件上, kube-controller-manager 并不能直接调用 CSI 插件。为了协调 Volume 生命周期的管理,并方便开发者实现 CSI 插件,Kubernetes 提供了几个 sidecar 容器并推荐使用下述方法来部署 CSI 插件:

Recommended CSI Deployment Diagram

该部署方法包括:

  • StatefuelSet:副本数为 1 保证只有一个实例运行,它包含三个容器
    • 用户实现的 CSI 插件
    • External Attacher:Kubernetes 提供的 sidecar 容器,它监听 VolumeAttachmentPersistentVolume 对象的变化情况,并调用 CSI 插件的 ControllerPublishVolume 和 ControllerUnpublishVolume 等 API 将 Volume 挂载或卸载到指定的 Node 上
    • External Provisioner:Kubernetes 提供的 sidecar 容器,它监听 PersistentVolumeClaim 对象的变化情况,并调用 CSI 插件的 ControllerPublishControllerUnpublish 等 API 管理 Volume
  • Daemonset:将 CSI 插件运行在每个 Node 上,以便 Kubelet 可以调用。它包含 2 个容器
    • 用户实现的 CSI 插件
    • Driver Registrar:注册 CSI 插件到 kubelet 中,并初始化 NodeId(即给 Node 对象增加一个 Annotation csi.volume.kubernetes.io/nodeid

配置

  • API Server 配置:
  1. --allow-privileged=true
  2. --feature-gates=CSIPersistentVolume=true,MountPropagation=true
  3. --runtime-config=storage.k8s.io/v1alpha1=true
  • Controller-manager 配置:
  1. --feature-gates=CSIPersistentVolume=true
  • Kubelet 配置:
  1. --allow-privileged=true
  2. --feature-gates=CSIPersistentVolume=true,MountPropagation=true

示例

Kubernetes 提供了几个 CSI 示例,包括 NFS、ISCSI、HostPath、Cinder 以及 FlexAdapter 等。在实现 CSI 插件时,这些示例可以用作参考。

Name Status More Information
Cinder v0.2.0 A Container Storage Interface (CSI) Storage Plug-in for Cinder
DigitalOcean Block Storage v0.0.1 (alpha) A Container Storage Interface (CSI) Driver for DigitalOcean Block Storage
AWS Elastic Block Storage v0.0.1(alpha) A Container Storage Interface (CSI) Driver for AWS Elastic Block Storage (EBS)
GCE Persistent Disk Alpha A Container Storage Interface (CSI) Storage Plugin for Google Compute Engine Persistent Disk
OpenSDS Beta For more information, please visit releases and https://github.com/opensds/nbp/tree/master/csi
Portworx 0.2.0 CSI implementation is available here which can be used as an example also.
RBD v0.2.0 A Container Storage Interface (CSI) Storage RBD Plug-in for Ceph
CephFS v0.2.0 A Container Storage Interface (CSI) Storage Plug-in for CephFS
ScaleIO v0.1.0 A Container Storage Interface (CSI) Storage Plugin for DellEMC ScaleIO
vSphere v0.1.0 A Container Storage Interface (CSI) Storage Plug-in for VMware vSphere
NetApp v0.2.0 (alpha) A Container Storage Interface (CSI) Storage Plug-in for NetApp’s Trident container storage orchestrator
Ember CSI v0.2.0 (alpha) Multi-vendor CSI plugin supporting over 80 storage drivers to provide block and mount storage to Container Orchestration systems.
Nutanix beta A Container Storage Interface (CSI) Storage Driver for Nutanix
Quobyte v0.2.0 A Container Storage Interface (CSI) Plugin for Quobyte

下面以 NFS 为例来看一下 CSI 插件的使用方法。

首先需要部署 NFS 插件:

  1. git clone https://github.com/kubernetes-csi/drivers
  2. cd drivers/pkg/nfs
  3. kubectl create -f deploy/kubernetes

然后创建一个使用 NFS 存储卷的容器

  1. kubectl create -f examples/kubernetes/nginx.yaml

该例中已直接创建 PV 的方式使用 NFS

  1. apiVersion: v1
  2. kind: PersistentVolume
  3. metadata:
  4. name: data-nfsplugin
  5. labels:
  6. name: data-nfsplugin
  7. annotations:
  8. csi.volume.kubernetes.io/volume-attributes: '{"server":"10.10.10.10","share":"share"}'
  9. spec:
  10. accessModes:
  11. - ReadWriteOnce
  12. capacity:
  13. storage: 100Gi
  14. csi:
  15. driver: csi-nfsplugin
  16. volumeHandle: data-id
  17. ---
  18. apiVersion: v1
  19. kind: PersistentVolumeClaim
  20. metadata:
  21. name: data-nfsplugin
  22. spec:
  23. accessModes:
  24. - ReadWriteOnce
  25. resources:
  26. requests:
  27. storage: 100Gi
  28. selector:
  29. matchExpressions:
  30. - key: name
  31. operator: In
  32. values: ["data-nfsplugin"]

也可以用在 StorageClass 中

  1. kind: StorageClass
  2. apiVersion: storage.k8s.io/v1
  3. metadata:
  4. name: csi-sc-nfsplugin
  5. provisioner: csi-nfsplugin
  6. parameters:
  7. ---
  8. apiVersion: v1
  9. kind: PersistentVolumeClaim
  10. metadata:
  11. name: request-for-storage
  12. spec:
  13. accessModes:
  14. - ReadWriteOnce
  15. resources:
  16. requests:
  17. storage: 5Gi
  18. storageClassName: csi-sc-nfsplugin

参考文档