查看原文
其他

B站容器云平台VPA技术实践

许龙崔超杰张鹤 哔哩哔哩技术 2023-03-21

本期作者



许龙

哔哩哔哩资深开发工程师


崔超杰

哔哩哔哩高级开发工程师




张鹤

哔哩哔哩资深SRE工程师


一、背景


B站基于k8s构建的私有云平台已达万级节点规模,托管了公司大部分的在线业务以及机器学习、大数据、转码等离线业务。在推进降本增效的过程中,我们发现业务申请的容器资源规格存在不合理的现象,通常设置的资源配额会比实际负载偏大很多。这就造成节点的cpu分配率很高,已经无法调度新容器,但是节点的实际cpu峰值利用率却很低(如图所示)。



这种不合理的容器规格导致整体集群资源产生了很大的浪费。面对这个问题,我们主要从两个角度进行解决:一是利用混部技术,通过调用一些低优业务到这类机器上,实现对闲置资源的有效利用,在之前的文章《B站云原生混部技术实践》【1】 中有详细介绍;二是从业务容器本身出发,采用垂直弹性伸缩(Vertical Pod Autoscaler,简称VPA)技术,基于业务的历史真实负载计算得到推荐的资源量,并自动调整容器资源规格。从我们的大规模实践效果来看,VPA技术有效地释放出了节点的空闲算力资源,满足了新增业务的资源需求,降低了新机器的采购成本。同时,作为一种自动化调整的机制,也极大地降低了人工进行容量管理的成本。下面,我们将详细介绍VPA技术的一些具体技术细节和实践经验。



二、业界现状


VPA一般需要具备以下三种关键能力:

1、容器资源规格推荐。基于应用的真实负载,根据特定的算法计算出容器的合理资源规格。

2、对于新创建的Pod,需要基于k8s webhook,在创建Pod对象的过程中将资源规格修改为推荐值。

3、对于已经创建的Pod,需要定时动态调整容器的资源规格。

目前,社区开源的VPA技术只支持上述1和2,存量pod如果要进行VPA,必须先驱逐,从而在重建时修改pod资源规格。很多业务不希望VPA调整资源配额时发生pod驱逐,因此业界也有部分公司选择修改K8S源代码来支持in-place VPA的能力,从而实现动态修改容器资源规格。K8S社区对于 in-place VPA已经有相关issue讨论 【2】,预计后续的k8s版本会合入该特性。目前,我们也是选择通过修改K8S源码来支持in-place VPA功能,同时自研了整体VPA的控制框架和管理平台,使得整体功能更加稳定易用。


三、VPA原理


 3.1 整体架构



VPA相关CRD

  • VPA Generator对象:由VPA管理平台创建的VPA策略模板对象,该对象基于label selector匹配业务应用的Pod,并创建应用维度的VPA对象。

  • VPA 对象:由控制器根据VPA Generator对象自动生成。主要包含Pod的匹配信息、推荐值算法相关的参数、当前的资源推荐值、容器资源的更新模式等。


VPA核心组件

  • VPA Generator控制器。主要用于降低VPA的管理复杂度,我们可以针对同一类的应用创建一个VPA策略模板对象VPA Generator,由控制器自动匹配这一类应用,并逐个创建出每个应用关联的VPA对象。

  • VPA Recommender控制器。主要是获取VPA对象所关联应用的历史负载值,计算出业务容器推荐的资源规格,并记录到VPA对象的Status字段中。

  • VPA Updater控制器。当VPA对象调整资源请求量的模式为自动模式或者直接更新模式时,该控制器会把VPA对象中Status字段里记录的资源推荐值更新到存量的业务Pod中,并立即生效。

  • VPA Webhook服务。当VPA对象调整资源请求量的模式为自动模式或者初始化模式时,该组件会把VPA对象中Status字段里记录的资源推荐值更新到新创建的业务Pod中。

  • VPA-API服务。作为VPA管理平台和kube-apiserver服务进行交互的中间代理,实现对K8S集群中VPA Generator对象的增删改查操作,同时也负责汇总收集VPA相关的可观测数据。


