前言
Kubernetes 提供了对 CPU、内存等资源的抽象能力,用户可以根据容器的实际需求声明资源规格,这种方式有效提升了集群资源的管理效率。然而,如何填写容器的资源规格一直以来都是困扰应用管理员的关键问题,过高的资源规格会导致大量的资源浪费,而过低的规格又会为应用带来潜在的稳定性风险。
阿里云容器服务 Kubernetes 版(Alibaba Cloud Container Service for Kubernetes,以下简称 ACK)为 Kubernetes 原生的工作负载提供了资源画像的能力,实现容器粒度的资源规格推荐,可以有效简化应用管理员为 Pod 配置 Request 和 Limit 的复杂度。
Kubernetes 容器资源管理
Kubernetes 为容器资源管理提供了资源请求(request)的资源语义描述,当容器指定了 request 时,调度器会将其与节点的资源容量(capacity)进行匹配,决定其应该被分配到哪个节点。容器的 request 一般基于经验来填写,应用管理员会参考容器的历史利用率情况、应用的压测表现,并根据线上运行情况的反馈持续调整。
然而,这种基于人工经验的资源规格配置模式存在以下局限性:
- 为了保障线上应用的稳定性,管理员通常会预留相当数量的资源 buffer 来应对上下游链路的负载波动,容器的 request 配置会远高于其实际的资源利用率,产生大量的浪费。相关统计数据表示,在大部分在线服务的生产环境中,集群的资源利用率处于相当低的水平。
- 当集群分配率较高时,为了提升集群资源利用率,管理员会主动缩小容器的 request 配置,以协调更多的资源容量。这类操作短期内可以提升容器的部署密度,但长期来看可能会因应用流量波动而产生稳定性风险。
- 完全依赖专家经验的管理方式无法适应规模的增长,随着应用数量增多,其管理效率会愈发降低。
资源画像
应用的资源画像数据可以为管理员提供有效帮助,所谓资源画像,指的是应用资源消耗的特征,既包括 CPU、内存这类常用的集群物理资源,也包括网络带宽、磁盘 IO 这类相对抽象的类型。在日常的容器资源管理中,运维人员最关注的就是 CPU 和内存。如果我们能够将资源消耗的历史数据收集起来,并进行汇总分析,管理员在为容器设置规格时就可以做到有的放矢。
除了资源规格这个维度,应用的资源画像还包含时间维度的特征,特别是互联网服务的流量会受到人们生产生活影响,呈现出明显的高低峰、周期性以及可预测性。例如本地生活类应用会存在午间和晚间高峰,办公类应用会存在上下班打卡高峰,而电商类应用在促销阶段的流量波峰预期会是波谷的数倍之多。如果调度系统能够捕捉到这一信息,根据集群和应用状态灵活调配资源,就可以实现资源分配的削峰填谷效果。
综上所述,一套稳定的资源画像系统,可以有效提升运维人员的管理效率,保障应用稳定运行的同时,充分提升集群资源使用率。
技术内幕
数据模型
容器资源规格的画像结果有多种应用场景,包括指导应用管理员填写容器的 Reqeust/Limit 配置,为资源调度、重调度算法优化提供数据参考,以及指导 VPA 等周边弹性组件对应用进行动态的扩缩容等等。这些场景对算法模型有比较通用的要求:
- 当应用负载水位上升时,画像结果需要快速响应变化,确保各组件可以迅速满足容器突发的资源需求。
- 当应用负载水位下降时,在画像结果上的体现需要推迟,避免过于乐观的降配导致应用产生稳定性问题。
以上要求可以通过典型的滑动窗口模型来满足,在此基础上,为了让画像结果更为平滑,可以根据数据的时效性对其权重因子进行衰减,确保越新的数据对算法模型的影响越大,越旧的数据对算法结果的影响越小。半衰期滑动窗口就是一种典型的算法模型:
其中τ为数据样本的时间点,t1/2 为半衰期,表示每经过t1/2 时间间隔,前一个t1/2 时间窗口内数据样本的权重就降低一半。
核心算法
资源画像依赖的是容器资源用量数据,这些数据的粒度往往是分钟级甚至秒级,基于半衰期滑动窗口的数据模型又需要大量的历史数据积累。如果把所有数据都保存下来,供画像算法定期迭代分析,其存储和计算的开销都难以接受,而且在冷启动阶段会引入严重的性能问题。
事实上,针对画像的数据模型,我们有多种统计工具可以利用,在历史数据存储方面我们可以采用统计直方图的形式,起到数据量压缩的效果。如下图所示,我们将直方图的横轴定义为资源量,纵轴定义为对应采样点的计数次数,统计间隔以 5% 左右的幅度增加,这样每个工作负载的容器历史数据只需要两百多个计数点即可完整保存。同时,这种存储方式也便于定期保存,可以显著提升冷启动阶段的性能。
画像规格推荐有多种计算方式,例如按采样峰值、加权平均、分位值等等。实践经验表明,分位值算法具有比较广泛的适用性,针对不同类型工作负载的资源规格都可以准确刻画。需要注意的是,这里的分位值算法并不是针对采样点的简单统计,而是针对工作负载算力需求的分位值。二者的区别如下图所示,有 9 个采样点的内存用量很低,只有 100MB,而第 10 个采样点的内存用量很高,达到了900MB以上,如果按时间采样点得到的 90% 分位值只有 100MB,显然无法准确刻画应用的资源需求,而按负载算力得到的 90% 分位值则为 900MB,相比之下更为准确。除此之外,画像算法还会考虑其它多种因素,例如前文提到的时间半衰期、样本数据置信度以及容器 OOM 情况等等。
案例实践
我们将某 Deployment 类型的测试应用部署到 ACK 集群,开启应用的资源画像功能,同时将容器的规格(request),容器实际的资源使用量(usage),以及容器的资源画像结果(recommend)汇总到 Prometheus 监控页面,如下图所示。
蓝色折线为该应用的 CPU 实际使用量,橙色折线为资源画像结果,绿色折线为 request 原始规格。此时管理员即可参考容器的画像结果来调小 request 规格,可以有效节省集群资源消耗。
未来计划
围绕资源画像的相关产品能力目前正在筹划中,后续我们提供产品控制台的形式进一步降低使用门槛,为用户提供高效便捷的管理能力,敬请期待!
往期文章—《阿里巴巴云原生混部系统 Koordinator 正式开源》我们介绍了云原生混部开源系统 Koordinator,接下来我们将逐步把 ACK 提供的一系列调度优化能力贡献到开源社区,帮助更广大的行业人士改进云原生工作负载运行的效率、稳定性和计算成本。
Koordinator 社区目前已经开放,我们非常欢迎广大云原生爱好者们通过各种方式一起参与共建,期待听到您的声音!
Github 地址:
https://github.com/koordinator-sh/koordinator
加入社区 Slack channel(English):
https://koordinatorgroup.slack.com/archives/C0392BCPFNK
作者:张佐玮(佑祎)
原文链接:http://click.aliyun.com/m/1000339341/
本文为阿里云原创内容,未经允许不得转载。