pod终止|优雅关闭

两个操作是异步的
要在摘除掉ip后,在开始处理服务管理
所谓T4≤T2 保证服务质量(T4关闭时长取决于集群大小)
在关闭开始的时候,留足够的sleep时间
 
notion image
notion image
Kubernetes (k8s) 中的 Pod 可能因多种原因被删除。以下是一些常见原因:
  1. 手动删除:用户使用 kubectl delete pod 命令手动删除 Pod。
  1. 控制器策略:Deployment、ReplicaSet 或 DaemonSet 等控制器根据其策略调整副本数,例如缩减副本数时会删除多余的 Pod;Job 和 CronJob 完成后删除其创建的 Pod。
  1. 节点故障:如果节点失效,节点上的 Pod 会被 Kubernetes 控制平面标记为失效并在其他节点上重新调度。
  1. 资源限制:当节点资源不足时,Kubernetes 可能会根据优先级和资源限制(如资源配额和调度策略)来删除一些 Pod。
  1. 健康检查失败:Pod 的 liveness 或 readiness 探针连续失败,Kubernetes 会认为 Pod 不健康并删除或重启它。
  1. 优先级抢占:如果有更高优先级的 Pod 需要资源,Kubernetes 可能会删除较低优先级的 Pod 以释放资源。
  1. 调度器策略:Kubernetes 调度器可能会根据调度策略(如 NodeAffinity、PodAffinity 等)重新分配 Pod,从而删除旧的 Pod。
  1. 更新策略:Deployment 或 StatefulSet 进行滚动更新时,旧的 Pod 会被删除并替换为新的 Pod。
  1. 节点自动缩放:当使用集群自动缩放器时,如果集群缩小(移除节点),部分 Pod 会被删除。
但是不管是何种原因删除Pod(用户手动删除或控制器自动删除),在Pod的删除过程中,都会同时会存在两条并行的时间线,如下图所示:
  1. 一条时间线是网络规则的更新过程。
  1. 另一条时间线是 Pod 的删除过程。
    notion image
    由上面流程图可知,在 Pod 删除过程中,存在两条并行的时间线,这两条时间线谁先执行完毕是不确定的。如果 Pod 内的容器已经删除,但网络层面的 Endpoint 资源仍包含该 Pod 的 IP,客户端请求可能会被路由到已删除的 Pod,导致请求处理失败;或者请求未处理完时,Pod 内的容器已经被删除,这样也会导致请求处理失败。
     
    注意从集群中删除的 Pod,因为它们的 IP 地址可能仍然用于路由流量。与立即关闭 Pod 相比,你应该考虑在应用程序中等待更长的时间,或者设置一个 preStop 钩子。只有在集群中的所有端点都被传播并从 kube-proxy、Ingress 控制器、CoreDNS 等中删除后,才应该删除 Pod。
    通过合理的优雅退出配置 T4 <= T2,即在确保网络层面已经删除了Pod IP的前提下,容器再进行优雅退出,在优雅退出过程中继续处理尚未完成的请求,并完成必要的清理工作,如数据保存、连接关闭等。确保Pod在退出时对用户客户端请求是无感知的,同时保证服务的一致性和可靠性。

    时间轴

    隐含的时间轴

    • TerminationGracePeriodSeconds(T1): 总体 Pod 关闭容忍时间。这个值并不是一个固定参考值,每一个应用对着值的要求也不一样,它跟着 Deployment 走,所以这个值有明确的业务属性。
    • Lifecycle PreStop Hook 执行时间(T2): 等待应用进程关闭前需要执行动作的执行时间,这个主要是影响 “新建请求” 到业务 Pod,因为在执行 preStop 的时候 k8s 网络层的变更也在执行。
    • Container Graceful Stop 执行时间(T3): 等待应用自主关闭已有请求的连接,同时结束到数据库之类后端数据写入工作,保证数据都落库或者落盘。
    • Kubernetes 网络层变更时间(T4)
    原则公式:T1 = T2 + T3
    复杂的逻辑:
    这里总结下 Kubernetes 网络层变更时间与 TerminationGracePeriodSeconds 之间在不同情况下,有可能对 http 业务的影响。
    场景
    Http_Code
    描述
    T4<=T2
    200
    正常
    T2<T4<=T1
    200/404
    少量 404,主要看应用的 webservice 如何关闭,如果关闭的优雅,只有 200
    T1<T4
    502
    Bad Gateway,后面的 Pod 已经消失了,但是网络层还没有完成变更,导致流量还在往不存在的 Pod 转发

    处理方法

    心思新密的小伙伴可能逐渐发现,要解决问题,实际就是做一个巧妙的动作调整时间差,满足业务 pod 能够真正的正确的关闭。
    知道了原因,知道了逻辑,那顺理成章的就有了解决方案:
    1. 容器应用进程中要有优雅退出代码,能够执行优雅退出;
    1. 增加 preStopHook,能够执行一定时间的 sleep;
    1. 修改 TerminationGracePeriodSeconds,每一个业务根据实际需要修改;
    当然还有关键的时间点需要考虑:
    1. 尽量满足 T3 >= T4,这样能够保证新建请求能转移到新 Pod 上。
    1. 合理配置 T1 和 T2 的值,留下合理的时间 T3 给 Pod 内的应用做优雅关闭。
    notion image
    Loading...
    文章列表
    王小扬博客
    Git
    AI
    产品
    film
    AI Code
    Java
    其他
    计算机网络
    DB
    云原生
    Node
    Docker
    操作系统
    Elasticsearch
    Apollo
    Nestjs
    Think
    大前端
    PHP
    软件开发
    设计
    生活技巧
    CI
    缓存