由于 K8S SIGTERM,RabbitMQ 客户端在服务器中被孤立

RabbitMQ clients orphaned in the server because of K8S SIGTERM

我们有一堆 pods 使用 RabbitMQ。如果 pods 被 K8S 使用 SIGTERM 关闭,我们发现我们的 RMQ 客户端(Python Pika)没有时间关闭与 RMQ 服务器的连接,导致它认为这些客户端仍然存在,直到错过了 2 次心跳。

我们的调查发现,在 SIGTERM 上,K8S 杀死了所有入站和最重要的出站 TCP 连接,除此之外(删除端点等)试图查看在 preStop 挂钩期间是否仍然存在任何连接,但是preStop 似乎非常专注于内部,没有流量出去。

有没有其他人遇到过这个问题并解决了?我们需要做的就是能够在 kubelet 关上门之前将消息传出门外。我们的 pods 不是 K8S“服务”,所以一些 suggestions 没有帮助。

重现步骤:

  1. 向 Sender pod 添加 preStop hook sleep 30s
  2. 用于查看入站请求的 Receiver pod 的尾部日志
  3. 进入 Sender 容器的 shell & loop curl Receiver - 请求出现在日志中
  4. k delete pod 开始终止 Sender pod
  5. curl 请求立即开始在发送方中挂起,接收方日志中没有任何内容

TERM 不会杀死任何东西,由您的应用程序决定如何处理它。 SIGKILL 会在一段时间后发送,它会强制核对进程,但 1) 它也会关闭 RMQ 可以检测到的所有套接字,以及 2) 您可以通过 terminationGracePeriodSeconds

控制容器必须干净关闭多长时间

我们对此进行了广泛测试,发现安装了 Calico(见下文)的新 EKS 集群会遇到此问题,除非升级 Calico。当 Pod 发送 SIGTERM 而不是等待宽限期时,网络将立即终止。如果您遇到此问题并且正在使用 Calico,请针对此线程检查 Calico 的版本:

https://github.com/projectcalico/calico/issues/4518

如果您使用此处找到的 AWS yaml 安装 Calico: https://github.com/aws/amazon-vpc-cni-k8s/tree/master/config

请注意,修复尚未出现在任何已发布的版本中,我们必须从 master 安装,如下所示:

  kubectl apply \
  -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/master/calico-operator.yaml \
  -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/master/config/master/calico-crs.yaml

我们还升级了 AWS CNI 以取得良好效果,尽管这并不是解决我们问题的明确要求:

  kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/v1.8.0/config/v1.8/aws-k8s-cni.yaml
  kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/v1.9.1/config/v1.9/aws-k8s-cni.yaml

这里有一堆 confusing documentation from AWS 让您看起来应该改用新的 AWS“附加组件”来管理这些东西,但在与支持人员进行广泛讨论后,建议不要这样做