EKS 1.20集群中Terminating状态Pod持续接收流量问题排查求助
问题原因
这不是EKS的已知bug,本质是Kubernetes Pod终止流程的默认行为和跨节点规则同步延迟导致的,和你遗漏了终止流程的时序配置有关。
Kubernetes Pod终止时,以下两个操作是并行触发的,没有先后顺序:
- 控制面将Pod从Service Endpoint列表中移除,通知所有节点的kube-proxy更新转发规则
- 执行Pod的preStop钩子,之后发送SIGTERM信号给容器进程
你当前的preStop逻辑是直接sleep 250秒,此时集群内其他节点的kube-proxy还没完成规则同步(EKS默认kube-proxy的iptables同步周期是30秒),其他节点上的服务发起的请求(尤其是长连接、HTTP keep-alive复用的连接)仍然会被转发到处于Terminating状态的Pod,就会出现你观察到的“Endpoint已移除、本地节点规则已删除,但Pod仍然收到新请求”的现象。
GKE表现符合预期的原因是GKE默认对kube-proxy的同步周期做了优化,且CNI插件对终止状态Pod的流量拦截做了额外处理,自然规避了这个时序问题。
解决方案
- 调整preStop钩子逻辑,先预留足够的时间等待全集群kube-proxy规则同步完成,再等待业务请求处理完成,示例配置如下:
lifecycle: preStop: exec: command: - /bin/sh - -c - "sleep 30 && sleep 220"
前面的30秒覆盖EKS默认的kube-proxy同步周期,确保所有节点的转发规则都已更新,不会再有新请求进入Pod,后面的220秒用来处理存量飞行请求。
- 业务代码开启优雅关闭逻辑:收到SIGTERM信号后立即停止监听新连接,仅处理已接收的请求,所有请求处理完成后再主动退出,不要完全依赖Kubernetes的流量拦截能力。
- 如有需要可调整kube-proxy的
--iptables-sync-period参数,将默认30秒的同步周期缩短到10秒,加快规则同步速度。 - 检查调用方的长连接配置,设置合理的最大空闲时间,避免连接无限复用导致请求被转发到已摘流的Pod。
内容的提问来源于stack exchange,提问作者Vaibhav Jain
相关产品推荐
相关产品推荐

