强制删除 StatefulSet Pod

此页面展示了如何删除作为 有状态集 部分的 Pod,并解释了在执行此操作时需要考虑的事项。

开始之前

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

有状态集注意事项

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

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

删除 Pod

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

kubectl delete pods <pod>

为了使上述操作导致优雅终止,Pod **必须不**指定 pod.Spec.TerminationGracePeriodSeconds 为 0。为有状态集 Pod 设置 pod.Spec.TerminationGracePeriodSeconds 为 0 秒的做法是不安全的,强烈建议不要这样做。优雅删除是安全的,并将确保 Pod 优雅地关闭,然后 kubelet 从 apiserver 中删除名称。

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

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

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

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

强制删除

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

当您强制删除有状态集 Pod 时,您断言该 Pod 将永远不会再与有状态集中的其他 Pod 建立联系,并且可以安全地释放其名称以创建替换 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}}'

始终谨慎地执行有状态集 Pod 的强制删除,并完全了解所涉及的风险。

下一步

了解有关 调试有状态集 的更多信息。

上次修改时间:2023 年 2 月 19 日下午 9:42 PST:清理 tasks/run-application 中的页面 (ba99616c27)