强制删除 StatefulSet Pod

本页介绍如何删除属于有状态集的 Pod,并解释在执行此操作时需要注意的事项。

开始之前

  • 这是一个相当高级的任务,并且有可能违反 StatefulSet 固有的一些属性。
  • 在继续之前,请先熟悉下面列出的注意事项。

StatefulSet 注意事项

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

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

删除 Pod

您可以使用以下命令执行优雅的 pod 删除

kubectl delete pods <pod>

为了使上述操作能够实现优雅终止,Pod 不得指定 pod.Spec.TerminationGracePeriodSeconds 为 0。对于 StatefulSet Pod,设置 pod.Spec.TerminationGracePeriodSeconds 为 0 秒的做法是不安全的,强烈不建议这样做。优雅删除是安全的,并且会确保 Pod 在 kubelet 从 apiserver 中删除名称之前优雅关闭

当节点无法访问时,Pod 不会自动删除。在超时后,在无法访问的节点上运行的 Pod 会进入“正在终止”或“未知”状态。当用户尝试优雅删除无法访问的节点上的 Pod 时,Pod 也可能会进入这些状态。从 apiserver 中删除处于这种状态的 Pod 的唯一方法如下

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

建议的最佳实践是使用第一种或第二种方法。如果确认节点已死(例如,永久断开网络连接、已断电等),则删除 Node 对象。如果节点遇到网络分区,请尝试解决此问题或等待其解决。当分区修复后,kubelet 将完成 Pod 的删除并在 apiserver 中释放其名称。

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

强制删除

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

当您强制删除 StatefulSet pod 时,您是在断言有问题的 Pod 将永远不会再与 StatefulSet 中的其他 Pod 联系,并且可以安全地释放其名称以创建替换项。

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

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

如果您使用的任何 kubectl 版本 <= 1.4,则应省略 --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 PST: 清理 tasks/run-application 中的页面 (ba99616c27)