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

Kubernetes 1.23:StatefulSet PVC 自动删除(alpha)

Kubernetes v1.23引入了一项新的 Alpha 级别策略,用于 StatefulSets。该策略控制了从 StatefulSet 规范模板生成的 PersistentVolumeClaims (PVCs) 的生命周期,以便在删除 StatefulSet 或缩减 StatefulSet 中的 Pod 时,PVCs 可以自动删除。

这解决了什么问题?

StatefulSet 规范可以包含 Pod 和 PVC 模板。当首次创建副本时,如果副本的 PVC 不存在,Kubernetes 控制平面会为其创建 PVC。Kubernetes v1.23 之前的行为是,控制平面从不清理为 StatefulSets 创建的 PVCs——这留给了集群管理员,或者需要您寻找、检查适用性并部署一些附加自动化工具。手动管理 PVCs 或通过 Helm 等工具管理 PVCs 的常见模式是,PVCs 由管理它们的工具明确跟踪生命周期。使用 StatefulSets 的工作流必须自行确定 StatefulSet 创建了哪些 PVCs 以及它们的生命周期应如何。

在此新功能之前,当由 StatefulSet 管理的副本消失时(无论是 StatefulSet 减少了副本数量,还是 StatefulSet 被删除),PVC 及其后端卷会保留下来,必须手动删除。虽然当数据至关重要时这种行为是适当的,但在许多情况下,这些 PVC 中的持久化数据要么是临时的,要么可以从其他来源重建。在这些情况下,其 StatefulSet 或副本被删除后仍然存在的 PVCs 及其后端卷是不必要的,会产生费用,并需要手动清理。

新的 StatefulSet PVC 保留策略

如果启用 Alpha 功能,StatefulSet 规范将包含一个 PersistentVolumeClaim 保留策略。这用于控制是否以及何时删除从 StatefulSet 的 `volumeClaimTemplate` 创建的 PVC。此保留策略的首次迭代包含两种情况下可以删除 PVCs。

第一种情况是当 StatefulSet 资源被删除时(这意味着所有副本也被删除)。这由 `whenDeleted` 策略控制。第二种情况由 `whenScaled` 控制,即当 StatefulSet 缩减时,这会删除 StatefulSet 中部分而不是所有副本。在这两种情况下,策略可以是 `Retain`(不触动相应的 PVCs),也可以是 `Delete`(表示删除 PVCs)。删除是正常的对象删除,因此例如,底层 PV 的所有保留策略都会被遵守。

此策略形成了四种情况的矩阵。我将逐一讲解并给出示例。

  • `whenDeleted` 和 `whenScaled` 都设置为 `Retain`。 这与 StatefulSets 的现有行为匹配,即不删除任何 PVC。这也是默认的保留策略。当 StatefulSet 卷上的数据不可替代且只能手动删除时,适合使用此策略。

  • `whenDeleted` 设置为 `Delete`,`whenScaled` 设置为 `Retain`。 在这种情况下,PVCs 仅在整个 StatefulSet 被删除时才会被删除。如果 StatefulSet 缩减,PVCs 不受影响,这意味着如果发生扩容,它们可以使用来自先前副本的任何数据重新连接。这可能用于临时 StatefulSet,例如在 CI 实例或 ETL 管道中,StatefulSet 上的数据仅在 StatefulSet 的生命周期内需要,但在任务运行时数据不容易重建。任何保留的状态都需要用于缩减后又扩容的任何副本。

  • `whenDeleted` 和 `whenScaled` 都设置为 `Delete`。 当副本不再需要时,PVC 会立即删除。请注意,这不包括 Pod 被删除并重新调度新版本的情况,例如当节点被排空并且 Pod 需要迁移到其他位置时。PVC 仅在副本不再需要时才会被删除,这通过缩减或 StatefulSet 删除来表示。此用例适用于数据不需要在其副本生命周期之后继续存在的情况。也许数据易于重建,并且删除未使用的 PVCs 的成本节省比快速扩容更重要,或者当创建新副本时,来自先前副本的任何数据都不可用,并且无论如何都必须重建。

  • `whenDeleted` 设置为 `Retain`,`whenScaled` 设置为 `Delete`。 这类似于上一种情况,即在扩容期间保留 PVC 以便快速重用几乎没有好处。一个例子是 Elasticsearch 集群。通常你会根据需求进行扩缩容,同时确保最小副本数量(例如:3)。在缩容时,数据会从移除的副本中迁移出来,因此保留这些 PVCs 没有好处。然而,暂时关闭整个 Elasticsearch 集群进行维护可能会很有用。如果你需要将 Elasticsearch 系统离线,可以通过暂时删除 StatefulSet 来实现,然后通过重新创建 StatefulSet 来恢复 Elasticsearch 集群。包含 Elasticsearch 数据的 PVCs 将仍然存在,新的副本将自动使用它们。

请访问文档,了解所有详细信息。

下一步是什么?

启用该功能并试用!在集群上启用 `StatefulSetAutoDeletePVC` 功能门,然后使用新策略创建 StatefulSet。测试一下并告诉我们您的想法!

我非常好奇这种所有者引用机制在实践中是否能很好地工作。例如,我们意识到 Kubernetes 中没有机制可以知道是谁设置了引用,因此 StatefulSet 控制器可能会与设置自己引用的自定义控制器发生冲突。幸运的是,维护现有保留行为不涉及任何新的所有者引用,因此默认行为将是兼容的。

请将您报告的任何问题标记为 `sig/apps`,并将其分配给 Matthew Cary(GitHub 上的 @mattcary)。

祝您使用愉快!