Kubernetes pod 长时间处于终止状态接收流量

Vai*_*ain 6 amazon-web-services kubernetes kube-proxy amazon-eks nginx-ingress

我有一个应用程序服务,运行着 2 个 pod,这些 pod 正在接收来自 Kubernetes 集群中另一个服务的流量。

我面临的问题是我的 Pod 被终止并且无法满足飞行中的请求。

因此,为了解决这个问题,我添加了一个 pod 生命周期 preStop 挂钩,以等待 250 秒来完成所有待处理的请求,并将 TerminationGracePeriodSeconds设置 为 300 秒。

lifecycle:
  preStop:
    exec:
      command:
      - /bin/sleep
      - "250"
Run Code Online (Sandbox Code Playgroud)

现在我期望的是,当 Pod 转换到 Terminate 状态时,它应该停止接收新请求,只满足它已经有的请求,但这并没有发生。

Pod 持续接收流量直到最后一秒,最终在 preStop 完成后被杀死,最终调用应用程序收到 502 错误代码。

因此,为了调试此问题,我进一步进行了操作,并怀疑可能是端点在服务中未正确更新,但我错了。当 Pod 转换到终止状态时,端点将从服务中删除,但 Pod 继续获取流量。

然后我登录到节点并检查 IPtables 以获取 IP 表转发规则,以验证 pod IP 是否仍然存在,但当 pod 转换为 Terminate 时,IPtable 转发规则立即更新。

>sudo iptables -t nat -L  KUBE-SVC-MYVS2X43QAGQT6BT -n | column -t
Chain                      KUBE-SVC-MYVS2X43QAGQT6BT  (1   references)
target                     prot                       opt  source       destination
KUBE-SEP-HDK3MJ4L3R3PLTOQ  all                        --   <IP>    <IP>    /*  default/test-cart-service:http  */  statistic  mode  random  probability  0.50000000000
KUBE-SEP-237VYZFMFXN2THCB  all                        --   <IP>    <IP>    /*  default/test-cart-service:http  */

>sudo iptables -t nat -L KUBE-SEP-HDK3MJ4L3R3PLTOQ -n | column -t
Chain           KUBE-SEP-HDK3MJ4L3R3PLTOQ  (1   references)
target          prot                       opt  source          destination
KUBE-MARK-MASQ  all                        --   <IP>  <IP>    /*  default/test-cart-service:http  */
DNAT            tcp                        --   <IP>  <IP>  /*  default/test-cart-service:http  */  tcp  to:<IP>:<PORT>

>sudo iptables -t nat -L KUBE-SEP-HDK3MJ4L3R3PLTOQ -n | column -t
iptables: No chain/target/match by that name.

Run Code Online (Sandbox Code Playgroud)

因此 kube-proxy 立即更新了表,但 pod 仍在接收流量。

我尝试直接端口转发服务以及使用网络流(ELB->Ingress->Service->pod)来命中它,认为这可能是负载均衡器问题,但结果是相同的。

K8s 由 Amazon EKS(1.20)管理 ,Ingress 服务映射到 Amazon classic Load Balancer(ELB)。

我不确定我错过了什么。如果这是 EKS 错误或与 k8s 行为相关的问题。

更新:

在 GKE 上测试了相同的场景,它按预期工作。然后,当 pod 进入 Terminate 状态时,它就停止接收流量并仅完成待处理的请求。