本文发布时间已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已不再正确。

Kubernetes 的容器存储接口 (CSI) Alpha 版介绍

Kubernetes的关键差异化因素之一是强大的卷插件系统,该系统使许多不同类型的存储系统能够

  1. 在需要时自动创建存储。
  2. 使存储在容器调度到的任何地方都可用。
  3. 在不再需要时自动删除存储。但是,向Kubernetes添加对新存储系统的支持一直具有挑战性。

Kubernetes 1.9引入了容器存储接口(CSI)的alpha实现,这使得安装新的卷插件就像部署一个pod一样简单。它还使第三方存储提供商能够开发解决方案,而无需添加到核心Kubernetes代码库中。

由于该功能在1.9中为alpha版本,因此必须显式启用。不建议将Alpha功能用于生产环境,但它们很好地指明了项目的发展方向(在本例中,朝着更可扩展和基于标准的Kubernetes存储生态系统发展)。

为什么选择Kubernetes CSI?

Kubernetes卷插件当前是“in-tree”的,这意味着它们与核心kubernetes二进制文件链接、编译、构建和发布。向Kubernetes添加对新存储系统的支持(卷插件)需要将代码检入核心Kubernetes存储库。但是,与Kubernetes发布流程保持一致对许多插件开发人员来说很痛苦。

现有的Flex Volume插件试图通过为外部卷插件公开一个基于exec的API来解决这种痛苦。尽管它使第三方存储供应商能够编写out-of-tree驱动程序,但为了部署第三方驱动程序文件,它需要访问节点和主机的根文件系统。

除了难以部署之外,Flex并未解决插件依赖关系带来的痛点:卷插件往往有许多外部要求(例如,在挂载和文件系统工具上)。这些依赖关系假定在底层主机操作系统上可用,但通常并非如此(并且安装它们需要访问节点机器的根文件系统)。

CSI通过使存储插件能够进行out-of-tree开发、容器化、通过标准Kubernetes原语进行部署,并通过用户熟悉和喜爱的Kubernetes存储原语(PersistentVolumeClaims、PersistentVolumes、StorageClasses)进行使用来解决所有这些问题。

什么是CSI?

CSI的目标是建立一种标准化的机制,使容器编排系统(CO)能够将其任意存储系统公开给其容器化的工作负载。CSI规范源于来自各种容器编排系统(CO)(包括Kubernetes、Mesos、Docker和Cloud Foundry)的社区成员之间的合作。该规范独立于Kubernetes进行开发,并在https://github.com/container-storage-interface/spec/blob/master/spec.md上进行维护。

Kubernetes v1.9公开了CSI规范的alpha实现,使与CSI兼容的卷驱动程序能够在Kubernetes上部署并被Kubernetes工作负载使用。

如何在Kubernetes集群上部署CSI驱动程序?

CSI插件作者将提供他们自己的有关在Kubernetes上部署其插件的说明。

如何使用CSI卷?

假设CSI存储插件已部署在您的集群上,则可以通过熟悉的Kubernetes存储原语来使用它:PersistentVolumeClaims、PersistentVolumes和StorageClasses。

CSI是Kubernetes v1.9中的alpha功能。要启用它,请设置以下标志

CSI is an alpha feature in Kubernetes v1.9. To enable it, set the following flags:

API server binary:
--feature-gates=CSIPersistentVolume=true
--runtime-config=storage.k8s.io/v1alpha1=true
API server binary and kubelet binaries:
--feature-gates=MountPropagation=true
--allow-privileged=true

动态配置

通过创建指向CSI插件的StorageClass,可以为支持动态配置的CSI存储插件启用卷的自动创建/删除。

例如,以下StorageClass通过名为“com.example.team/csi-driver”的CSI卷插件启用对“快速存储”卷的动态创建。

kind: StorageClass

apiVersion: storage.k8s.io/v1

metadata:

  name: fast-storage

provisioner: com.example.team/csi-driver

parameters:

  type: pd-ssd

要触发动态配置,请创建一个PersistentVolumeClaim对象。例如,以下PersistentVolumeClaim使用上面的StorageClass触发动态配置。

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: my-request-for-storage

spec:

  accessModes:

  - ReadWriteOnce

  resources:

    requests:

      storage: 5Gi

  storageClassName: fast-storage

当调用卷配置时,参数“type: pd-ssd”通过“CreateVolume”调用传递给CSI插件“com.example.team/csi-driver”。作为响应,外部卷插件配置一个新卷,然后自动创建一个PersistentVolume对象以表示该新卷。然后,Kubernetes将新的PersistentVolume对象绑定到PersistentVolumeClaim,使其可以使用。

如果将“fast-storage”StorageClass标记为默认,则无需在PersistentVolumeClaim中包含storageClassName,它将默认使用。

预配置卷

