Volume插件扩展

    如果内置的这些Volume还不满足要求,则可以使用 FlexVolume 或者 CSI 实现自己的Volume插件。

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

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

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

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

    该部署方法包括:

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

    Kubernetes 提供了几个 CSI 示例,包括 NFS、ISCSI、HostPath、Cinder 以及 FlexAdapter 等。在实现 CSI 插件时,这些示例可以用作参考。下面以 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. apiVersion: v1
    2. kind: PersistentVolume
    3. metadata:
    4. labels:
    5. name: data-nfsplugin
    6. annotations:
    7. csi.volume.kubernetes.io/volume-attributes: '{"server": "10.10.10.10", "share": "share"}'
    8. spec:
    9. accessModes:
    10. - ReadWriteOnce
    11. capacity:
    12. storage: 100Gi
    13. csi:
    14. driver: csi-nfsplugin
    15. ---
    16. apiVersion: v1
    17. kind: PersistentVolumeClaim
    18. metadata:
    19. name: data-nfsplugin
    20. spec:
    21. accessModes:
    22. - ReadWriteOnce
    23. resources:
    24. requests:
    25. storage: 100Gi
    26. selector:
    27. matchExpressions:
    28. - key: name
    29. values: ["data-nfsplugin"]

    也可以用在 StorageClass 中

    实现一个FlexVolume包括两个步骤

    • 实现,包括init/attach/detach/mount/umount等命令(可参考lvm示例和)
    • 将插件放到/usr/libexec/kubernetes/kubelet-plugins/volume/exec/<vendor~driver>/<driver>目录中

    而在使用flexVolume时,需要指定卷的driver,格式为<vendor~driver>/<driver>,如下面的例子使用了kubernetes.io/lvm

    1. kind: Pod
    2. metadata:
    3. name: nginx
    4. namespace: default
    5. spec:
    6. containers:
    7. - name: nginx
    8. image: nginx
    9. volumeMounts:
    10. - name: test
    11. mountPath: /data
    12. ports:
    13. - containerPort: 80
    14. volumes:
    15. - name: test
    16. flexVolume:
    17. driver: "kubernetes.io/lvm"
    18. fsType: "ext4"
    19. options:
    20. volumeID: "vol1"
    21. volumegroup: "kube_vg"