摘要:本文结合Karmada社区对大规模场景的思考,揭示Karmada稳定支持100个大规模集群、管理超过50万个节点和200万个Pod背后的原理
本文分享自华为云社区《Karmada百倍集群规模多云基础设施体系揭秘》,作者: 云容器大未来 。
随着云原生技术在越来越多的企业和组织中的大规模落地,如何高效、可靠地管理大规模资源池以应对不断增长的业务挑战成为了当下云原生技术的关键挑战。
在过去的很长一段时间内,不同厂商尝试通过扩展单集群的规模来扩展资源池。然而,Kubernetes社区很早就发布了大规模集群的最佳实践,其中包括几项关键数据:节点数不超过5k,Pod数不超过150k,单个节点的Pod数量不超过110 k等。这侧面说明了支持超大规模的集群不是Kubernetes社区主要努力的方向。同时,以单集群的方式扩展资源池通常需要定制Kubernetes的原生组件,这在增加了架构复杂度的同时也带来了不少弊端:
(1)集群运维复杂度急剧增加。
(2)与社区演进方向相左,后续的维护成本上升,升级路径不清晰。
(3)单集群本质上属于单个故障域,集群故障时将导致无法控制爆炸半径。
而多集群技术能在不侵入修改Kubernetes单集群的基础上横向扩展资源池的规模,在扩展资源池的同时降低了企业的运维管理等成本。此外,多集群系统天然支持多故障域,符合多数业务场景,如多地数据中心、CDN就近提供服务等。
Karmada作为CNCF首个多云容器编排项目,提供了包括Kubernetes原生API支持、多层级高可用部署、多集群故障迁移、多集群应用自动伸缩、多集群服务发现等关键特性,致力于让用户轻松管理无限可伸缩的资源池,为企业提供从单集群到多云架构的平滑演进方案。
随着以Karmada为代表的多集群架构在企业的逐步落地,大规模场景下多集群系统的性能问题往往是用户的核心关注点之一。本文将围绕以下几个问题,结合Karmada社区对大规模场景的思考,揭示Karmada稳定支持100个大规模集群、管理超过50万个节点和200万个Pod背后的原理。
(1) 如何衡量一个多集群系统资源池的维度与阈值?
(2) 对多集群系统进行大规模环境的压测时,我们需要观测哪些指标?
(3) Karmada是如何支撑100个大规模K8s集群并纳管海量应用的?
(4) 在Karmada的生产落地过程中,有哪些最佳实践和参数优化手段可以参考?
当前,业界对于多云资源池的Scalability尚未达成统一标准,为此,Karmada社区结合企业用户的实践,率先对这一问题进行了深入探索。一个多集群系统资源池规模不单指集群数量,实际上它包含很多维度的测量标准,在不考虑其他维度的情况下只考虑集群数量是毫无意义的。在若干因素中,社区按照优先级将其描述为以下三个维度:
(1) 集群数量。集群数量是衡量一个多集群系统资源池规模和承载能力最直接且最重要的维度。
(2) 资源(API对象)数量。对于多集群系统的控制面来说,存储并不是无限的,在控制面创建的资源对象的数量和总体大小受限于系统控制面的存储,也是制约多集群系统资源池规模的重要维度。这里的资源对象不仅指下发到成员集群的资源模板,而且还包括集群的调度策略、多集群服务等资源。
(3) 集群规模。集群规模是衡量一个多集群系统资源池规模不可忽视的维度。一方面,集群数量相等的情况下,单个集群的规模越大,整个多集群系统的资源池越大。另一方面,多集群系统的上层能力依赖系统对集群的资源画像,例如在多集群应用的调度过程中,集群资源是不可或缺的一个因素。综上所述,单集群的规模与整个多集群系统息息相关,但单集群的规模同样不是制约多集群系统的限制因素。用户可以通过优化原生的Kubernetes组件的方式来提升单集群的集群规模,达到扩大整个多集群系统的资源池的目的,但这不是衡量多集群系统性能的关注点。在集群的标准配置中,Node与Pod毫无疑问是其中最重要的两个资源,Node是计算、存储等资源的最小载体,而Pod数量则代表着一个集群的应用承载能力。
在多集群系统的大规模落地进程中,如何衡量多集群联邦的服务质量是一个不可避免的问题。在参考了Kubernetes社区的SLI(Service Level Indicator)/SLO(Service Level Objectives)和多集群系统的落地应用后,Karmada社区定义了以下SLI/SLO来衡量大规模场景下多集群联邦的服务质量。
注:API调用时延仍然是衡量基于Kubernetes的多集群系统服务质量的关键指标。Karmada兼容Kubernetes原生API,用户除了使用原生API创建K8s的资源模板外,也可以使用Karmada自有API来创建多集群策略和访问跨集群的资源。
注:集群注册时延是从集群注册到控制面到集群在联邦侧可用的时延,它反映了控制面接入集群以及管理集群的生命周期的性能。但它在某种程度上取决于控制面如何收集成员集群的状态。因此,我们不会对这个指标进行强制的限制。
注:资源使用量是多集群系统中非常重要的指标,我们希望在纳管海量的集群和资源的同时消耗尽量少的系统资源。但由于不同的多集群系统提供的上层服务不同,因此对于不同的系统,其对资源的要求也会不同。因此,我们不会对这个指标进行强制的限制。
Karmada社区在结合对上述两个问题的思考以及用户在落地过程中的反馈后,测试了Karmada同时管理100个5K节点和2w Pod的Kubernetes集群的场景。本文不详细描述具体的测试环境信息与测试过程,而是侧重于对测试结果进行分析
在整个测试过程中,API调用时延均符合上述定义的SLI/SLO。
图一:只读API(cluster-scope)调用时延
图二:只读API(namespace-scope)调用时延
图三:只读API(resource-scope)调用时延
图四:Mutating API调用时延
Karmada在百倍集群规模下,仍能做到快速的API响应,这取决于Karmada独特的多云控制面架构。事实上,Karmada在架构设计之初就采用了关注点分离的设计理念,使用Kubernetes原生API来表达集群联邦资源模板,使用可复用的策略API来表达多集群的管理策略,同时控制面的资源模板作为应用的模板,不会在控制面生成具体的Pod。不同集群的应用在控制面的映射(Work对象)通过命名空间来进行安全隔离。完整的API工作流如下图所示。如此设计,不仅可以让Karmada能够轻松集成Kubernetes的生态, 同时也大大减少了控制面的资源数量和承载压力。基于此,控制面的资源数量不取决于集群的数量,而是取决于多集群应用的数量。
此外,Karmada的架构极具简洁性和扩展性。karmada-apiserver作为控制面的入口与kube-apiserver类似,即使是在百倍集群规模下,Karmada仍能保持快速API响应。
Karmada支持通过命令行快速接入集群,以及集群的全生命周期管理。Karmada会实时采集集群心跳和状态,其中集群状态包括集群版本、支持的API列表、集群健康状态以及集群资源使用量等。其中,Karmada会基于集群资源使用量对成员集群进行建模,这样调度器可以更好地为应用选择资源足够的目标集群。在这种情况下,集群注册时延与集群的规模息息相关。下表展示了加入一个5,000节点的集群直至它可用所需的时延。你可以通过关闭集群资源建模来使集群注册时延与集群的大小无关,在这种情况下,集群注册时延这个指标将小于2s。
Cluster Registration Latency:
Karmada支持多模式的集群统一接入,在Push模式下,Karmada控制面直连成员集群的kube-apiserver,而在Pull模式下,Karmada将在成员集群中安装agent组件,并委托任务给它。因此Push模式多用于公有云的K8s集群,需要暴露APIServer在公网中,而Pull模式多用于私有云的K8s集群。下表展示了Karmada在不同模式下下发一个应用到成员集群所需的时延。
Resource Distribution Latency:
结论:我们容易得出,不论是Push模式还是Pull模式,Karmada都能高效地将资源下发到成员集群中。
在Karmada演进的数个版本中,大规模场景下使用Karmada管理多云应用的资源消耗一直是用户比较关注的问题。Karmada社区做了许多工作来减少Karmada管理大型集群的资源使用量,比如我们优化了Informer的缓存,剔除了资源无关的节点、Pod元数据;减少了控制器内不必要的类型转换等等。相较于1.2版本,当前Karmada在大规模集群场景下减少了85%的内存消耗和32%的CPU消耗。下图展示了不同模式下Karmada控制面的资源消耗情况。
Push模式:
Pull模式:
总的来说,系统消耗的资源在一个可控制面的范围,其中Pull模式在内存使用上有明显的优势,而在其他资源上相差的不大。
Karmada支持性能参数的可配置化,用户可以通过调整组件的参数来调整同一时间段内并发处理Karmada内部对象的数量、系统的吞吐量等以优化性能。同时Karmada在不同模式下的性能瓶颈并不相同,以下着重对此进行分析。
在Push模式中,控制面的资源消耗主要集中在karmada-controller-manager(约70%),而Karmada控制面基座(etcd/karmada-apiserver)的压力不大。
结合karmada-apiserver的qps以及karmada-etcd的请求时延我们可以看出karmada-apiserver的请求量保持在一个较低的水平。在Push模式中,绝大多数的请求来自karmada-controller-manager。因此我们可以通过调整karmada-controller-manager的--concurrent-work-syncs来调整同一时间段并发work的数量来提升应用下发的速度,也可以配置--kube-api-qps和--kube-api-burst这两个参数来控制Karmada控制面的整体流控。
在Pull模式中,控制面的资源消耗主要集中在karmada-apiserver,而不是karmada-controller-manager。
结合karmada-apiserver的qps以及karmada-etcd的请求时延我们可以看出karmada-apiserver的请求量保持在一个较高的水平。在Pull模式中,每个成员集群的karmada-agent需要维持一条与karmada-apiserver通信的长连接。我们很容易得出:在下发应用至所有集群的过程中请求总量是karmada-agent中配置的N倍(N=#Num of clusters)。因此,在大规模Pull模式集群的场景下,Pull模式在资源下发/状态收集方面有更好的性能,但同时需要考虑控制面的抗压能力以及各个karmada-agent和控制面的整体流控。
当前,Karmada提供了集群资源模型的能力来基于集群空闲资源做调度决策。在资源建模的过程中,它会收集所有集群的节点与Pod的信息。这在大规模场景下会有一定的内存消耗。如果用户不使用这个能力,用户可以关闭集群资源建模来进一步减少资源消耗。
根据上述测试结果分析,Karmada可以稳定支持100个大规模集群,管理超过50万个节点和200万个Pod。在Karmada落地进程中,用户可以根据使用场景选择不同的部署模式,通过参数调优等手段来提升整个多集群系统的性能。
受限于测试环境和测试工具,上述测试尚未测试到Karmada多集群系统的上限,同时多集群系统的分析理论以及测试方法仍处于方兴未艾的阶段,下一步我们将继续优化多集群系统的测试工具,系统性地整理测试方法,以覆盖更大的规模和更多的典型场景。
揭秘In-Context Learning(ICL):大型语言模型如何通过上下文学习实现少样本高效推理[示例设计、ICL机制详解]