您始终可以通过手动创建PersistentVolume对象来表示现有卷来在Kubernetes中公开预先存在的卷。例如,以下PersistentVolume公开一个名称为“existingVolumeName”的卷,该卷属于名为“com.example.team/csi-driver”的CSI存储插件。

apiVersion: v1

kind: PersistentVolume

metadata:

  name: my-manually-created-pv

spec:

  capacity:

    storage: 5Gi

  accessModes:

    - ReadWriteOnce

  persistentVolumeReclaimPolicy: Retain

  csi:

    driver: com.example.team/csi-driver

    volumeHandle: existingVolumeName

    readOnly: false

挂载和挂接

您可以在任何pod或pod模板中引用绑定到CSI卷的PersistentVolumeClaim。

kind: Pod

apiVersion: v1

metadata:

  name: my-pod

spec:

  containers:

    - name: my-frontend

      image: dockerfile/nginx

      volumeMounts:

      - mountPath: "/var/www/html"

        name: my-csi-volume

  volumes:

    - name: my-csi-volume

      persistentVolumeClaim:

        claimName: my-request-for-storage

当调度引用CSI卷的pod时,Kubernetes将针对外部CSI插件触发适当的操作(ControllerPublishVolume,NodePublishVolume等),以确保已挂接,安装并准备好供pod中的容器使用的指定卷。

有关更多详细信息,请参阅CSI实现设计文档文档

如何创建CSI驱动程序?

Kubernetes对CSI卷驱动程序的打包和部署的规定尽可能少。有关在Kubernetes上部署CSI卷驱动程序的最低要求,请参见此处

最低要求文档还包含一个部分,概述了建议的在Kubernetes上部署任意容器化CSI驱动程序的机制。存储提供商可以使用此机制来简化在Kubernetes上部署容器化的与CSI兼容的卷驱动程序。

作为此建议的部署过程的一部分,Kubernetes团队提供以下sidecar(辅助)容器

  • external-attacher

    • Sidecar容器,用于监视Kubernetes VolumeAttachment对象,并针对CSI端点触发ControllerPublish和ControllerUnpublish操作。
  • external-provisioner

    • Sidecar容器,用于监视Kubernetes PersistentVolumeClaim对象,并针对CSI端点触发CreateVolume和DeleteVolume操作。
  • driver-registrar

    • Sidecar容器,用于向kubelet注册CSI驱动程序(将来),并将驱动程序自定义的NodeId(通过针对CSI端点的GetNodeID调用检索)添加到Kubernetes Node API对象上的注释中

存储供应商可以使用这些组件为其插件构建Kubernetes部署,同时使其CSI驱动程序完全不知道Kubernetes。

在哪里可以找到CSI驱动程序?

CSI驱动程序由第三方开发和维护。您可以在此处找到CSI驱动程序示例,但这些示例仅用于说明目的,不打算用于生产工作负载。

Flex怎么样?

Flex Volume插件作为一种基于exec的机制存在,用于创建“out-of-tree”卷插件。尽管它有一些缺点(如上所述),但Flex卷插件与新的CSI卷插件共存。SIG Storage将继续维护Flex API,以使现有的第三方Flex驱动程序(已部署在生产集群中)继续工作。将来,新的卷功能只会添加到CSI,而不会添加到Flex。

内置卷插件将会发生什么?

一旦 CSI 达到稳定状态,我们计划将大多数内置卷插件迁移到 CSI。请继续关注 Kubernetes CSI 实现接近稳定时的更多细节。

alpha 版本的局限性是什么?

CSI 的 alpha 实现具有以下局限性:

  • 不支持 CreateVolume、NodePublishVolume 和 ControllerPublishVolume 调用中的凭据字段。
  • 不支持块卷;仅支持文件卷。
  • 不支持指定文件系统,默认为 ext4。
  • CSI 驱动程序必须与提供的“external-attacher”一起部署,即使它们不实现“ControllerPublishVolume”。
  • Kubernetes 调度器拓扑感知不支持 CSI 卷:简而言之,无法共享有关卷的配置位置(区域、地区等)的信息,以允许 k8s 调度器做出更智能的调度决策。

下一步是什么?

根据反馈和采纳情况,Kubernetes 团队计划在 1.10 或 1.11 版本中将 CSI 实现推向 beta 版本。

如何参与?

像所有 Kubernetes 项目一样,这个项目是来自不同背景的众多贡献者共同努力的结果。非常感谢 Vladimir Vivien (vladimirvivien)、Jan Šafránek (jsafrane)、Chakravarthy Nelluri (chakri-nelluri)、Bradley Childs (childsb)、Luis Pabón (lpabon) 和 Saad Ali (saad-ali) 在将 CSI 带入 Kubernetes 中所做的辛勤工作。

如果您有兴趣参与 CSI 或 Kubernetes 存储系统的任何部分的设计和开发,请加入 Kubernetes 存储特别兴趣小组 (SIG)。我们正在快速发展,并始终欢迎新的贡献者。