22cf758f1f6c4e76671f03ab234647c6.gif

嘉宾 | 宋翔

出品 | CSDN云原生

提到近两年的技术热词,“云原生”觉得是位居前列。从云计算大数据再到如今的云原生时代,一大批新技术涌现,例如当下最火热的系统部署和容器服务平台Kubernetes(K8s),K8s 甚至被不少人认为就是未来云平台基础设施的标准。

网上关于K8s如何使用的案例跟教程已数不胜数,那么在实际使用中,该如何最大性能地提升K8s集群利用率呢?

近日,来自腾讯的宋翔在由信通院、腾讯云、FinOps 产业标准工作组联合策划的《原动力 x 云原生正发声 降本增效大讲堂》第三期直播上就《如何提升Kubernetes集群利用率》进行了实战经验分享,内容非常干货且具备实操性,笔者整理分享给大家。

0484c1670577eb2f39b31a043f8262eb.png

利用率提升背景

利用率提升的大背景可以归纳为4个字——降本增效。通常来说,集群的利用率低会导致成本居高不下。集群、应用等配置,使用不合理,可能无法持续提升集群资源利用率,导致恶性循环。

资源不合理的原因主要有以下几点:

  • 集群管理员无法准确评估集群规模

    • 配置的集群Buffer不合理,Node资源冗余。

  • 用户Pod资源配置不合理

    • Pod实际利用率低,配置要求高,导致集群调度满了,但利用率无法提升。

若想要深入探究集群低负载的原因,可以从两种情况着手分析。

情况1:Pod Resource Setting

ee92631b1e78b5e5cce862d6825c7c9e.png

如上图所示,Pod QoS分级有三种。

  • BestEfforts模式下,Pod不设置Request值和Limit值。因为QoS优先级过低,所以在当前的实际应用场景中,几乎都不采用该设置模式;

  • Guaranteed模式要求用户设置相同的Request值与Limit值,虽然该模式具有较强的稳定性,但无法有效提升集群资源利用率;

  • 最常使用的是Burstable模式,该模式下用户设置Request值与Limit值,同时要求Request值小于Limit值,通过二者数值的调整可以实现实际场景下利用率的提升。

情况2:Node分配Pod资源

47b22effef9d626ec0c7f83bfcc01735.png

一个Node节点具有一定的Capacity,实际上这些资源并不能够全部被Pod所使用。其中Node需要预留部分资源给操作系统和Kubelet。除此以外的Node剩余可调度资源可以提供给Pod进行调度。

通常情况下,Node节点上会剩余一些碎片资源,这些资源无法满足待调度Pod的要求,这便造成了节点资源的浪费。

通过以上两种情况,可以总结出造成节点资源不足的两个原因。

第一,节点Pod调度不充分。

  • 集群Node资源常年冗余,Pod调度不充分;

  • 少数HPA扩容场景时,Pod调度水位较高,但是日常又恢复低水位,导致日常预留Buffer过多。

第二,Pod设置不合理。

  • 一般用户难以估算Request/Limit值;

  • 用户更倾向过于保守的Request/Limit值;

  • 为满足短暂(周期)峰值设置较高的Limit值;

  • 不合理的镜像导致需要较大Request,进而导致Pod本身常年低负载。

1f86a73204b0afcf729325e4930d68b6.png

常见集群负载优化方案思路

1. 用户篇

优化思路

第一,优化Pod配置。

5eca10799e2a625ed228ad1694a97cc5.png

  • 利用历史数据进行Request、Limit调整;

  • 用户在资源分析页面,利用Crane推荐值;

  • 调整Pod类型为相对规整的资源类型;

  • 优化程序和镜像。

第二,设置合理的HPA。

  • 根据历史数据,推荐用户设置合理的HPA范围和阈值;

  • 基于Crane EHPA算法修正HPA触发条件;

  • 梯度扩容减少扩容频率,提高利用效率。

第三,设置合理的CronHPA。

  • 对于周期性明显的业务,可以设置定时周期扩缩容;

  • 在节假日、活动促销时,可以提前设置时间段扩容。

