强制删除 StatefulSet 类型的 Pods
本文介绍了如何删除 StatefulSet 管理的部分 pods,并且解释了这样操作时需要记住的注意事项。
准备开始
- 这是一项相当高级的任务,并且可能会违反 StatefulSet 固有的某些属性。
- 继续任务之前,请熟悉下面列举的注意事项。
StatefulSet 注意事项
在 StatefulSet 的正常操作中,永远不需要强制删除 StatefulSet 管理的 pod。StatefulSet 控制器负责创建,扩容和删除 StatefulSet 管理的 pods。它尝试确保从序号 0 到 N-1 指定数量的 pods 处于活动状态并准备就绪。StatefulSet 确保在任何时候,集群中最多只有一个具有给定标识的 pod。这就是所谓的由 StatefulSet 提供的*最多一个*的语义。
应谨慎进行手动强制删除操作,因为它可能会违反 StatefulSet 固有的至多一个的语义。StatefulSets 可用于运行分布式和集群级的应用,这些应用需要稳定的网络标识和可靠的存储。这些应用通常配置为具有固定标识固定数量的成员集合。具有相同身份的多个成员可能是灾难性的,并且可能导致数据丢失 (e.g. 基于 quorum 系统中的脑裂场景)。
删除 Pods
您可以使用下面的命令执行优雅地删除 pod:
kubectl delete pods <pod>
为了使上面的方法能够正常终止,Pod 一定不能设置 pod.Spec.TerminationGracePeriodSeconds
为 0。将 pod.Spec.TerminationGracePeriodSeconds
设置为 0s 的做法是不安全的,强烈建议 StatefulSet 类型的 pods 不要使用。优雅删除是安全的,并且会在 kubelet 从 apiserver 中删除名称之前确保 优雅地关闭 pod 。
Kubernetes (1.5 版本或者更新版本)不会因为一个 Node 无法访问而删除 pods。在无法访问节点上运行的 pods 在超时后会进入’Terminating’ 或者 ‘Unknown’ 状态。当用户尝试优雅删除无法访问节点上的 pod 时,pods 也可能会进入这些状态。从 apiserver 中删除处于这些状态 pod 的唯一方法如下:
Node 对象被删除(要么您删除, 或者Node Controller)。
无响应节点上的 kubelet 开始响应,杀死 pod 并从 apiserver 中移除该条目。
用户强制删除 pod。
推荐使用第一种或者第二种方法。如果确认节点已经不可用了 (比如,永久断开网络,断电等),则删除 Node 对象。如果节点遇到网裂,请尝试解决该问题或者等待其解决。当网裂愈合时,kubelet 将完成 pod 的删除并从 apiserver 中释放其名字。
通常,pod 一旦不在节点上运行,或者管理员删除了节点,系统就会完成删除。你可以通过强制删除 pod 来覆盖它。
强制删除
强制删除不要等待来自 kubelet 的确认 pod 已被终止。无论强制删除是否成功杀死了 pod,它都会立即从 apiserver 中释放该名字。这将让 StatefulSet 控制器创建一个具有相同标识的替换 pod;这可能导致正在运行 pod 的重复,并且如果所述 pod 仍然可以与 StatefulSet 的成员通信,则将违反 StatefulSet 旨在保证的最多一个的语义。
当你强制删除 StatefulSet 类型的 pod 时,你要确保有问题的 pod 不会再和 StatefulSet 管理的其他 pods通信,并且可以安全地释放其名字以便创建替换 pod。
如果要使用 kubectl version >= 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 类型的 pods,并完全了解所涉及地风险。
接下来
进一步了解调试 StatefulSet。