首页 > 解决方案 > 使用 externalTrafficPolicy: Local 在 GKE 上是否可以进行无中断滚动更新?

问题描述

我有一个 GKE 集群(1.12.10-gke.17)。

我正在运行nginx -ingress-controllertype: LoadBalancer

我已设置externalTrafficPolicy: Local保留源 ip

一切都很好,除了在滚动更新期间。我有maxSurge: 1maxUnavailable: 0

我的问题是在滚动更新期间,我开始收到请求超时。Terminating我怀疑即使运行状况检查失败,Google 负载均衡器仍在向 pod 所在的节点发送请求。当 pod 从Running变为时,这会发生大约 30-60 秒Terminating。一段时间后一切都会稳定下来,流量最终只会流向带有新 pod 的新节点。

如果负载均衡器停止向终止 pod 发送请求的速度很慢,是否有某种方法可以使这些滚动部署无中断?


我的理解是,在正常的k8s服务中,externalTrafficPolicy不正常的地方,谷歌负载均衡器只是简单地向所有节点发送请求,让iptables来整理。当 pod 存在时Terminating,iptables 会快速更新,并且流量不会再发送到该 pod。但是,在 where 的情况下externalTrafficPolicyLocal如果接收请求的节点没有Runningpod,则请求超时,这就是这里发生的情况。

如果这是正确的,那么我只看到两个选项

  1. Terminating停止使用pod向节点发送请求
  2. 继续服务请求,即使 pod 是Terminating

我觉得选项 1 很困难,因为它需要通知负载均衡器 Pod 即将启动Terminating

我在选项 2 上取得了一些进展,但到目前为止还没有让它发挥作用。我已经设法通过添加一个preStop刚刚运行的生命周期钩子继续为来自 pod 的请求提供服务sleep 60,但我认为问题在于healthCheckNodePort报告localEndpoints: 0和我怀疑在到达节点和到达 pod 之间有什么东西阻塞了请求。也许,iptables 在localEndpoints: 0.

我还调整了与readinessProbeand不同的 Google 负载均衡器健康检查,将其livenessProbe设置为可能的“最快”设置,例如 1s 间隔、1 个故障阈值,并且我已经验证负载均衡器后端 aka k8s 节点确实无法正常运行快速检查,但无论如何都会继续向终止的 pod 发送请求。

标签: kubernetestimeoutgoogle-kubernetes-enginenginx-ingresskubernetes-health-check

解决方案


这里有类似的讨论。尽管它不完全相同,但它是一个相似的用例。

一切听起来都像预期的那样工作。

  • LoadBalancer 将根据 LoadBalancer 健康检查将流量发送到任何健康节点。LoadBalancer 不知道单个 pod。

  • 一旦超过健康检查阈值,健康检查就会将节点标记为不健康,即每隔 x 秒发送一次 HC,有 x 个超​​时延迟,x 个失败请求。这会导致 pod 终止和标记为不健康之间的延迟。

  • 另请注意,一旦 pod 被标记为 notReady,该 pod 就会从服务端点中删除。如果某个节点上没有其他 pod,流量将继续到达该节点(由于上面解释的 HC 行为),由于 externalTrafficPolicy 无法转发请求(流量保留在发送它的节点上)。

有几种方法可以解决这个问题。

  1. 为了最大限度地减少终止的 pod 和被标记为不健康的节点之间的时间量,您可以设置更积极的健康检查。这样做的问题是,过于敏感的 HC 可能会导致误报,通常会增加节点的开销(额外的健康检查请求),并且不会完全消除失败的请求。

  2. 运行足够的 pod,以便每个节点始终至少有 2 个 pod。由于服务一旦进入 notReady 就会从端点中删除 pod,因此请求只会被发送到正在运行的 pod。这里的缺点是您将有额外的开销(更多的 pod)或更紧密的分组(更容易发生故障)。它也不会完全消除失败的请求,但它们会非常少。

  3. 调整 HC 和您的容器一起工作: 3a. 将 HC 端点与您使用的正常路径分开。3b。配置容器readinessProbe以匹配您的容器提供流量的主路径(它将不同于 LB HC 路径)3c。配置您的图像,以便在SIGTERM接收到时,首先要向下的是 HC 路径。3d。将映像配置为在收到 a 后优雅地耗尽所有连接,SIGTERM而不是立即关闭所有会话和连接。

这应该意味着正在进行的会话将正常终止,从而减少错误。这也应该意味着即使节点已准备好为正常流量提供服务,节点也会开始失败 HC 探测,这为节点提供了时间被标记为不健康,并且 LB 将在不再能够服务之前停止向其发送流量要求。

最后一个选项的问题是 2 倍。首先,配置比较复杂。另一个问题是,这意味着您的 pod 将需要更长的时间来终止,因此滚动更新将需要更长的时间,任何其他依赖于优雅终止 pod 的进程(例如耗尽节点)也将需要更长的时间。除非您需要快速转身,否则第二个问题还不错。


推荐阅读