强制删除 StatefulSet Pods

此页面展示了如何删除作为 有状态集 的一部分的 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 联系,并且其名称可以安全地释放以供创建替换。

如果您想使用 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:清理任务/运行应用程序中的页面 (ba99616c27)