第四,根据用户的策略,设置适当的VPA。

腾讯医疗服务案例

f6eead11937f53ba23b807a4208011bd.png

从上图可以看出,上午时段流量上涨迅速且每周五具有HPV疫苗抢购活动,所以需要在该时段进行提前自动扩容设置。

同时,根据低峰期、高峰期、平峰期所需要的节点数(分别为2、18、8),用户可以结合HPA和CronHPA做简单的调整——将实例范围设置为2-30,CPU使用率达到Limit值的50%时触发策略。

26956109db673f37fa6c7dd1bfa98562.png

通过以上一系列操作,相比未开始HPA时,成本可以有效减少60%,达到“降本”的目的。

2. 平台篇

优化思路

前面已提到,Node资源并不能够全部被Pod所使用,需要预留部分资源给操作系统和Kubelet,同时还会产生无法满足Pod调度要求的碎片资源。那么在这种情况下,该如何充分提高利用率呢?

第一,动态Pod压缩。

e78943f2c3fe0396f3824f313f23b80d.png

如上图所示,我们可以看到Pod被分配至节点A、B、C上,其中Pod A、Pod B的CPU Usage较低,这种情况下可以对Pod A、Pod B进行压缩,将其余待调度的Pod放置在该节点,以实现平均CPU负载提升的目的。

f803bdaf7d47d4524de0506d89cf7511.png

需要特别注意的是,在线业务没有优先级之分,每一个Pod都非常重要,不能因为其中某一个Pod占用多数资源或可能造成其他资源异常就对其进行驱逐。

同时,做资源压缩的前提是用户已设置Request值与Limit值,且二者初始值一般相等。这可以保证用户可使用的最大值不变,在对Request值进行压缩时,一个节点可以容纳更多的Pod。

此外,起初可以设置全局默认压缩比,随后可根据历史数据进行行态调试,以达到最佳值。

第二,Node节点超卖。

6b830db1214c77ad78172840f1ce7fa7.png

如上图所示,假设左侧节点为30核,若能通过一系列的手段让Kubelet、Kubernetes调度器认为该节点为60核,那是不是就能够调度更多的Pod呢?

该如何去做呢?分两个阶段:

  • 设置全局默认超卖比;

  • 根据历史数据、实时数据动态改变超卖比。

c34c886bc476b0b0b2fb01b3566f2092.png

第三,碎片整理。

7792c8f4554e56756cd162294484c066.png

如上图,我们可以看到节点A、B的资源均不满足未调度Pod G的需求,且节点B中的Pod E可以调度到节点A中,腾挪空间。

14b8f4bc15da41f80fceb4bbdeeeefd6.png

70cf30361aee2cfa0395b5f5a61ecdf4.png

这种情况下,可以Pod E从节点B调度至节点A ,以此增加节点B的空闲资源来满足未调度的Pod G的需求。这就是碎片资源整理的过程。

a4a58ef98417be283f46b454c3b56a7d.png

第四,在离线混部。

08f344eaf3eb0842198aeeaf283fb46f.png

当平台规模较大或在线、离线业务均具有的情况下,一般都需要使用在离线混部的方式提升资源利用率。

989de82fec3995a668687204d2c0d263.png

其实现逻辑较为简单:当集群资源充足时,动态地将离线任务调度到空闲节点上;当节点资源接近高负载阈值时,优先驱逐离线任务。

38c506745715dc1d19770cb4e92cbd21.png

负载提升和稳定性优化

通过各种手段提升集群利用率的同时,也会带来相应的负面问题:

  • 引起Node节点高负载,影响服务质量;

  • Node节点负载不均;

  • 剩余剩余资源不足导致Pod 横向度失败。

针对以上负面问题,通常需要使用扩容及稳定性相关的手段来解决。

第一,两级扩容机制。

1df4a5f773c4cb5d823b8704b8532047.png

  • HNA: 当集群负载(装箱率)达到阈值(如85%)时,会触发节点自动扩缩容,来增加Node节点;

  • 超级节点:当工作负载引发大量扩容、集群资源不足而导致Pod突增时,利用超级节点(通过Virtual Kubelet加入集群的虚拟Node)直接将Pod扩容到Virtual Kubelet节点上,超级节点的底层直接使用腾讯云公有云资源池创建弹性Pod。

