本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

Kubernetes 的容器存储接口(CSI)进入 Beta 阶段

Kubernetes Logo CSI Logo

Kubernetes 的容器存储接口 (CSI) 实现在 Kubernetes v1.10 中已进入 Beta 阶段。CSI 在 Kubernetes v1.9 中 作为 Alpha 版本引入

Kubernetes 功能通常作为 Alpha 版本引入,并在随后的 Kubernetes 版本中移至 Beta 阶段(最终移至稳定版/GA)。此过程允许 Kubernetes 开发人员获取反馈、发现和修复问题、迭代设计并交付高质量的生产级功能。

为什么要在 Kubernetes 中引入容器存储接口?

尽管 Kubernetes 已经提供了一个强大的卷插件系统,可以轻松使用不同类型的块存储和文件存储,但添加对新卷插件的支持一直具有挑战性。由于卷插件目前是“树内”的——卷插件是核心 Kubernetes 代码的一部分并随核心 Kubernetes 二进制文件一起发布——因此希望向 Kubernetes 添加对其存储系统支持的供应商(甚至修复现有卷插件中的错误)必须与 Kubernetes 发布流程保持一致。

通过采用容器存储接口,Kubernetes 卷层变得真正可扩展。第三方存储开发人员现在可以编写和部署卷插件,在 Kubernetes 中公开新的存储系统,而无需触及核心 Kubernetes 代码。这将为支持 Kubernetes 用户有状态容器化工作负载的存储提供更多选择。

Beta 版有哪些新功能?

随着升级到 Beta 版,CSI 现在默认在标准 Kubernetes 部署上启用,而不是选择性加入。

Kubernetes CSI 实现进入 Beta 阶段还意味着:

  • Kubernetes 与 CSI 规范的 v0.2 版本兼容(而非 v0.1 版本)。
    • CSI 规范 v0.1 和 v0.2 之间存在破坏性更改,因此现有 CSI 驱动程序必须更新为 0.2 兼容,然后才能与 Kubernetes 1.10.0+ 一起使用。
  • 挂载传播(一种允许容器和主机之间双向挂载的功能,容器化 CSI 驱动程序的要求)也已进入 Beta 阶段。
  • Kubernetes VolumeAttachment 对象(在 v1.9 中引入,属于 storage v1alpha1 组)已添加到 storage v1beta1 组。
  • Kubernetes CSIPersistentVolumeSource 对象已升级到 Beta 版。已将 VolumeAttributes 字段添加到 Kubernetes CSIPersistentVolumeSource 对象(在 Alpha 版本中,此字段通过注释传递)。
  • 节点授权器已更新,以限制 kubelet 对 VolumeAttachment 对象的访问。
  • Kubernetes CSIPersistentVolumeSource 对象和 CSI 外部供应器已修改,以允许将秘密传递给 CSI 卷插件。
  • Kubernetes CSIPersistentVolumeSource 已修改,以允许传入文件系统类型(以前总是假定为 ext4)。
  • 已向 CSI 规范添加了一个新的可选调用 NodeStageVolume,并且 Kubernetes CSI 卷插件已修改,以在 MountDevice 期间调用 NodeStageVolume(在 Alpha 版本中,此步骤是一个空操作)。

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

CSI 插件作者必须提供自己的说明,以指导如何在 Kubernetes 上部署其插件。

Kubernetes-CSI 实现团队创建了一个示例 hostpath CSI 驱动程序。该示例大致展示了 CSI 驱动程序的部署过程。然而,生产驱动程序将通过 DaemonSet 部署节点组件,并通过 StatefulSet 部署控制器组件,而不是单个 Pod(例如,请参阅 GCE PD 驱动程序的部署文件)。

如何在 Kubernetes Pod 中使用 CSI 卷?

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

CSI 是 Kubernetes v1.10 中的 Beta 功能。尽管默认启用,但它可能需要以下标志

  • API 服务器二进制文件和 kubelet 二进制文件
    • --allow-privileged=true
      • 大多数 CSI 插件将需要双向挂载传播,这只能为特权 Pod 启用。特权 Pod 仅在设置此标志为 true 的集群上允许(这在某些环境(如 GCE、GKE 和 kubeadm)中是默认设置)。

动态配置

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

例如,以下 StorageClass 启用名为“com.example.csi-driver”的 CSI 卷插件动态创建“fast-storage”卷。

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: fast-storage
provisioner: com.example.csi-driver
parameters:
  type: pd-ssd
  csiProvisionerSecretName: mysecret
  csiProvisionerSecretNamespace: mynamespace

