热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Kubernetes和Istio构建大规模集群带来的挑战和解决方案

原文地址:https:blog.houzz.comchallenges-and-solutions-in-building-a-large-scale-cluster-with-k


原文地址:https://blog.houzz.com/challenges-and-solutions-in-building-a-large-scale-cluster-with-kubernetes-and-istio/


译者:陈龙全


为更好的管理不断增长的服务和流量,Houzz 基础架构团队最近将 Web Server 服务从 Amazon Elastic Compute Cloud(Amazon EC2)迁移到 Kubernetes 集群。 这次迁移使资源使用降低了 33%,首页延迟有了 30% 的改善。


Kubernetes 集群的整体架构包含多个应用程序,包括用 NodeJS 编写的前端(FE)应用程序和用 HHVM 编写的后端(BE)服务。FE 应用程序通过 HTTP 上的 Apache Thrift 协议与 BE 服务进行通信。每个应用程序都启用了水平 Pod 自动缩放(HPA)。集群内以及与外部服务的通信由 Istio 管理,都会经过 Envoy Sidecar。


迁移过程中有诸多挑战,本文主要是想和大家分享一下我们迁移过程中的最佳实践。


Pod 延迟启动


在开始 Kubernetes 迁移时,我们注意到 Pod 延迟启动有时会在新配置的节点上发生。Envoy 容器准备就绪大约花了六分钟,阻止了其他容器的启动。从 Envoy 日志中,我们观察到 pilot-agent 不断报告 Envoy 尚未准备就绪,并提出了检查 Istiod 是否仍在运行的建议。


我们实现了一个 DaemonSet,其唯一的工作就是解析 Istiod 服务的 FQDN。从其指标来看,我们观察到在新节点引导后 DNS 名称解析几分钟后会超时,推测 Envoy 遇到了相同的超时问题。


我们确定了导致该问题的根因是 dnsRefreshRate,其在 Istio 1.5.2 中的默认值为 5 分钟,并且与观察到的延迟大致匹配。由于在启动某些 Pod 之后新节点上的 DNS 客户端已准备就绪,因此较长的重试间隔导致 Envoy 无法及时检测到 DNS 客户端的就绪状态。通过强制 Envoy 进行更频繁的重试,将附加的 Pod 启动延迟从 360 秒减少到 60 秒。


请注意,在 Istio 1.6 中,默认的 dnsRefreshRate 已更改为 5 秒。


HHVM Pod 预热和级联伸缩


我们的 BE 服务内置于 HHVM 中,该服务在其代码缓存预热之前具有很高的 CPU 使用率和高延迟。预热阶段通常需要几分钟,因此在默认的 15 秒 HPA 同步周期或 HPA 评估 CPU 使用率指标并调整所需 Pod 数量的时间间隔内,它不能很好地工作。当由于负载增加而创建新的 Pod 时,HPA 从新 Pod 中检测到更高的 CPU 使用率,并扩展了更多 Pod。这种积极的反馈循环一直持续到新的 Pod 被完全预热或达到 Pod 的最大数量为止。新的 Pod 完全预热后,HPA 检测到 CPU 使用率显著下降,并缩减了大量 Pod。级联伸缩导致了不稳定和延迟峰值。


我们进行了两项更改以解决级联伸缩问题。我们根据官方建议改进了 HHVM 预热过程。预热期间的 CPU 使用率从正常使用的 11 倍减少到 1.5 倍。Pod 开始提供流量后的 CPU 使用率从正常使用的 4 倍降低到 1.5 倍。


此外,我们将 HPA 同步时间从 15 秒增加到 10 分钟。尽管 HPA 对负载增加的响应速度较慢,但它避免了级联扩展,因为大多数 Pod 可以在 10 分钟内完成预热并开始正常使用 CPU。我们发现这是一个值得权衡的选择。





更改之前的 HPA 活动





更改之后的活动


负载均衡


负载不均衡是我们迁移到 Kubernetes 期间遇到的最值得注意的挑战,尽管它仅在最大的虚拟服务中发生。症状是某些 Pod 在重负载下无法通过就绪检查,然后更多的请求将路由到这些 Pod,从而导致 Pod 在就绪状态和未就绪状态之间摆动。在这种情况下添加更多的节点或 Pod 将导致更多的飘动 Pod。发生这种情况时,延迟和错误计数会大大增加。缓解此问题的唯一方法是强行缩小部署规模,以杀死不断波动的 Pod,而无需添加新 Pod。但是,这不是可持续的解决方案,因为更多的 Pod 很快就开始波动。由于此问题,我们多次回退了迁移。





