阿里云「飞天发布时刻」2024来啦!新产品、新特性、新能力、新方案,等你来探~ 了解详情
写点什么

Airbnb 如何实现 Kubernetes 集群动态扩展

David Morrison,Evan Sheng,David Morrison

  • 2022-06-12
  • 本文字数:4250 字

    阅读完需:约 14 分钟

Airbnb如何实现Kubernetes集群动态扩展

本文最初发布于 Airbnb 技术博客。


运营 Airbnb 基础设施的一项重要工作是,确保我们的云开支随着需求自动增长和下降。我们的流量每天波动很大,为此,我们的云资源占用应该能够动态扩展。


为了实现这种扩展,Airbnb 利用了 Kubernetes 这个开源的容器编排系统。我们还利用了 OneTouch,一个建立在 Kubernetes 之上的服务配置界面,在之前的文章中有更详细的描述。


在这篇文章中,我们将讨论如何使用 Kubernetes Cluster Autoscaler 动态调整集群大小,并重点介绍我们为sig-autoscaling社区贡献的特性。这些改进增加了可定制性和灵活性,满足了 Airbnb 独特的业务需求。

Airbnb 的 Kubernetes 集群

在过去几年里,Airbnb 已经将几乎所有的在线服务从手工编排的 EC2 实例迁移到 Kubernetes。如今,我们在近百个集群中运行着数千个节点以适应我们的工作负载。然而,这种变化不是一夜之间发生的。在迁移过程中,随着更多的工作负载和流量转移到新技术栈,底层 Kubernetes 集群的配置得到了优化,也变得更加复杂。这种演变可以分为三个阶段:

阶段 1:同构集群,手动扩展

阶段 2:多集群类型,独立自动扩展

阶段 3:异构集群,自动扩展

阶段 1:同构集群,手动扩展

在使用 Kubernetes 之前,服务的每个实例都运行在自己的机器上,当流量增加时需要手动扩展。每个团队的容量管理方式不一样,负载下降时,已分配的容量也很少会取消。


我们最初的 Kubernetes 集群设置相对简单。我们有少数几个集群,每个集群都有一个底层节点类型和配置,它们只运行无状态的在线服务。随着其中一些服务开始迁移到 Kubernetes,我们开始在多租户环境中运行容器化服务(一个节点上有许多 pod)。这种聚合减少了资源浪费,并将服务的容量管理整合到了 Kuberentes 控制平面上。在这个阶段,集群扩展是手动的,但相比之前仍然有显著的改进。



图 1:EC2 节点 vs Kubernetes 节点

阶段 2:多集群类型,独立自动扩展

集群配置的第二个阶段始于我们试图在 Kubernetes 上运行更多不同类型的工作负载,每个类型都有不同的需求。为了满足这些需求,我们创建了一个集群类型抽象。“集群类型”定义了集群的底层配置,集群类型相同的集群从节点类型到各种集群组件设置都相同。


集群类型越多集群也越多,我们的初始策略“手动管理每个集群的容量”很快就支撑不下去了。为了解决这个问题,我们在每个集群中添加了 Kubernetes Cluster Autoscaler。该组件根据 pod 请求自动调整集群大小——如果集群的容量耗尽了,就可以通过添加一个新节点来满足待处理的 pod 请求,此时,Cluster Autoscaler 就会启动一个节点。类似地,如果集群中有节点在很长一段时间内未得到充分利用,那么 Cluster Autoscaler 将从集群中删除这些节点。在我们的设置中,添加这个组件非常有效,为我们省却了大约 5%的云开销,以及手动扩展集群的操作开销。



图 2:Kubernetes 集群类型

阶段 3:异构集群,自动扩展

当 Airbnb 几乎所有的在线计算都转向 Kubernetes 时,集群类型的数量已经增加到 30 多个,而集群的数量则达到 100 多个。这种扩张使得 Kubernetes 集群管理变得非常繁琐。例如,集群的升级必须针对众多集群类型中的每一种单独进行测试。


