Kubernetes v1.34:从存储卷扩展失效中恢复(GA)

你是否曾经在扩展 Kubernetes 中的持久卷时犯过拼写错误?本来想指定 2TB 却写成了 20TiB? 这个看似无害的问题实际上很难修复——项目花了将近 5 年时间才解决。 存储扩展的自动恢复 此特性在一段时间内一直处于 Beta 状态;不过,随着 v1.34 版本的发布,我们已经将其提升到正式发布状态。

虽然手动从失败的卷扩展中恢复总是可能的,但这通常需要集群管理员权限,而且操作繁琐(更多信息请参见上述链接)。

如果你在申请存储时不小心填错了大小,并且立刻发现了这个错误怎么办? 在 Kubernetes v1.34 中,你可以降低 PersistentVolumeClaim(PVC)请求的存储大小,只要上一次扩容操作还未完成, 就可以修改为新的大小。 Kubernetes 会自动进行修正,归还因扩容失败而暂时占用的配额,并将关联的 PersistentVolume 调整为你最新指定的大小。

我将通过一个示例来演示这一切是如何工作的。

通过降低 PVC 尺寸完成从失败的扩展操作中恢复

想象一下,你的某个数据库服务器磁盘空间不足, 你想将 PVC 从之前指定的 10TB 扩展到 100TB——但你犯了一个拼写错误,指定了 1000TB

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1000TB # 新的大小配置,但不正确!

现在,你的磁盘阵列可能空间不足,或者云平台所分配的配额已用完。 不管怎样,我们先来假设扩展到 1000TB 的操作永远不会成功。

在 Kubernetes v1.34 中,你可以轻松地修正错误,重新请求一个新的 PVC 尺寸,令该尺寸比之前错误请求的更小, 但前提是它仍需大于最初 PersistentVolume 的实际尺寸

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100TB # 更正后的大小;必须大于 10TB。
                     # 你不能将卷缩小到其实际大小以下。

这不需要管理员干预。更好的是,你临时消耗的任何多余 Kubernetes 配额都将自动返回。

这个故障恢复机制有一点很值得注意:无论你为 PVC 所指定的新尺寸是多少, 它必须仍然高于 .status.capacity 中的原始大小。 由于 Kubernetes 不支持缩小你的 PV 对象,你一定不能给出低于你的 PVC 请求的最初分配尺寸。

卷扩展操作的错误处理和可观测性提升

即便看似相对较小的更改,也需要我们几乎完全重新实现 Kubernetes 中卷扩展操作的底层工作方式。 PVC 对象中有新的 API 字段可供你监控以观察卷扩展的进度。

对进行中扩展的可观测性改进

你可以查询 PVC 的 .status.allocatedResourceStatus['storage'] 来监控卷扩展操作的进度。 对于典型的块卷,字段值应该在 ControllerResizeInProgressNodeResizePendingNodeResizeInProgress 之间转换, 并在卷扩展完成时变为 nil(空)。

如果由于某种原因,无法将卷扩展到请求的尺寸,这一字段应该处于对应的 ControllerResizeInfeasibleNodeResizeInfeasible 等状态。

你还可以通过观察 pvc.status.allocatedResources 来观察 Kubernetes 正在处理的大小。

改进的错误处理和报告

Kubernetes 现在应该以较慢的速率重试你已经失败的卷扩展操作,它应该向存储系统和 Kubernetes apiserver 发出更少的请求。

卷扩展期间观察到的错误现在作为 PVC 对象上的状况报告,并且应该持久化,不像事件。当卷扩展失败时, Kubernetes 现在将用错误键 ControllerResizeErrorNodeResizeError 填充 pvc.status.conditions

修复调整大小工作流中的长期错误

此功能还允许我们修复调整大小工作流中的长期存在的若干错误,例如 Kubernetes issue #115294。 如果你观察到任何问题,请将你所发现的错误及如何重新问题的详细信息报告到 https://github.com/kubernetes/kubernetes/issues

此功能的整个开发周期中充满挑战,如果没有 @msau42@jsafrane@xing-yang 的反馈, 就不可能达到正式发布状态。

感谢所有参与此功能开发的贡献者,同时也感谢 @thockin@liggitt 在各种 Kubernetes 贡献者峰会上提供的意见。