使用 externalTrafficPolicy: Local 在 GKE 上是否可以实现无中断滚动更新?

2023-12-25

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

我正在运行nginx 入口控制器 https://github.com/kubernetes/ingress-nginx with type: LoadBalancer.

我已经设置了externalTrafficPolicy: Local to 保留源ip https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-type-loadbalancer.

除了滚动更新期间之外,一切都运行良好。我有maxSurge: 1 and maxUnavailable: 0.

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

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


我的理解是,在一个normalk8s服务,哪里externalTrafficPolicy这是不正常的,Google 负载均衡器只是将请求发送到所有节点,然后让 iptables 进行排序。当 pod 处于Terminatingiptables 更新很快,流量不再发送到该 Pod。在这种情况下externalTrafficPolicy is Local但是,如果接收请求的节点没有Runningpod,然后请求超时,这就是这里发生的情况。

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

  1. 停止向节点发送请求Terminating pod
  2. 即使 pod 已关闭,仍继续服务请求Terminating

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

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

我还调整了Google负载均衡器健康检查,这与readinessProbe and livenessProbe,到可能的“最快”设置,例如1 秒间隔,1 个故障阈值,我已经验证了负载均衡器后端(又名 k8s 节点)确实很快就失败了运行状况检查,但仍然继续向终止 pod 发送请求。


有一个类似的讨论here https://stackoverflow.com/questions/58751354/testing-graceful-shutdown-on-an-http-server-during-a-kubernetes-rollout/58752566#58752566。虽然不完全相同,但它是一个相似的用例。

一切听起来都按预期进行。

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

  • 一旦超过健康检查阈值,健康检查就会将节点标记为不健康,即每 x 秒发送一次 HC,超时延迟为 x,失败请求数为 x。这会导致 pod 进入终止状态和被标记为不健康状态之间存在延迟。

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

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

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

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

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

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