在第三阶段,我们的目标是通过创建“异构”集群来整合集群类型。这些集群可以在一个 Kubernetes 控制平面上容纳许多不同的工作负载。首先,这大大降低了集群管理的开销,因为数量更少更通用的集群可以减少需要测试的配置数量。其次,现在 Airbnb 大部分都在 Kubernetes 集群上运行,集群效率为降低成本提供了一个重要杠杆。整合集群类型使我们能够在每个集群中运行不同的工作负载。工作负载类型聚合——有大有小——可以实现更好的装箱(bin packing)和效率,从而提高利用率。得益于工作负载的这种灵活性,我们有更多的空间在 Cluster Autoscaler 默认的扩展逻辑之外实施复杂的扩展策略。具体来说,我们的目标是实现与 Airbnb 具体业务逻辑相关的扩展逻辑。



图 3:异构 Kubernetes 集群


随着我们对集群进行扩展和整合(实现异构集群,每个集群有多个实例类型),我们开始在扩展过程中实现特定的业务逻辑,并发现有必要对自动扩展行为做一些修改。下一节将描述我们对 Cluster Autoscaler 所做的一些改进,目的是使其更加灵活。

改进 Cluster Autoscaler

自定义 gRPC Expander

我们对 Cluster Autoscaler 所做的最重要的改进是提供了一种新的方法来确定要扩展的节点组。在内部,Cluster Autoscaler 维护着一个节点组列表(它们映射到不同的候选扩展),它会针对当前的 Pending(不可调度)pod 集进行调度模拟,过滤出不满足 pod 调度需求的节点组。如果有任何 Pending(不可调度)pod,Cluster Autoscaler 会尝试扩展集群以容纳这些 pod。任何满足所有 pod 需求的节点组都会被传递给一个名为Expander的组件。



图 4:Cluster Autoscaler 和 Expander


Expander 负责根据操作要求进一步过滤节点组。Cluster Autoscaler 内置了许多不同的扩展器选项,每个选项都有不同的逻辑。例如,默认是随机扩展器,它从可用的选项中机会均等地随机选择。另一个选项,也是 Airbnb 历来使用的选项,是优先级扩展器,它根据用户指定的分层优先级列表选择要扩展的节点组。


随着我们迈向异构集群逻辑,我们发现默认的扩展器不够成熟,无法满足我们以成本和实例类型选择为中心的更复杂的业务需求。


假如有这样一个情况,我们想实现一个加权优先级扩展器。目前,优先级扩展器只允许用户指定节点组的不同层级,这意味着它将始终以确定的方式按顺序扩展层级。如果一个层中有多个节点组,它将随机选择。在默认设置下,无法实现将两个节点组置于在同一层级的加权优先策略,在 80%的时间内扩展一个,在 20%的时间内扩展另一个。


除了目前支持的扩展器存在局限性之外,还有一些操作上的考虑:

  1. Cluster Autoscaler 的发布管道非常严格,变更需要时间审核,然后再合并到上游。然而,我们的业务逻辑和所需的扩展策略在不断变化。开发一个今天可以满足需求的扩展器,可能无法满足我们未来的需求。

  2. 我们的业务逻辑是特定于 Airbnb 的,其他用户未必如此。任何我们针对自己的逻辑所做的修改,都不会对上游有什么贡献。


为此,我们希望 Cluster Autoscaler 中有一个新扩展器类型可以满足下列要求:

  1. 我们希望能有一个既可扩展又能为他人所用的东西。其他人在大规模使用默认的 Expander 时可能会遇到类似的限制,我们希望提供一个通用的解决方案,并向上游贡献功能。

  2. 我们的解决方案应该可以与 Cluster Autoscaler 一起部署,并允许我们更迅速地响应不断变化的业务需求。

  3. 我们的解决方案应该适合 Kubernetes Cluster Autoscaler 生态系统,这样我们就不必无限期地维护 Cluster Autoscaler 的一个分叉。