其他依赖模块

  • Kube-apiserver服务:是K8S集群的API访问入口。

  • Cadvisor服务:用于采集pod中每个容器的资源使用量指标。

  • Prometheus服务:用于聚合汇总Cadvisor采集的资源指标,供VPA Recommender控制器查询业务容器的历史资源使用量。


下面分别介绍一下VPA Generator控制器、VPA Updater控制器和VPA Recommender控制器。


 3.2 VPA Generator控制器


一般业界的VPA系统只会定义VPA CRD,会给每个应用建一个VPA。但实际场景中应用数量非常多,如果逐个应用维护VPA对象会产生较大的运维成本。B站内部业务是区分服务等级的,而相同服务等级的应用通常所需的VPA推荐策略是一样的,因此我们考虑引入VPA Generator CRD,在其中定义某一类VPA的生成策略,然后通过控制器来动态维护VPA对象的生命周期。上层不再需要关心每个应用的VPA怎么配置,而只需要为不同服务等级的应用制定好VPA策略即可。

VPA Generator控制器的主要逻辑如下:

1、VPA Generator控制器监听管理平台创建的策略模板VPA Generator对象,根据其中的selector信息匹配到集群中的相关pod;

2、将步骤1中匹配到的pod按所属应用分组,分别创建应用级别的VPA对象;

3、对于已经下线的业务Pod,相关联的VPA对象会保留一段时间,之后控制器会自动删除这批VPA对象。

如下图所示,VPA Generator对象的分组标签是:level=L0,它会命中集群中所有level=L0的服务,并划归为一个服务群,这样控制器就会为这个服务群的所有应用创建出关联的VPA对象。基于这个策略,业务SRE针对同一个应用等级的服务群,只需要维护一个VPA Generator对象,控制器可以动态创建或者删除该服务群对应的VPA对象,减少对VPA对象的管理运维成本。



 3.3 VPA Updater控制器


VPA Updater控制器会根据VPA对象中的匹配策略,过滤出VPA对象关联的业务Pod,并结合设定的更新模式,完成业务Pod资源量的更新动作。这里更新模式包含四种:预跑模式、初始化模式、直接更新模式和自动模式。各个模式分别适用于不同的应用场景。

  • 模式一:预跑模式,仅仅对创建的VPA对象进行推荐值计算,不进行Pod资源配额的动态更新,主要用在VPA策略预估和对照的场景。

  • 模式二:初始化模式,在创建Pod的时候,VPA Webhook根据pod的标签信息匹配到对应的VPA对象,然后根据VPA对象中的资源推荐值来更新Pod的资源配额。由于公有云不支持in-place Vpa能力,一般只能使用这种模式。

  • 模式三:直接更新模式,VPA Updater控制器直接动态更新存量pod的资源配额。IDC内部k8s集群(私有云)支持了in-place Vpa能力,因此可以开启该模式。

  • 模式四:自动模式,这个模式相当于同时开启了模式二和模式三,可以更新增量Pod或者存量Pod的资源配额。我们内部集群一般使用该模式。

如下图所示,模式二代表VPA Webhook组件监听到创建Pod的动作,然后根据VPA对象设定的模式来决定是否更新Pod的资源配额。模式三代表VPA Updater组件监听到VPA对象中的推荐值被更新之后,会根据VPA对象设定的模式决定是否直接更新存量Pod的资源配额。通过多种更新模式,很好地支撑了私有云和公有云场景的VPA需求。



 3.4 VPA Recommender控制器


VPA Recommender控制器根据VPA对象的指标策略,从Prometheus服务中获取业务服务的历史负载,然后结合推荐值算法计算出业务Pod的资源推荐值,并更新到VPA对象的Status中。其中可以根据VPA对象中设定的Schedule字段,约定VPA计算资源推荐值的周期,控制资源推荐值更新的节奏。



目前VPA推荐组件的推荐算法主要覆盖了两个场景。

场景一:自动化调整业务实例的资源request值,释放空闲资源,提高集群资源利用率

