前言
资源使用背景
当前众多金融企业开始将业务应用进行容器化部署,以期实现业务应用开发的敏捷迭代、运行环境的快速部署、业务负载的弹性伸缩、应用系统的全生命周期管理等效果。助力企业金融科技创新和金融场景创新,拓宽金融业行业边界,让金融服务内容更加多元,挖掘用户更多潜在需求,提升用户黏性和服务体验,全面增强企业竞争力。
当前上云用云作为G行数字化转型的关键一步已走到决定性阶段。从内部来看,随着上云由外围系统过渡到核心系统,用云进入深水区,目标从如何上云用云,变成如何用好云。安全可靠、控制成本和优化性能是目前G行云使用方案需要关注的三个重要维度。从外部来看,一方面全球经济下行处于下行期,另一方面近期一些互联网头部企业相继发生系统崩溃事件,促使业界对云使用的资源优化和安全运行讨论又一次达到高峰。
在云资源降本增效的过程中,我们目标是要降本不降质,不能以降低系统稳定性、效率、安全运营等为代价。本文基于有效保障业务平稳运行的前提下,探索常见容器环境的资源优化方法,对如何提升资源利用率,控制云成本做出思考和总结。
资源使用背景
为方便理解,我们将容器环境应用架构分为如图1所示的应用层、调度层、资源层。逐一阐述各层资源使用情况。
图1 容器环境应用基础架构
应用层
Kubernetes 使用了Request(请求)和Limit(限额)来描述容器对CPU和内存资源的需求。
Request:容器预留的资源量。即便容器没有实际使用到这些资源,Kubernetes也会为容器预留好这些资源,其他容器无法在资源池内申请这些资源。
Limit:限制容器使用的资源上限。容器在实际运行的时候不能超过的资源阈值。如果容器使用的资源超过了这个值,就会触发K8s后续对应的操作。对于CPU来说,由于CPU 是可压缩资源,所以如果容器使用的CPU超过了 limit 设置的值,会导致CPU节流服务降级,影响应用处理速度。但对于内存这种不可压缩资源,如果内存的使用量超过了limit的值,则会触发OOMKilled。
G行在业务的实际使用中,为大部分服务设置Request和Limit,同时Limit是Request的2倍以上(Limit比Request大,实际是对物理资源的一种超卖)。在图2中,从G行某集群工作节点CPU使用线性图可以看出,CPU限制率为209.14%,节点上的应用超卖109.14%。通过应用资源配置进行一定程度的超卖,增加Pod的部署密度,可以有效提升集群整体的利用率。
图2 集群工作节点应用CPU超卖情况
调度层
在Kubernetes中,调度是指将Pod放置到合适的节点上,以便节点上的Kubelet能够运行这些Pod。原生Kubernetes调度器Kube-scheduler给一个Pod做调度选择时包含两个阶段—预选和优选。
预选阶段会将所有满足Pod调度需求的节点选出来。其中PodFitsResurces策略会检查候选节点的可用资源是否满足Pod的Request资源请求。
优选阶段会对每个通过预选的节点优先级打分。其中LeastRequestedPriority策略会优先从预选节点列表选择资源占用最小的节点。BalancedResourceAllocation策略会优先从预选节点选择CPU和内存占用率最均衡的节点。
从原生Kubernetes调度器的策略可以看出,Pod请求值Request配置的准确性直接影响集群节点资源利用率和集群负载的均衡性。
资源层
Node节点资源并不能完全被Pod所使用,这就引入了一个问题,Kubernetes如何划分节点上的计算资源。Kubernetes将节点上的计算资源分为如图3所示几部分,其中:
- System Reserved:系统保留的计算资源,不能被Kubernetes调度和使用,比如 sshd 等等。
- Kubernetes Reserved:Kubernetes为Dockerd、Kubelet、Kube-proxy等保留的计算资源,这部分保证Kubernetes正常工作。
- Eviction Thread:当节点内存或磁盘资源紧张时达到阈值,kubelet会根据Pod 的 QoS优先级回收Pod占用的资源。
- Fragments Resource:通常情况下,Node节点上会剩余一些资源碎片,这些资源无法满足调度Pod的资源需求。
- Node Allocatable Capacity: 能够被Kubernetes调度和使用的计算资源,它的计算方法为:[Node Allocatable Capacity] = [Node Capacity] - [System Reserved] - [Kubernetes Reserved] - [Eviction Thread] - [Fragments Resource]
图3 Node节点维度的计算资源
资源未能充分使用原因
应用层
- 采用传统资源评估分配方法进行云上资源分配
容器资源规格Resource Request和Limit的填写让Kubernetes的使用者困惑,应用管理员需要预留较多的冗余资源,来应对流量的波动,保障业务运行的稳定性,导致资源冗余性有余,利用率不足。在图4中,某教学类系统CPU请求率为2%到5%(请求率=使用值/请求值),资源规格Request值设置有冗余,资源利用率有一定的提升空间。
图4 教学类项目资源使用率
- 对容器的自动弹性能力保持谨慎,按需自动扩缩容未能有效运用
在应用层开启弹性能力赋能业务是我们需要重点考虑的问题。容器秒级启动的特性,让我们可以在业务中利用弹性扩缩容按需分配资源。G行在研究探索过程中发现在线类交易业务流量存在波峰波谷现象,若此类业务开启弹性扩缩容,会避免大量资源浪费。图5为某在线交易项目微服务模块的CPU使用率情况,我们可以看到该业务每天会有突发性流量高峰,其他时间段流量处于较低的水平,有明显的流量波峰和波谷的特征。非常适合利用容器的极速弹性能力实现资源优化。
图5 在线交易项目微服务模块CPU使用率
调度层
- 原生调度无法满足实际使用场景
Kubernetes默认使用原生调度器Kube-scheduler,它的主要职责是为一个新创建出来的 Pod,寻找一个最合适的 Node节点。G行在探索过程中发现由于原生 Kubernetes 调度器只能基于资源的 Resource Request 进行调度,有些节点 Pod 的真实资源使用率,往往与其所申请资源的Request差异很大,这直接导致集群负载不均的问题和部分节点的资源使用不充分。Kubernetes 原生调度与资源绑定功能已经无法满足复杂的算力场景。图6为某集群节点的CPU使用率,从中可以看到使用原生调度器的场景下每个节点的CPU使用率并不均匀并且存在个别节点资源使用不充分的情况。
图6 集群节点CPU使用率
资源层
- 资源碎片使资源池无法充分利用
由于 Kubernetes 调度程序无法预测未来的 Pod 大小和节点添加,随着时间的推移,最终会导致任何节点都无法满足Pod的资源调度,即使节点上可能剩余很多资源。这样就产生一个假的资源紧张现象。结合图7和图8展示的G行某集群节点CPU资源使用情况和Pod业务资源规格可以看出节点计算资源总量为16核,已请求13.15核,但业务的请求规格为4核,这直接导致节点有至少2核的资源碎片无法被其他Pod调度。
图7 G行某集群节点CPU使用情况
资源优化措施
通过分析上面影响资源利用率的原因做出以下相应改进措施。
应用层
- 结合云的特性优化资源评估方法,规范调配常驻资源
针对使用方普遍存在的过度申请冗余资源的情况。在资源申请方面,G行通过非功能测试评估业务部门未来一段时间的业务规划,梳理出合规并有一定冗余量的资源规格;在资源优化方面,通过持续收集容器的资源用量,进行汇总分析,根据历史数据和智能算法为每个容器生成资源规格的合理推荐值,沉淀形成资源评估分配规范标准;在资源运营方面,强化资源使用跟踪,监控资源运行数据,按日发布资源利用率情况,按月发布项目运营分析报告及综合效能评分,协助各项目组优化资源部署,提升资源效能。
从图9展示的资源利用率变化趋势图可以看出,针对某电子化项目资源利用率低的问题做出整改措施后,利用率有明显的上升变化。
图9 某电子化项目资源使用优化趋势图
- 在充分测试后,有效推进弹性技术赋能业务
在线类业务的使用量会根据负载情况出现波动,所以在设置资源规格时应该充分考虑周期性特点使用弹性资源,以便业务在流量谷底可以降低资源使用,而在高峰之前又能及时提升能力。Kubernetes提供了自动扩展功能,如基于指标的自动水平弹性扩缩容HPA,可以根据工作负载的 CPU 或内存使用率自动扩缩 Pod 副本数,通过使用弹性能力实现资源按需分配。
从图10和图11可以看到某业务在CPU负载超过目标阈值45秒后,Pod自动扩容到3副本。弹性扩缩容帮助业务减少冗余资源的设置、规避容量风险。
图10 扩容CPU平均使用率
图11 扩容Pod副本数
调度层
- 调度感知实际资源负载
由于原生Kubernetes调度器依赖于Request 静态配置,而不是基于实际节点的负载情况调度Pod,因此会出现集群各个节点负载不均衡的现象。我们期望动态获取当前节点 的实时资源水位,据此打分从而干预调度结果,平衡各个计算节点的资源使用,充分发挥资源池的资源供给。
资源层
- 资源碎片再平衡
原生Kubernetes调度器会根据当时集群的资源描述做出最佳的调度决定,但基于静态数据的调度有时并不能适应之后资源的动态变化,我们期望通过识别和迁移节点间的特定 Pod 来实现可用资源片段的整合,解决资源池的资源碎片,更充分利用好现有资源,节省不必要的开支。
总结
本文首先介绍容器环境各层使用资源的背景,通过生产环境的资源使用实践,分析造成资源使用率低于预期的原因,最后提出相应解决方案。
云上资源优化并不是盲目追求低成本,而是在业务价值得到保障前提下有效提高投入产出比。优化需要统筹多方指标达到最优解,任何时候都不能忽视系统安全性、稳定性、可扩展性和性能,这样才能取得最优效果。总之,上云用云是个循序渐进的过程,云上资源优化也是反复迭代过程,需要覆盖业务上云全周期形成闭环、持续跟踪、持续分析、持续优化最终达到最佳效果。
本文是介绍G行全栈云容器环境降本增效之路的入门文章,之后会不定期更新系列文章介绍G行容器云资源优化实践和效益,助力充分发挥云效能,服务好广大客户。