基于这些要求,我们提出了一个设计,将扩展职责从 Cluster Autoscaler 的核心逻辑中分离出来。我们设计了一个可插拔的“自定义扩展器”,它被实现为一个 gRPC 客户端(类似于自定义云提供商)。这个自定义扩展器由两个部分组成。


第一个组件是一个内置于 Cluster Autoscaler 的 gRPC 客户端。这个 Expander 使用了与 Cluster Autoscaler 中其他 Expander 相同的接口,负责将 Cluster Autoscaler 中有效的节点组信息转换为定义好的protobuf模式(如下图所示),并接收 gRPC 服务器的输出,变回最终的选项列表,供 Cluster Autoscaler 扩展。

Plain Textservice Expander { rpc BestOptions (BestOptionsRequest) returns (BestOptionsResponse)}message BestOptionsRequest { repeated Option options; map<string, k8s.io.api.core.v1.Node> nodeInfoMap;}message BestOptionsResponse { repeated Option options;}message Option { // ID of node to uniquely identify the nodeGroup string nodeGroupId; int32 nodeCount; string debug; repeated k8s.io.api.core.v1.Pod pod;}

第二个组件是 gRPC 服务器,这需要由用户自己编写。这个服务器的用意是作为一个单独的应用程序或服务来运行,在选择要扩展的节点组时,可以使用从客户端传过来的特定信息运行任意复杂的扩展逻辑。目前,通过 gRPC 传递的 protobuf 信息基于传递给 Cluster Autoscaler 中的 Expander 的信息稍微做了些转换。


从我们前面提到的例子来看,加权随机优先级扩展器的实现可以很简单,让服务器从优先级层级列表和配置图中读取加权百分比配置并作出相应的选择即可。



图 5:Cluster Autoscaler 和自定义 gRPC Expander


我们的实现包括一个故障安全选项。建议使用该选项,将多个扩展器作为参数传递给 Cluster Autoscaler。有了这个选项,如果服务器发生故障,Cluster Autoscaler 仍然能够使用后备扩展器进行扩展。


由于是作为一个独立的应用程序运行,扩展逻辑可以在 Cluster Autoscaler 之外开发。而且,由于 gRPC 服务器可以由用户根据自己的需要进行定制开发,所以这个解决方案也是可扩展的,对整个社区都很有用。


在内部,自 2022 年初开始,Airbnb 一直在使用这个新的解决方案来扩展我们所有的集群,没有任何问题。它使我们能够动态选择何时扩展某些节点组,以满足 Airbnb 的业务需求,实现了我们开发可扩展的自定义扩展器的最初目标。


在今年早些时候,我们的自定义扩展器被上游的Cluster Autoscaler所接受,并将在下一个版本(v1.24.0)发布时推出。

Autoscaler 的其他改进

在迁移到异构 Kubernetes 集群的过程中,我们发现了其他一些 Bug 以及 Cluster Autoscaler 的可改进之处。下面简要介绍一下这些情况:

  • 提前中止没有容量的AWS ASG:缩短 Cluster Autoscaler 调用 AWS EC2 端点来检查 ASG 是否有容量,进而判断它们试图扩展的节点是否准备就绪的等待时间。实现这一修改后,用户可以更快地实现准确扩展。以前,使用优先级的用户必须在每次尝试启动 ASG 之后等待 15 分钟,再尝试低优先级的 ASG。

  • 缓存启动模板,减少AWS API调用:为 AWS ASG 启动模板引入缓存。这一修改让我们可以使用大量的 ASG,这对我们的广义集群策略至关重要。以前,对于空的 ASG(集群中当前没节点),Cluster Autoscaler 会反复调用 AWS 端点来获取启动模板,导致 AWS API 限流。

小结

在过去的四年里,Airbnb 在 Kubernetes 集群配置上取得了长足的进步。将 Airbnb 最大的计算部分置于单个平台上,为提高效率提供了一个强有力的杠杆。现在,我们正专注于一般化我们的集群设置(考虑下“Cattle而非Pets”)。通过在 Cluster Autoscaler 中开发和使用更复杂的扩展器(以及修复 Autoscaler 的其他一些小问题),我们已经实现目标,以成本和混合实例类型为中心开发出特定于业务的复杂扩展策略,同时也为社区贡献了一些有用的特性。


要了解更多关于我们异构集群迁移的细节,请观看我们的Kube-Con演讲。今年,我们也会参加 KubeCon EU,欢迎来和我们交流!


查看英文原文:Dynamic Kubernetes Cluster Scaling at Airbnb


2022-06-12 15:075389

评论

发布
暂无评论
发现更多内容

从0到1:企业官网小程序开发笔记(一)

CC同学

Penpad的Season 2 规则解读,其生态资产 $PDD LaunchPad 在即

股市老人

Penpad 生态资产 $PDD LaunchPad 在即,Season 2 规则解读

石头财经

颠覆传统开发流程!「原型、设计、开发」仅需一个组件设计器就够了!

优秀

低代码 组件设计器

【教程】深入探究 JS代码混淆与加密技术

.NET Core 服务实现监控可观测性最佳实践

观测云

.net core

Penpad 生态资产 $PDD 即将LaunchPad ,一文读懂Season 2 规则

大瞿科技

【redis问题】Caused by: io.netty.channel

百度搜索:蓝易云

redis 云计算 Linux 运维 云服务器

新零售SaaS架构:线上商城系统架构设计

快乐非自愿限量之名

架构 零售 SaaS

众安保险AI代码助手DevPilot获奖,全面开源构筑技术新生态

ZA技术社区

海信电视U8N Pro,用AI算尽 “每一粒沙”

脑极体

AI

Microsoft Office LTSC 2021 for Mac v16.82 beta版

iMac小白

Penpad 生态资产 $PDD 即将LaunchPad ,一文读懂Season 2 规则

BlockChain先知

jackson对象带时间的转换报错,附带fastjson封装工具就填

进哥

java‘

一文详解大数据时代与低代码开发应用

快乐非自愿限量之名

大数据 低代码

全球首个Open机器人诞生!当GPT模型有了“肉体”,不仅能听能写还可以干家务!

Finovy Cloud

AI Open AI

使用gitlab+gitlab runner+k8s完成devops

了了

千万别让老板知道,这套80%海报,是我用生成式 AI 设计的!

亚马逊云科技 (Amazon Web Services)

PowerPhotos for Mac v2.5.7b3 直装版 mac专用图片管理工具

iMac小白

AWE2024,中国家电智能化的《山海经》

脑极体

AI

深入理解 C++ 语法:从基础知识到高级应用

小万哥

程序人生 编程语言 软件工程 C/C++ 后端开发

Penpad的Season 2 规则解读,其生态资产 $PDD LaunchPad 在即

威廉META

游戏直播APP平台开发多少钱成本:定制与成品源码差距这么大

软件开发-梦幻运营部

Penpad 生态资产 $PDD 即将LaunchPad ,一文读懂Season 2 规则

长安区块链

头部银行 AI 落地实践|数据应用赋能经营管理闭环

Kyligence

Penpad 生态资产 $PDD 即将LaunchPad ,一文读懂Season 2 规则

加密眼界

Penpad 生态资产 $PDD 即将LaunchPad ,一文读懂Season 2 规则

股市老人

热点!浅谈低代码到底是什么?

互联网工科生

SideNotes v1.4.14 for Mac激活版 让你随时在 Mac 屏幕上管理笔记

iMac小白

Amazon Bedrock 实践 | 动手玩转 Claude 3

亚马逊云科技 (Amazon Web Services)

一个案例,看懂AI Agent厂商的商业落地路径

王吉伟频道

LLM 大语言模型 AI Agent AI智能体 RPA Agent

Airbnb如何实现Kubernetes集群动态扩展_架构_InfoQ精选文章