这篇文章已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已不再正确。
Kubernetes v1.26:追溯性默认 StorageClass
Kubernetes v1.25 版本引入了一个 Alpha 功能,用于改变如何将默认 StorageClass 分配给 PersistentVolumeClaim (PVC)。启用此功能后,你不再需要先创建默认 StorageClass,然后创建 PVC 来分配类。此外,任何未分配 StorageClass 的 PVC 稍后都可以更新。此功能已在 Kubernetes v1.26 中升级到 Beta。
你可以在 Kubernetes 文档中阅读追溯式默认 StorageClass 分配,了解更多关于如何使用此功能的信息,或者你可以继续阅读,了解 Kubernetes 项目为何做出这一改变。
为什么 StorageClass 分配需要改进
用户可能已经熟悉一个类似的功能,即在创建时为新的 PVC 分配默认 StorageClass。这目前由准入控制器处理。
但是如果在创建 PVC 时没有定义默认 StorageClass 怎么办?用户最终会得到一个永远不会被分配类的 PVC。结果是不会供应存储,并且 PVC 会在此处“卡住”。通常,两种主要场景可能导致 PVC“卡住”并在后续引起问题。让我们更详细地看看每种情况。
更改默认 StorageClass
启用此 Alpha 功能后,管理员在想要更改默认 StorageClass 时有两种选择
在移除与 PVC 关联的旧 StorageClass 之前,创建一个新的 StorageClass 作为默认。这会导致在短时间内存在两个默认。此时,如果用户创建一个将 storageClassName 设置为
null
的 PersistentVolumeClaim(表示默认 StorageClass),则将选择最新的默认 StorageClass 并分配给此 PVC。首先移除旧的默认 StorageClass,然后创建一个新的默认 StorageClass。这会导致在短时间内没有默认 StorageClass。随后,如果用户创建一个将 storageClassName 设置为
null
的 PersistentVolumeClaim(表示默认 StorageClass),则该 PVC 将永远处于Pending
状态。用户必须通过删除 PVC 并在默认 StorageClass 可用后重新创建它来解决此问题。
集群安装期间的资源顺序
如果集群安装工具需要创建需要存储的资源,例如镜像仓库,则很难正确设置顺序。这是因为任何需要存储的 Pod 都依赖于默认 StorageClass 的存在,并且如果未定义默认 StorageClass,则无法创建这些 Pod。
发生了什么变化
我们更改了 PersistentVolume (PV) 控制器,使其能够为任何 storageClassName 设置为 null
的未绑定 PersistentVolumeClaim 分配默认 StorageClass。我们还修改了 API Server 中的 PersistentVolumeClaim 准入,允许将未设置的值更改为实际的 StorageClass 名称。
Null storageClassName
与 storageClassName: ""
- 有区别吗?
在引入此功能之前,这些值在行为上是相同的。任何将 storageClassName 设置为 null
或 ""
的 PersistentVolumeClaim 都将绑定到 storageClassName 也设置为 null
或 ""
的现有 PersistentVolume 资源。
启用此新功能后,我们希望保持这种行为,同时也能更新 StorageClass 名称。考虑到这些限制,此功能改变了 null
的语义。如果存在默认 StorageClass,则 null
将转换为“给我一个默认”,而 ""
则表示“给我一个 StorageClass 名称也为 ""
的 PersistentVolume”。在没有 StorageClass 的情况下,行为将保持不变。
总结上述内容,我们更改了 null
的语义,使其行为取决于默认 StorageClass 定义的存在与否。
下表展示了所有这些情况,以便更好地描述 PVC 何时绑定以及其 StorageClass 何时更新。
PVCstorageClassName = "" | PVCstorageClassName= null | ||
---|---|---|---|
没有默认类时 | PVstorageClassName = "" | 绑定 | 绑定 |
没有 PVstorageClassName | 绑定 | 绑定 | |
有默认类时 | PVstorageClassName = "" | 绑定 | 类更新 |
没有 PVstorageClassName | 绑定 | 类更新 |
如何使用
如果你想在功能处于 Alpha 阶段时测试它,你需要启用 kube-controller-manager 和 kube-apiserver 中的相关 Feature Gate。使用 --feature-gates
命令行参数。
--feature-gates="...,RetroactiveDefaultStorageClass=true"
试用
如果你想查看此功能实际运行并验证它在你的集群中正常工作,你可以尝试以下操作
定义一个基本的 PersistentVolumeClaim
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-1 spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
在没有默认 StorageClass 时创建 PersistentVolumeClaim。此 PVC 将不会供应或绑定(除非已存在一个现有且合适的 PV),并将保持
Pending
状态。kubectl get pvc
输出类似于此
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-1 Pending
配置一个 StorageClass 作为默认。
kubectl patch sc -p '{"metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
输出类似于此
storageclass.storage.k8s.io/my-storageclass patched
验证 PersistentVolumeClaims 现在已正确供应,并且已追溯式地更新为新的默认 StorageClass。
kubectl get pvc
输出类似于此
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-1 Bound pvc-06a964ca-f997-4780-8627-b5c3bf5a87d8 1Gi RWO my-storageclass 87m
新的指标
为了帮助你查看此功能是否按预期工作,我们还引入了新的 retroactive_storageclass_total
指标,用于显示 PV 控制器尝试更新 PersistentVolumeClaim 的次数,以及 retroactive_storageclass_errors_total
指标,用于显示其中失败的尝试次数。
参与其中
我们始终欢迎新的贡献者,如果你想参与其中,可以加入我们的 Kubernetes Storage 特别兴趣小组 (SIG)。
如果你想分享反馈,可以在我们的公共 Slack 频道上进行。
特别感谢所有提供出色评审、分享宝贵见解并帮助实现此功能的贡献者(按字母顺序排列)
- Deep Debroy (ddebroy)
- Divya Mohan (divya-mohan0209)
- Jan Šafránek (jsafrane)
- Joe Betz (jpbetz)
- Jordan Liggitt (liggitt)
- Michelle Au (msau42)
- Seokho Son (seokho-son)
- Shannon Kularathna (shannonxtreme)
- Tim Bannister (sftim)
- Tim Hockin (thockin)
- Wojciech Tyczynski (wojtek-t)
- Xing Yang (xing-yang)