删除一个 Kubernetes Pod 的过程涉及多个步骤和组件之间的协作,以确保 Pod 被安全地终止并从集群中移除。以下是删除 Pod 的简要流程:
1. 用户或控制器发起删除请求
- 用户通过 kubectl delete pod 命令,或者控制器(如 Deployment, StatefulSet)通过更新其管理的副本数量来触发 Pod 的删除。
- Kubernetes API Server 接收到删除请求后,会将 Pod 的 metadata.deletionTimestamp 字段设置为当前时间,标志着该 Pod 进入删除流程。
2. 更新 Pod 状态为 Terminating
- 一旦 deletionTimestamp 被设置,Pod 的状态会更新为 Terminating。
- 在这个状态下,Pod 仍然存在,并且正在运行中的容器也可能继续运行一段时间。
3. 发送 SIGTERM 信号到 Pod 内的容器
- kubelet 会向 Pod 中的每个容器发送一个 SIGTERM 信号,通知容器需要优雅地终止。这给应用程序一些时间来完成当前的工作并执行清理操作。
- 容器通常有一个默认的 graceful period(默认 30 秒)来完成这些操作。
4. 等待 Graceful Period(优雅终止期)
- kubelet 等待一段时间(由 spec.terminationGracePeriodSeconds 指定,默认是 30 秒),以便容器完成终止过程。
- 在优雅终止期内,Pod 的状态保持为 Terminating,Kubernetes 会等待容器自己退出。
5. 发送 SIGKILL 信号
- 如果在优雅终止期内,容器仍未退出,kubelet 会向容器发送 SIGKILL 信号,强制终止容器。
- 这一步确保即使容器未能优雅退出,它们也会被强制终止,从而完成 Pod 的删除过程。
6. 清理 Pod 资源
- 一旦容器被终止,kubelet 会清理与该 Pod 相关的所有资源,如卷挂载、网络配置、cgroup 等。
- 这些资源的清理确保了系统资源不会被浪费,Pod 被完全移除。
7. 从 API Server 中移除 Pod
- 最后一步,API Server 从其存储(etcd)中删除该 Pod 的资源定义。
- 此时,Pod 完全从集群中消失,不能再通过 kubectl 命令查询到它。
8. 更新控制器状态(如果适用)
- 如果该 Pod 是由控制器(如 Deployment, StatefulSet 等)管理的,控制器会注意到 Pod 的删除,并可能创建新的 Pod 以满足期望的副本数。
- 控制器会根据其策略和配置(如 Deployment 的 maxSurge 和 maxUnavailable)决定如何处理 Pod 的删除。
9. 总结
删除 Pod 的过程旨在确保应用程序有机会优雅地终止,并且所有相关资源都得到正确清理。Kubernetes 通过信号传递、资源清理和状态管理,保证 Pod 被安全地从集群中移除,避免资源泄漏或状态不一致的情况发生。