对于 Beta 版新增功能,默认 CSI 外部供应器保留参数键 csiProvisionerSecretNamecsiProvisionerSecretNamespace。如果指定,它将获取秘密并在预配期间将其传递给 CSI 驱动程序。

动态预配由 PersistentVolumeClaim 对象的创建触发。例如,以下 PersistentVolumeClaim 使用上述 StorageClass 触发动态预配。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-request-for-storage
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: fast-storage

当调用卷预配时,参数类型:`pd-ssd` 和任何引用的秘密通过 `CreateVolume` 调用传递给 CSI 插件 `com.example.csi-driver`。作为响应,外部卷插件预配一个新卷,然后自动创建一个 `PersistentVolume` 对象来表示新卷。Kubernetes 然后将新的 `PersistentVolume` 对象绑定到 `PersistentVolumeClaim`,使其准备好使用。

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

预先配置的卷

您始终可以通过手动创建一个 PersistentVolume 对象来表示现有卷,从而在 Kubernetes 中公开预先存在的卷。例如,以下 PersistentVolume 公开一个名为“existingVolumeName”的卷,该卷属于名为“com.example.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.csi-driver
    volumeHandle: existingVolumeName
    readOnly: false
    fsType: ext4
    volumeAttributes:
      foo: bar
    controllerPublishSecretRef:
      name: mysecret1
      namespace: mynamespace
    nodeStageSecretRef:
      name: mysecret2
      namespace: mynamespace
    nodePublishSecretRef
      name: mysecret3
      namespace: mynamespace

附加和挂载

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

kind: Pod
apiVersion: v1
metadata:
  name: my-pod
spec:
  containers:
    - name: my-frontend
      image: 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`、`NodeStageVolume`、`NodePublishVolume` 等),以确保指定的卷被附加、挂载并可供 Pod 中的容器使用。

更多详情请参阅 CSI 实现设计文档文档

如何编写 CSI 驱动程序?

Kubernetes 上的 CSI 卷驱动程序部署必须满足一些最低要求

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

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

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

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

CSI 驱动程序由第三方开发和维护。您可以找到一些示例和生产 CSI 驱动程序的非详尽列表。

FlexVolumes 怎么样?

正如Alpha 版本博客文章中所述,FlexVolume 插件是早期尝试使 Kubernetes 卷插件系统可扩展的方法。尽管它使第三方存储供应商能够编写“树外”驱动程序,但由于它是一个基于 exec 的 API,FlexVolumes 要求将第三方驱动程序二进制文件(或脚本)复制到每个节点(在某些情况下,还有主节点)机器根文件系统上的一个特殊插件目录中。这需要集群管理员对每个节点的主机文件系统具有写访问权限,并且需要一些外部机制来确保如果驱动程序文件被删除,它会被重新创建,仅仅是为了部署一个卷插件。

除了部署困难之外,Flex 也未能解决插件依赖性问题:卷插件往往有许多外部要求(例如,对挂载和文件系统工具的要求)。这些依赖项被假定在底层主机操作系统上可用,但事实往往并非如此。

CSI 解决了这些问题,它不仅使存储插件能够在树外开发,而且能够容器化并通过标准 Kubernetes 原语进行部署。

如果您仍然对树内卷、CSI 和 Flex 之间的区别有疑问,请参阅卷插件 FAQ

树内卷插件会怎么样?

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

Beta 版有哪些限制?

CSI 的 Beta 版实现有以下限制:

  • 不支持块卷;仅支持文件。
  • CSI 驱动程序必须与提供的 external-attacher sidecar 插件一起部署,即使它们没有实现 ControllerPublishVolume
  • CSI 卷不支持拓扑感知,包括与 Kubernetes 调度器共享卷预置位置(区域、地域等)信息以使其做出更智能的调度决策的能力,以及 Kubernetes 调度器或集群管理员或应用程序开发人员指定卷应预置位置的能力。
  • driver-registrar 需要修改所有 Kubernetes 节点 API 对象的权限,这可能导致受损节点获得相同权限。

下一步是什么?

根据反馈和采用情况,Kubernetes 团队计划在 1.12 版本中将 CSI 实现推向 GA。

团队鼓励存储供应商开始开发 CSI 驱动程序,将其部署在 Kubernetes 上,并通过 Kubernetes Slack 频道 wg-csi、Google 群组 kubernetes-sig-storage-wg-csi 或任何标准SIG 存储通信渠道与团队分享反馈。

我如何参与?

这个项目,和所有 Kubernetes 项目一样,是许多来自不同背景的贡献者共同努力的结果。

除了自 Alpha 版本以来一直致力于 Kubernetes CSI 实现的贡献者之外

我们非常感谢本季度为帮助项目达到 Beta 阶段而站出来的新贡献者

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