负载均衡


为了方便排查,我们添加了额外的日志记录,发现负载不均衡时触发,一个可用区(AZ)的请求明显多于其他两个。我们怀疑这种不均衡是由于我们当时使用的最少请求负载均衡策略中的正反馈回路造成的。我们尝试了其他几种策略(Round Robin,Locality Aware 和 Random),都没有解决问题。


在排除了负载均衡策略之后,我们在其他两个方面寻找了积极的反馈循环:重试失败的请求和异常检测。


尽管 Istio 的官方文档中指出默认情况下不会对失败的请求进行重试,但实际的默认重试次数设置为 2。重试会导致级联失败,因为某些请求失败后会发送更多请求。此外,我们观察到异常检测中的某些行为(也称为被动健康检查)无法解释,因此我们决定禁用这两个功能。之后,不平衡问题消失了,我们能够将 95%的请求迁移到 Kubernetes。我们在旧平台上保留 5%的资源用于性能比较和调整。最初,我们不确定重试或异常检测这两个功能中的哪一个是造成负载不均衡的原因,尽管我们现在认为它与重试有关。


在将 Istio 升级到 1.6 版,进行了一些性能改进并将 100%的请求迁移到 Kubernetes 之后,我们尝试重新启用离散值检测 - 我们愿意承担这种风险,因为更改可以在几秒钟内恢复。在撰写本文时,我们还没有遇到负载不均衡的问题。就是说,我们用以下事实证明了我们的理论,即当前 Istio 版本的集群配置与发生不均衡时的配置不同。


发布后性能下降


我们观察到,每次发布后,Kubernetes 上的延迟都会随时间而增加,因此我们创建了一个仪表板来显示 Envoy 在 Ingress 网关,FE 应用程序和 BE 服务 Pod 中报告的入站 / 出站延迟。仪表盘表明,总体增加是由 Envoy 在 BE Pod 中报告的入站延迟的增加所驱动的,这包括服务延迟和 Envoy 本身的延迟。由于服务延迟没有显着增加,因此代理延迟被认为是延迟增加的驱动力。我们发现,每个版本发布后,Envoy 在 BE Pod 中的内存使用量也随着时间增加,这使我们怀疑延迟增加是由于 BE Pod 中的 Envoy 的内存泄漏引起的。我们 exec 到一个 BE Pod,并列出了 Envoy 和主容器中的连接,发现 Envoy 中有大约 2800 个连接,主容器中有 40 个连接。在 2800 个连接中,绝大多数是与 FE Pod(BE Pod 的客户)连接的。


为了解决 Envoy 内存泄漏问题,我们做了一些更改,包括:


将 FE Pod 到 BE Pod 之间的连接的 idleTimeout 从默认的 1 小时减少到 30 秒。此更改减少了错误数量并提高了请求成功率,但同时也增加了 FE 和 BE 容器之间每秒的连接请求数量。  将 Envoy 的并发或线程数从 FE Pod 中的 16 减少到 2。该更改取消了自第一次更改以来每秒大多数连接请求数量的增加。  在 BE Pod 中将 Envoy 内存限制设置为 300MB。观察到预期的行为,并且 Envoy 的内存使用量超出限制时重新启动。容器继续运行,但是内存使用率较低。重新启动 Envoy 时,有些 Pod 有短暂的准备就绪时间,这是对前两个更改的补充。虽然前两个更改减少了 Envoy 的内存使用量,但第三个更改将在 Envoy 的内存使用量超出限制时重新启动。与重新启动主容器相比,重新启动 Envoy 所导致的停机时间明显更少,因为后者会在 HHVM 中产生几分钟的预热时间。





变更之前的延迟





变更之前内存变化





变更之后的延迟


解决了发布后的性能下降问题之后,我们将 100%的请求迁移到 Kubernetes 并关闭了旧主机环境。


集群的瓶颈


