由于 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 没有帮助。
重现步骤:
- 向 Sender pod 添加 preStop hook sleep 30s
- 用于查看入站请求的 Receiver pod 的尾部日志
- 进入 Sender 容器的 shell & loop curl Receiver - 请求出现在日志中
k delete pod
开始终止 Sender pod
- 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“附加组件”来管理这些东西,但在与支持人员进行广泛讨论后,建议不要这样做
我们有一堆 pods 使用 RabbitMQ。如果 pods 被 K8S 使用 SIGTERM 关闭,我们发现我们的 RMQ 客户端(Python Pika)没有时间关闭与 RMQ 服务器的连接,导致它认为这些客户端仍然存在,直到错过了 2 次心跳。
我们的调查发现,在 SIGTERM 上,K8S 杀死了所有入站和最重要的出站 TCP 连接,除此之外(删除端点等)试图查看在 preStop 挂钩期间是否仍然存在任何连接,但是preStop 似乎非常专注于内部,没有流量出去。
有没有其他人遇到过这个问题并解决了?我们需要做的就是能够在 kubelet 关上门之前将消息传出门外。我们的 pods 不是 K8S“服务”,所以一些 suggestions 没有帮助。
重现步骤:
- 向 Sender pod 添加 preStop hook sleep 30s
- 用于查看入站请求的 Receiver pod 的尾部日志
- 进入 Sender 容器的 shell & loop curl Receiver - 请求出现在日志中
k delete pod
开始终止 Sender pod- 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“附加组件”来管理这些东西,但在与支持人员进行广泛讨论后,建议不要这样做