我们引入容器资源饱和率的概念,即“容器的资源使用量/资源request”。假设当前VPA对象使用业务容器的7天资源使用量的95分位值作为历史负载targetUsed,以及bufferFactor表示预期的资源饱和率,我们按如下公式计算得到推荐的资源值targetRequest,并更新到VPA对象的Status中。可以看到,预期资源饱和率实际上决定了给容器留多少配额buffer。对于服务等级较高的应用,我们希望其峰值饱和率相对较低,例如40%,以确保其在流量突发等场景下的稳定性;对于服务等级较低的应用,我们会把预期饱和率设的高一些,虽然牺牲了一定的稳定性,但是可以节省更多的配额资源。





在计算推荐值targetRequest时,需要约束推荐值的边界值,一般在生产环境中推荐下限MinAllowed默认为0.1C或者0.1G,推荐上限值MaxAllowed=资源的limit值-资源预留值,这样保证业务容器的推荐资源值合理有效。


场景二:业务Pod发生OOM事件,自动调整资源的limit值,提高运维效率

业务容器因为资源评估不准确,内存的limit值设置的较低而触发OOM事件,如果不及时调整limit值,业务容器会频繁OOM重启。针对这个现象,VPA Recommender控制器可以实时捕捉到Pod的OOM事件,并利用下面的公式评估出新的内存limit值。方式是根据最近内存使用量memoryUsed、扩容因子oomFactor以及发生内存泄漏的次数oomCount,计算出新的内存limit值,保证重建的Pod不会频繁发生OOM事件。






四、VPA管理平台


VPA管理平台基于Paas层的VPA技术,实现对集群资源的自动化治理能力。该平台主要负责VPA策略调优,VPA策略避让,VPA效果分析以及VPA异常检测等功能,下图展示了VPA管理平台的功能矩阵。



VPA策略调优,主要包含业务容器资源指标管理,维护VPA策略模板以及VPA策略预估和对照分析。

VPA策略避让,主要用于在压测、活动等场景中临时关闭某些应用的VPA策略。

VPA效果分析,主要用于VPA策略的数据运营和分析工作,着重统计了资源的覆盖率,VPA调整前后的资源量以及调整记录。

VPA异常检测,主要用来监控VPA策略的一些异常行为,比如调整业务容器资源发生失败,单个应用命中了多个VPA策略等异常事件。


 4.1 VPA策略管理


业务容器资源指标

资源指标用于计算业务容器的历史负载情况,一般约定容器前7天资源使用量的95分位值(指标名字:app_cpu_usage_7day_p95)作为VPA策略中的指标策略,同时根据当前策略的调整效果可以灵活变更指标策略。



VPA策略模板

VPA策略模板主要是定义了VPA Generator对象的核心属性,比如匹配的应用等级、自动扩缩的执行周期、资源推荐值上下限值、指标策略以及预期资源饱和率。平台可以根据VPA的策略模板在K8s集群中创建出VPA Generater对象。



VPA的预跑和对照能力

基于VPA对象的预跑模式,平台可以下发预跑的VPA策略,用于分析该策略的效果是否符合预期,确保完全符合预期后再下发正式的VPA策略。对于已经生效的VPA策略,我们也可以下发一个预跑模式的VPA策略作为对照组,精细化对比分析VPA调整效果,最终选取出最优的VPA策略。



 4.2 VPA策略避让


在生产环境中,存在部分场景需要临时关闭某些应用的VPA策略。例如业务经常会针对大型活动进行提前压测,在压测期间,业务流量比平时高出多倍,相应的业务容器的资源负载也会增加不少。此时VPA如果继续按历史峰值来计算推荐值,会造成资源池的分配率突增。因此,VPA管理平台联动压测平台,支持了策略避让的能力,可以指定具体的应用以及避让的时间窗口。



 4.3 VPA效果分析


VPA效果分析主要记录了一些关键的运营数据,可用于评估VPA策略是否符合预期。运营数据包含以下几个关键指标:覆盖的应用数量、覆盖的资源量以及资源扩缩记录等。

VPA策略覆盖的应用数量,下图记录了VPA策略命中应用数量的趋势图,其中区分了VPA可以调整的应用数量和不可调整的应用数量