随着我们将更多请求迁移到 Kubernetes 中最大的虚拟服务,我们遇到了跨集群范围的资源的问题,这些资源在虚拟服务之间共享,包括 APIServer,DNS 服务器和 Istio 控制平面。在事件期间,观察到持续了一两分钟所有虚拟服务的错误峰值,我们发现这是由于未能解析 FE Pod 中 BE 虚拟服务的 DNS 名称所致。错误峰值还与 DNS 解析错误和 DNS 请求下降有关。Ingress 服务调用不应依赖于 DNS。相反,应该将 FE Pod 中的 Envoy 定向为将出站 HTTP 请求定向到 BE 服务中的端点的 IP 地址。但是,我们发现 NodeJS Thrift 客户端库对无用的服务 IP 进行了 DNS 查找。为了消除 DNS 依赖性,我们部署了 Sidecar,将 Virtual Service 中 BE 服务的主机绑定到本地套接字地址。





Sidecar 清单示例


尽管 Istio 从应用程序角度最大程度地提高了透明度,但除了在应用程序代码中用本地 IP 地址和端口号替换 DNS 名称之外,我们还必须显式添加 Host 标头。值得一提的是,sidecar 的一个附带好处是可以优化内存使用。默认情况下,无论是否需要,Istio 都会将跨 Kubernetes 集群的每个服务的上游集群添加到 Envoy。维护那些不必要的配置的一项重大成本是 Envoy 容器的内存使用。使用 sidecar 解决方案,我们将 DNS 服务器故障与关键路径中的服务调用隔离开来,将 DNS 服务器上的 QPS 从 30,000 减少到 6,000,并将 Envoy 的平均内存使用量从 100MB 减少到 70MB。





coreDNS QPS 的变化





变更前内存使用情况





变更后内存使用情况


我们遇到的另一个错误高峰与不一致的集群成员身份(节点终止时出现这种情况)有关。尽管 Kubernetes 应该能够优雅地处理节点终止,但是节点终止时有一种特殊情况会导致错误尖峰:在终止的节点上运行 Istiod pod。节点终止后,一些 FE Pod 花费了大约 17 分钟的时间从新的 Istiod Pod 接收更新。在他们收到更新之前,他们对 BE 集群成员身份看法不一致。鉴于此,这些有问题的 FE Pod 中的集群成员很可能已过时,导致它们向终止或未就绪的 BE Pod 发送请求。





集群成员身份不一致且是旧数据


我们发现 tcpKeepalive 选项在检测终止的 Istiod Pod 中起作用。在我们的 Istio 设置中,将 keepaliveTime,keepaliveProbes 和 keepaliveInterval 分别设置为默认值 300 秒,9 秒和 75 秒。理论上讲,Envoy 可


能需要至少 300 秒加 9,再乘以 75 秒(16.25 分钟),才能检测到终止的 Istiod Pod。我们通过将 tcpKeepalive 选项自定义为更低的值来解决了这个问题。


建立大规模的 Kubernetes 集群具有挑战性,并且对大家来说非常有意义。希望你从我们的经验中找到有用的信息。


加入云原生社区 Istio SIG


扫描下面的二维码加入云原生社区 Istio SIG, 与 Istio 专家及爱好者们共同交流。




首届 IstioCon 演讲嘉宾招募中 ,议题提交截止时间为北京时间 2021 年 1 月 19 日 15:59。


点击下方“阅读原文”查看更多


↓↓↓




推荐阅读
  • 微服务应用性能如何?APM监控工具来告诉你
    当微服务系统越来越庞大,各个服务间的调用关系也变得越来越复杂,需要一个工具来帮忙理清请求调用的服务链路。之前使用的是Sleuth+Zipkin的解决方案,最近发现应 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • Linux如何安装Mongodb的详细步骤和注意事项
    本文介绍了Linux如何安装Mongodb的详细步骤和注意事项,同时介绍了Mongodb的特点和优势。Mongodb是一个开源的数据库,适用于各种规模的企业和各类应用程序。它具有灵活的数据模式和高性能的数据读写操作,能够提高企业的敏捷性和可扩展性。文章还提供了Mongodb的下载安装包地址。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • Vagrant虚拟化工具的安装和使用教程
    本文介绍了Vagrant虚拟化工具的安装和使用教程。首先介绍了安装virtualBox和Vagrant的步骤。然后详细说明了Vagrant的安装和使用方法,包括如何检查安装是否成功。最后介绍了下载虚拟机镜像的步骤,以及Vagrant镜像网站的相关信息。 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
author-avatar
手机用户2502872401
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有