第二,两级动态超卖。

3ec9cb69d302ca27c43b273498ac6e81.png

通常情况况下,Pod压缩与Node超卖两种手段需同时使用。Pod压缩已实现从静态到动态的优化,其压缩比(Request/limit)可以根据历史状态进行动态修改。

同样,Node超卖也实现了由静态向动态的升级,Node节点可以根据实时负载进行动态调整,以防止节点负载过高。

第三,动态调度。

动态调度机制可以实现保证Node节点的资源均衡,避免不同Node节点负载不均的现象。

1474c2f2b76a7490f7bc75e31425c3c9.png

上图可以看到,原生调度为静态调度且Node2空闲资源较多,那么根据静态调度策略,会将新的Pod调度到Node2节点中。但经过动态调度的算法优化,实际上会将Pod调度到Node1节点上,这是什么原因呢?

这是因为Node1节点的真是利用率更低所致的,将Pod调度至Node1上会提高Node的Pod利用率,进而使各节点的平均负载相近。

08a8b4d8c837937f5883f75ff6a1ff71.png

上图是动态调度机制的原理,Extend NodeScorer会根据不同时段的信息参数对Node进行打分,Kube-scheduler调度器可获取这些参数信息进而将新增Pod调度至实际内存使用更低的节点上。

第四,动态驱逐。

8e2801d071d5f4851a6539aa86b1f2e1.png

当Node负载不均或Node利用率过高时,大概率会对节点上运行的Pod资源产生影响。这种情况下,我们可以根据节点当前的状态信息以及节点上Pod的实际利用率对Pod进行动态驱逐。这里的参考维度是多样的,一般包括:CPU、Memory、FD、Inode等,且不同业务针对参数的权重与指标也存在差异。

dada39a4e20090d488c79431bbc8cb8f.png

上图是某一在线业务集群的状态,可以清晰看到在经过超卖及压缩后,该集群的节点平均利用率可达38.7%。

5de903e090dd4793d72fbb6852ab8275.png

节点负载分布(未采用动态调度及动态驱逐)

4240b816d95d72823355570f2f1b9fda.png

节点负载分布(采用动态调度及动态驱逐)

通过以上两图对比,我们可以看到:在未采用动态调度及动态驱逐时,节点负载不均衡同时方差值较大。而在采用了动态调度及动态驱逐后,节点负载便会趋于稳定,异常Node数目减少,资源利用率得到有效提高。

e99b90512e2e7529dbc7d56a1520a2ea.png

总结

本文结合腾讯应用实践,分享了Kubernetes集群利用率提升的思路和实现方式,包括两级扩容机制、两级动态超卖、动态调度、动态驱逐。

作者简介:

宋翔,负责腾讯超大规模自研业务上云的容器平台TKEx研发设计,将Docker、Kubernetes、Istio等云原生技术内部落地,助力腾讯QQ、在线教育、腾讯会议等海量业务的云原生容器化改造。

栏目介绍:

《原动力 x 云原生正发声 降本增效大讲堂》是由信通院、腾讯云、FinOps 产业标准工作组联合策划,围绕“云原生”主题进行的线上分享活动。感兴趣的小伙伴可以点击『阅读原文』查看活动视频。

— 推荐阅读 —

 
 
☞传腾讯计划出售美团全部股权,知情人士辟谣;苹果证实iOS 16要大量推送广告;Linux 6.0-rc1 发布|极客头条
☞开发者驱动的软件公司,如何赚取万亿美元?
☞遭老牌 Node.js、新贵 Bun “围攻”,Deno 之父紧急求变!

83011667ece04599fe854b97e0901895.jpeg

Logo

20年前,《新程序员》创刊时,我们的心愿是全面关注程序员成长,中国将拥有新一代世界级的程序员。20年后的今天,我们有了新的使命:助力中国IT技术人成长,成就一亿技术人!

更多推荐