最后一个选项的问题有两个。首先,配置比较复杂。另一个问题是,这意味着您的 Pod 将需要更长的时间才能终止,因此滚动更新将需要更长的时间,任何其他依赖于优雅终止 Pod 的进程(例如耗尽节点)也会花费更长的时间。第二个问题还不错,除非您需要快速扭转局面。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 externalTrafficPolicy: Local 在 GKE 上是否可以实现无中断滚动更新? 的相关文章

  • Eclipse IDE - 错误:构建路径指定执行环境 Java SE 1.7

    在 Eclipse 中 我收到一个错误 构建路径指定执行环境Java SE 1 7 工作区中没有安装与此环境严格兼容的 JRE 尝试这个 In Eclipse your project gt properties gt java build
  • 我可以在某些网格中打印带有颜色的 pandas 数据框吗?

    我有一个 pandas DataFrame 我想突出显示一些数据 例如 In 1 import pandas as pd In 2 import numpy as np In 3 df pd DataFrame np reshape ran
  • List 与 IEnumerable 的协变和逆变

    所以 假设我有 Public Interface ISomeInterface End Interface Public Class SomeClass Implements ISomeInterface End Class 如果我有MyL
  • 如何在express中动态渲染/加载页面?

    我需要使用express gt 3 0 框架动态加载 渲染nodejs v1 8 15 中页面的一部分 一般来说 我想创建一个单页应用程序 我在页面顶部有一个带有链接的菜单 单击链接将更改下面的内容 就像 AJAX 页面加载一样 例如 gt
  • 使用 mongoimport 从 Windows 文件夹批量导入 MongoDB

    我的存档中有很多 json 文件 我需要将它们导入到 mongo 每一个操作中 我认为它可能是循环的 你对此有什么想法吗 如果您使用的是 Linux Unix shell 您可以尝试 for filename in do mongoimpo
  • 如何使用 Typescript 将 jest.spyOn 与 React 函数组件一起使用

    我正在使用 Typescript 和 hooks 开发一个 React 应用程序 并且尝试使用 Enzyme 和 Jest 来测试功能组件 我无法使用 jest spyOn 来测试我的组件中的方法 jest spyOn 方法无法正确解析并在
  • 如何从 fetch API 返回 json 响应

    我有一个像这样的函数 check auth fetch Urls check auth credentials include method GET then response gt if response ok return respon
  • 复杂对象上的 GroupBy(例如 List

    Using GroupBy and Count gt 1我试图在列表中查找我的类的重复实例 该类看起来像这样 public class SampleObject public string Id public IEnumerable
  • 时间复杂度和整数输入

    我遇到一个问题 要求描述以下代码的 Big O 中的计算复杂性 i 1 while i lt N i i 2 I found this https stackoverflow com questions 40066016 is time c
  • 同时使用多个控制台

    是否有捷径可寻 我现在仅使用控制台测试我的网络应用程序 最好的办法是从一个项目中拥有多个控制台 然后按一下 立即调试 菜单项 我可以像过去一样使用多个项目 但这似乎很笨拙 理想情况下 我可以启动多个控制台实例 从同一线程运行很好 并且让它们
  • 无法使用 Struts 2 重定向 JSP 文件并显示值

    我创建了一个简单的程序 使用文本字段获取用户的名字和姓氏 但问题是 当我单击提交按钮时 我无法将其重定向到另一个显示用户名字和姓氏的 jsp 文件 这是我的HelloAction class package com novamsc trai
  • 网站可以检测您何时将 Selenium 与 chromedriver 结合使用吗?

    我一直在使用 Chromedriver 测试 Selenium 我注意到有些页面可以检测到您正在使用 Selenium 即使根本没有自动化 即使我只是通过 Selenium 使用 Chrome 手动浏览 Xephyr https en wi
  • 为什么 JDOM 的 getChild() 方法返回 null?

    我正在做一个关于 html 文档操作的项目 我想要现有 html 文档中的正文内容将其修改为新的 html 现在我正在使用 JDOM 我想在我的编码中使用 body 元素 为此 我在编码中使用了 getChild body 但它向我的程序返
  • 读取完 JSON 内容和意外标记后遇到的其他文本(在我的 json 中)

    我使用 JSON Net 创建的 json feed 遇到一些问题 当我尝试解析它时 它给了我 读取完 JSON 内容后遇到的附加文本 路径 第 17 行 位置 4 我尝试用以下方法验证它http json parser online fr
  • 用于清除工作空间和转储存储的 R 全局函数

    我希望创建一个全局函数来清除我的工作区并转储我的内存 我将我的函数称为 cleaner 并希望它执行以下代码 remove list ls gc 我尝试在全局环境中创建该函数 但是当我运行它时 控制台仅打印该函数的文本 在我要获取的函数文件
  • 有没有办法阻止 SQL Express 2008 空闲?

    我使用 SQL Express 2008 作为 Web 应用程序的后端 问题是 Web 应用程序是在工作时间使用的 因此有时在午餐或休息时间 如果 20 分钟内没有用户登录 SQL Express 将进入空闲状态模式并释放其缓存 我知道这一
  • 使用 TABLE_DATE_RANGE 时如何获取表名称

    我想使用 TABLE DATE RANGE 获取每日统计信息 如下所示 Select count tableName FROM TABLE DATE RANGE appengine logs appengine googleapis com
  • Razor 视图类型不继承自“System.Web.WebPages.WebPage”

    我在配置 ASP NET MVC 应用程序时遇到问题 HttpException 0x80004005 Type ASP Page Currency Index cshtml does not inherit from System Web
  • Ansible - 任务系列 1 逆序

    我想创建两本剧本 一本用于停止环境 另一本用于启动它 环境的一部分是 RabbitMQ 集群 对于其停止 启动顺序非常重要 特别是最后一个停止的节点需要是第一个启动的节点 我想知道是否有一种方法可以指定针对组运行任务的相反顺序 这样我就可以
  • localStorage 获取 NULL?

    我不知道为什么 因为我之前已经这样做过并且工作正常 我认为这可能是因为浏览器问题 错误 localStorage setItem foo bar alert localStorage getItem foo 我使用的是 Firefox 3

随机推荐