VPA策略覆盖的资源量(以cpu为例),下图记录了VPA策略命中的所有应用占用资源请求量的趋势图(即覆盖cpu容量),其中包含VPA策略预估调整之后应用所占cpu容量和不可被调整的cpu容量。通过趋势图的对比可以看出该VPA策略预估应用被调整后所占cpu容量和覆盖cpu容量比较接近,说明资源调整的比较充分。



VPA策略调整记录明细,记录了VPA策略命中的每个应用扩缩资源请求量的情况。其中包含应用资源调整前后的容量和变化量,以及该策略覆盖的应用数,整体释放的空闲资源容量。



资源的饱和度指标,记录了业务服务的资源饱和度(即资源使用量/资源请求量)的变化趋势图。VPA就是根据预期的资源饱和度进行资源推荐值计算的,因此我们根据服务的实际资源饱和率趋势图,可以有效地评估VPA的整体调整效果。



 4.4 VPA异常检测


VPA异常检测主要是通过对VPA核心组件错误日志、错误事件的自动分析以及定期对关键指标的巡检来实现。例如VPA强依赖于监控系统的可用性,如果VPA Recommender控制器获取容器历史指标的错误日志频率超过了阈值,值班同学就会收到告警。此外,系统底层也记录了非常详细的应用资源使用率数据、VPA调整明细数据等,基于这些数据,VPA管理平台可以灵活地自定义一些巡检规则,例如VPA策略命中的应用是否能达到预期的峰值饱和率、VPA调整失败率是否高于阈值等。这一系列的异常检测和报警手段,使得我们能快速感知到VPA系统存在的潜在风险并及时介入处理。



五、基于VPA的集群资源治理


集群容量管理是一个逐步优化的过程,有了这套VPA系统之后,我们仍然需要持续地优化VPA策略,以及治理业务方的一些不合理的资源配置。

1、VPA存在一些无法生效的场景,VPA管理平台会把这部分问题记录下来,便于制定优化资源调整的策略。比如某些低服务等级的应用,其Pod Qos等级却是guaranteed,此时VPA是无法调整业务容器的资源请求量的。对于这类问题,我们会梳理出应用列表,找业务服务的负责人进行沟通并修改配置。当然对于新增应用,我们也会在应用创建时增加一些预检措施,提前规避此类问题。



2、优化业务容器指标。我们一开始采用前一天的99分位值作为历史负载来计算推荐值,忽略了周末的流量高峰对第二天推荐值的影响,导致资源推荐值波动比较大。替换为前七天的95分位值作为历史负载计算推荐值之后,整体推荐值变得平稳很多。

3、精细化配置VPA策略的预期饱和率,不同保障等级的应用期望饱和率不尽相同。例如,对于多活场景下的应用,保证VPA对象的资源饱和率设置低于50%,确保单机房故障之后,多活机房可以承载全部流量。对于非多活场景下的非高保障的应用,VPA对象的资源饱和率设置为70%~80%,从而减少资源浪费。


六、相关收益


基于上述VPA技术,我们较好地解决了IDC以及公有云集群中的容器规格不合理问题,从而在存量机器中释放出了大量闲置资源。在测试集群中,整体释放了约60%的cpu容量空间以及30%的内存容量空间;在生产集群中,释放了约30%的cpu容量空间,累计节省了超千台机器的采购成本。


七、总结与展望


本文介绍了B站云平台垂直弹性伸缩(VPA)的技术实践,主要涉及VPA的核心控制器逻辑,包括策略生成模板、推荐值计算、推荐值更新模式等。同时介绍了VPA管理平台的VPA策略调优、VPA策略避让、VPA效果分析以及VPA异常检测等功能。我们充分结合了实际的业务场景,将VPA技术产品化并推广落地。在未来的VPA技术迭代过程中,我们会结合应用画像、算力标准化等技术能力,制定精细化的VPA策略,进一步助力降本增效。


参考资料:

[1] https://mp.weixin.qq.com/s/pPEkfrLm0XEpgMU1KjiD4A

[2] https://github.com/kubernetes/enhancements/issues/1287


以上是今天的分享内容,如果你有什么想法或疑问,欢迎大家在留言区与我们互动,如果喜欢本期内容的话,欢迎点个“在看”吧!


往期精彩指路


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存