强制删除 StatefulSet Pod

本页面展示了如何删除属于 StatefulSet 的 Pod,并解释了在执行此操作时需要注意的事项。

准备工作

  • 这是一个相当高级的任务,有可能会破坏 StatefulSet 固有的某些属性。
  • 在继续之前,请务必熟悉下面列出的注意事项。

StatefulSet 注意事项

在 StatefulSet 的正常操作中,永远没有必要强制删除 StatefulSet Pod。 StatefulSet 控制器负责创建、扩缩和删除 StatefulSet 的成员。它试图确保从序号 0 到 N-1 的指定数量的 Pod 处于活跃和就绪状态。StatefulSet 确保在任何时候,集群中最多只有一个具有给定身份的 Pod 在运行。这被称为 StatefulSet 提供的**至多一个**语义。

手动强制删除应谨慎进行,因为它可能会违反 StatefulSet 固有的至多一个语义。StatefulSet 可用于运行分布式和集群应用程序,这些应用程序需要稳定的网络身份和稳定的存储。这些应用程序通常具有依赖于固定数量的具有固定身份的成员集合的配置。拥有多个相同身份的成员可能会造成灾难性后果,并可能导致数据丢失(例如,基于仲裁的系统中的脑裂情况)。

删除 Pods

你可以使用以下命令执行优雅的 Pod 删除

kubectl delete pods <pod>

要使上述操作实现优雅终止,Pod **不得**指定 `pod.Spec.TerminationGracePeriodSeconds` 为 0。将 `pod.Spec.TerminationGracePeriodSeconds` 设置为 0 秒的做法不安全,强烈不建议 StatefulSet Pod 使用。优雅删除是安全的,它将确保 Pod 优雅关闭,然后 kubelet 从 apiserver 中删除该名称。

当节点无法访问时,Pod 不会自动删除。在超时后,在无法访问的节点上运行的 Pod 会进入“Terminating”或“Unknown”状态。当用户尝试优雅删除无法访问节点上的 Pod 时,Pod 也可能进入这些状态。处于这种状态的 Pod 只能通过以下方式从 apiserver 中移除:

  • Node 对象被删除(由你或由 Node Controller)。
  • 无响应节点上的 kubelet 开始响应,杀死 Pod 并从 apiserver 中删除该条目。
  • 用户强制删除 Pod。

推荐的最佳实践是采用第一种或第二种方法。如果节点被确认死亡(例如,永久断开网络连接、断电等),则删除节点对象。如果节点出现网络分区,则尝试解决或等待其解决。当分区恢复时,kubelet 将完成 Pod 的删除,并在 apiserver 中释放其名称。

通常,一旦 Pod 不再在节点上运行,或者节点被管理员删除,系统就会完成删除。你可以通过强制删除 Pod 来覆盖此行为。

强制删除

强制删除**不会**等待 kubelet 确认 Pod 已终止。无论强制删除是否成功杀死 Pod,它都会立即从 apiserver 中释放该名称。这将允许 StatefulSet 控制器创建具有相同身份的替换 Pod;这可能导致仍在运行的 Pod 重复,并且如果该 Pod 仍能与 StatefulSet 的其他成员通信,将违反 StatefulSet 旨在保证的至多一个语义。

当你强制删除 StatefulSet Pod 时,你是在断言该 Pod 永远不会再与 StatefulSet 中的其他 Pod 通信,并且其名称可以安全地释放以创建替换 Pod。

如果你想使用 kubectl 版本 >= 1.5 强制删除 Pod,请执行以下操作:

kubectl delete pods <pod> --grace-period=0 --force

如果你使用任何版本小于等于 1.4 的 kubectl,应省略 `--force` 选项并使用:

kubectl delete pods <pod> --grace-period=0

如果即使执行了这些命令,Pod 仍停留在 `Unknown` 状态,请使用以下命令从集群中移除 Pod:

kubectl patch pod <pod> -p '{"metadata":{"finalizers":null}}'

务必谨慎执行 StatefulSet Pod 的强制删除,并完全了解所涉及的风险。

下一步

了解更多关于调试 StatefulSet的信息。

最后修改于 2023 年 2 月 19 日太平洋标准时间晚上 9:42:清理任务/运行应用程序中的页面 (ba99616c27)