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

Kubernetes 中的动态供应和存储类

存储是运行容器的关键部分,而 Kubernetes 提供了一些强大的原语来管理它。动态卷供应是 Kubernetes 特有的功能,允许按需创建存储卷。如果没有动态供应,集群管理员必须手动调用其云或存储提供商来创建新的存储卷,然后在 Kubernetes 中创建 PersistentVolume 对象来表示它们。动态供应功能消除了集群管理员预先供应存储的需求。相反,它会在用户请求存储时自动供应。此功能在 Kubernetes 1.2 中作为 Alpha 版本引入,并在最新版本 1.4 中得到改进并升级为 Beta 版本。此版本使动态供应更加灵活和实用。

新特性有哪些?

动态供应的 Alpha 版本只允许在集群中同时使用一个硬编码的 provisioner。这意味着当 Kubernetes 确定需要动态供应存储时,它总是使用相同的卷插件进行供应,即使集群上有多个存储系统可用。使用的 provisioner 是根据云环境推断的 - AWS 的 EBS,Google Cloud 的 Persistent Disk,OpenStack 的 Cinder,以及 vSphere 上的 vSphere Volumes。此外,用于供应新存储卷的参数是固定的:只有存储大小可配置。这意味着所有动态供应的卷除了存储大小之外都将完全相同,即使存储系统在供应期间暴露了其他可配置参数(例如磁盘类型)。

尽管该功能的 Alpha 版本在实用性上有限,但它让我们能够“摸索”这个想法,并帮助确定了我们想要采取的方向。

Kubernetes 1.4 中新增的动态供应 Beta 版本引入了一个新的 API 对象 StorageClass。可以定义多个 StorageClass 对象,每个对象指定用于供应卷的卷插件(也称为 provisioner)以及在供应时传递给该 provisioner 的一组参数。这种设计允许集群管理员在集群中定义和暴露多种存储类型(来自相同或不同的存储系统) within a cluster,每种类型都有一组自定义参数。这种设计还确保最终用户无需担心存储供应方式的复杂性和细微差别,但仍然能够从多种存储选项中进行选择。

如何使用它?

下面是一个示例,说明集群管理员如何暴露两层存储,以及用户如何选择和使用其中一层。更多详细信息,请参阅参考文档示例文档

管理员配置

集群管理员定义并将两个 StorageClass 对象部署到 Kubernetes 集群

kind: StorageClass

apiVersion: storage.k8s.io/v1beta1

metadata:

  name: slow

provisioner: kubernetes.io/gce-pd

parameters:

  type: pd-standard

这创建了一个名为“slow”的存储类,它将供应标准磁盘类型的 Persistent Disks。

kind: StorageClass

apiVersion: storage.k8s.io/v1beta1

metadata:

  name: fast

provisioner: kubernetes.io/gce-pd

parameters:

  type: pd-ssd

这创建了一个名为“fast”的存储类,它将供应 SSD 类型的 Persistent Disks。

用户请求

用户通过在其 PersistentVolumeClaim 中包含存储类来请求动态供应的存储。对于该功能的 Beta 版本,这是通过 volume.beta.kubernetes.io/storage-class annotation 完成的。此 annotation 的值必须与管理员配置的 StorageClass 名称匹配。

例如,要选择“fast”存储类,用户将创建以下 PersistentVolumeClaim

{

  "kind": "PersistentVolumeClaim",

  "apiVersion": "v1",

  "metadata": {

    "name": "claim1",

    "annotations": {

        "volume.beta.kubernetes.io/storage-class": "fast"

    }

  },

  "spec": {

    "accessModes": [

      "ReadWriteOnce"

    ],

    "resources": {

      "requests": {

        "storage": "30Gi"

      }

    }

  }

}

此声明将导致自动供应一个 SSD 类型的 Persistent Disk。当声明被删除时,该卷也将被销毁。

默认行为

可以为集群启用动态供应,以便所有声明都无需存储类 annotation 即可动态供应。集群管理员通过将一个 StorageClass 对象标记为“default”来启用此行为。可以通过向 StorageClass 添加 storageclass.beta.kubernetes.io/is-default-class annotation 来将其标记为默认。

当存在一个默认 StorageClass 并且用户创建 PersistentVolumeClaim 时未包含存储类 annotation,新的 DefaultStorageClass admission controller(也在 v1.4 中引入)会自动添加指向默认存储类的 annotation。

我还能使用 Alpha 版本吗?

Kubernetes 1.4 保持了与动态供应 Alpha 版本的向后兼容性,以便更平滑地过渡到 Beta 版本。Alpha 行为由 Alpha 动态供应 annotation (volume. alpha.kubernetes.io/storage-class) 的存在触发。请注意,如果 Beta annotation (volume. beta.kubernetes.io/storage-class) 存在,它将优先,并触发 Beta 行为。

Alpha 版本的支持已弃用,并将在未来的版本中移除。

下一步计划?

动态供应和存储类将在未来的版本中继续发展和完善。以下是一些正在考虑进一步开发的领域。

标准云 Provisioner

对于在云提供商上部署 Kubernetes,我们正在考虑自动为云的原生存储系统创建 provisioner。这意味着在 AWS 上的标准部署将生成一个供应 EBS 卷的 StorageClass,在 Google Cloud 上的标准部署将生成一个供应 GCE PD 的 StorageClass。目前也在讨论是否应该将这些 provisioner 标记为默认,这将使动态供应成为默认行为(无需 annotation)。

树外 Provisioner

关于 Kubernetes 存储插件应该“在树内”还是“在树外”一直存在讨论。虽然如何实现树外插件的细节仍未确定,但目前有一个提案,旨在引入一种标准化方法来实现树外动态 provisioner。

如何参与进来?

如果你对参与 Kubernetes 存储的设计和开发感兴趣,请加入 Kubernetes 存储特殊兴趣小组 (SIG)。我们正在快速发展,并且随时欢迎新的贡献者。