TKE 标准集群指南

最佳实践

API 文档

诚邀爱技术、爱分享的你,成为文档内容共建者> HOT
文档中心 > 容器服务 > 最佳实践 > 成本管理 > 资源利用率提升工具大全

背景

公有云的发展为业务的稳定性、可拓展性、便利性带来了极大帮助。这种用租代替买、并且提供完善的技术支持和保障的服务,理应为业务带来降本增效的效果。但实际上业务上云并不意味着成本一定较少,还需适配云上业务的应用开发、架构设计、管理运维、合理使用等多方面解决方案,才能真正助力业务的降本增效。在《Kubernetes 降本增效标准指南》系列的文章《容器化计算资源利用率现象剖析》中可看到,IDC 上云后资源利用率提高有限,即使已经容器化,节点的平均利用率依旧仅在13%左右,资源利用率的提升任重道远。

本篇文章将带您了解:

  1. 为什么 Kubernetes 集群中的 CPU 和内存资源利用率通常都如此之低?
  2. 现阶段在 TKE 上面有哪些产品化的方法可以轻松提升资源利用率?

资源浪费场景

为何资源利用率通常都如此之低?首先可以了解几个业务的实际使用资源场景:

场景1:资源预留普遍存在50%以上的浪费

Kubernetes 中的 Request(请求)字段用于管理容器对 CPU 和内存资源预留的机制,保证容器至少可以达到的资源量,该部分资源不能被其他容器抢占,详情见 Kubernetes 官方文档。当 Request 设置过小,无法保证业务的资源量,当业务的负载变高时无力承载,因此用户通常习惯将 Request 设置得很高,以保证服务的可靠性。但实际上,业务在大多数时段时负载不会很高。以 CPU 为例,下图是某个实际业务场景下容器的资源预留(Request)和实际使用量(CPU_Usage)关系图:

从图中可以看出,资源预留远大于实际使用量,两者之间差值所对应的资源不能被其他负载使用,因此 Request 设置过大势必会造成较大的资源浪费。如何解决这样的问题?现阶段需要用户自己根据实际的负载情况设置更合理的 Request、以及限制业务对资源的无限请求,防止资源被某些业务过度占用。这里可以参考后文中的 Request Quota 和 Limit Ranges 的设置。此外,TKE 将推出 Request 推荐产品,帮助用户智能缩小 Request 和 Usage 之间的差值,在保障业务的稳定性的情况下有效提升资源利用率。

场景2:业务资源波峰波谷现象普遍,通常波谷时间大于波峰时间,资源浪费明显

大多数业务存在波峰波谷,例如公交系统通常在白天负载增加,夜晚负载减少;游戏业务通常在周五晚上开始出现波峰,在周日晚开始出现波谷。如下图所示:

从图中可以看出,同一业务在不同的时间段对资源的请求量不同,如果用户设置的是固定的 Request,在负载较低时利用率很低。这时可以通过动态调整副本数以高资源利用率承载业务的波峰波谷,可以参考后文中的 HPA 、HPC、CA

场景3:不同类型的业务,导致资源利用率有较大差异

在线业务通常白天负载较高,对时延要求较高,必须优先调度和运行;而离线的计算型业务通常对运行时段和时延要求相对较低,理论上可以在在线业务波谷时运行。此外,有些业务属于计算密集型,对 CPU 资源消耗较多,而有些业务属于内存密集型,对内存消耗较多。

如上图所示,通过在离线混部可以动态调度离线业务和在线业务,让不同类型业务在不同的时间段运行以提升资源利用率。对于计算密集型业务和内存密集型业务,可以使用亲和性调度,为业务分配更合适的节点,有效提升资源利用率。具体方式可参考后文中的离在线混部和亲和性调度。

在 Kubernetes 上提升资源利用率

腾讯云容器服务 TKE 基于大量的用户实际业务,已经产品化了一系列工具,帮助用户轻松有效的提升资源利用率。主要从两方面着手:一是利用原生的 Kubernetes 能力手动进行资源的划分和限制;二是结合业务特性的自动化方案。

1. 资源划分和限制

设想,您是集群管理员,现在有4个业务部门使用同一个集群,您的责任是保证业务稳定性的前提下,让业务真正做到资源的按需使用。为了有效提升集群整体的资源利用率,这时就需要限制各业务使用资源的上限,以及通过一些默认值防止业务过量使用。

理想情况下,业务应该根据实际情况,设置合理的 Request 和 Limit(Request 用于对资源的占位,表示容器至少可以获得的资源;Limit 用于对资源的限制,表示容器至多可以获得的资源)。这样更利于容器的健康运行和资源的充分使用。但实际上用户经常忘记设置容器对资源的 Request 和 Limit。此外,对于共享使用一个集群的团队/项目来说,他们通常都将自己容器的 Request 和 Limit 设置得很高以保证自己服务的稳定性。当您使用容器服务控制台,创建负载时会给所有的容器设置如下默认值。该默认值是 TKE 根据真实业务分析预估得出,和具体的业务需求之间可能存在偏差。

资源 Request Limit
CPU(核) 0.25 0.5
Memory(MiB) 256 1024

为了更细粒度的划分和管理资源,您可以在 TKE 上设置命名空间级别的 Resource Quota 以及 Limit Ranges。

如果您管理的某个集群有4个业务,为了实现业务间的隔离和资源的限制,您可以使用命名空间和 Resource Quota。
Resource Quota 用于设置命名空间资源的使用配额,命名空间是 Kubernetes 集群里面的一个隔离分区,一个集群里面通常包含多个命名空间,例如 Kubernetes 用户通常会将不同的业务放在不同的命名空间里,您可以为不同的命名空间设置不同的 Resource Quota,以限制一个命名空间对集群整体资源的使用量,达到预分配和限制的效果。Resource Quota 主要作用于如下方面,详情见 Kubernetes 官方文档

  1. 计算资源:所有容器对 CPU 和 内存的 Request 以及 Limit 的总和。
  2. 存储资源:所有 PVC 的存储资源请求总和。
  3. 对象数量:PVC/Service/Configmap/Deployment 等资源对象数量的总和。

Resource Quota 使用场景

  • 给不同的项目/团队/业务分配不同的命名空间,通过设置每个命名空间资源的 Resource Quota 以达到资源分配的目的。
  • 设置一个命名空间的资源使用数量的上限以提高集群的稳定性,防止一个命名空间对资源的多度侵占和消耗。

TKE 上的 Resource Quota

TKE 上已经实现对 Resource Quota 的产品化,您可以直接在控制台利用 Resource Quota 限制一个命名空间的资源使用量,操作详情可参见 Namespaces 文档

2. 自动化提升资源利用率

上面提到的利用 Resource Quota 和 Limit Ranges 来分配和限制资源的方法依赖经验和手工,主要解决的是资源请求和分配不合理。如何更自动化的动态调整以提升资源利用率是用户更关心的问题,接下来从弹性伸缩、调度、在离线混部三大产品化的方向,详述如何提升资源利用率。

2.1 弹性伸缩

在资源浪费场景2中,如果您的业务存在波峰波谷,固定的资源 Request 注定在波谷时会造成资源浪费,针对这样的场景,如果波峰的时候可以自动增加业务负载的副本数量,波谷的时候可以自动减少业务负载的副本数量,将有效提升资源整体利用率。

HPA(Horizontal Pod Autoscaler)可以基于一些指标(例如 CPU、内存的利用率)自动扩缩 Deployment 和 StatefulSet 中的 Pod 副本的数量,达到工作负载稳定的目的,真正做到按需使用。

HPA 使用场景

  1. 流量突发:突然流量增加,负载过载时会自动增加 Pod 数量以及时响应。
  2. 自动缩容:流量较少时,负载对资源的利用率过低时会自动减少 Pod 的数量以避免浪费。

TKE 上的 HPA

TKE 基于 Custom Metrics API 支持许多用于弹性伸缩的指标,涵盖 CPU、内存、硬盘、网络以及 GPU 相关的指标,覆盖绝大多数的 HPA 弹性伸缩场景,详细列表请参见 自动伸缩指标说明。此外,针对例如基于业务单副本 QPS 大小来进行自动扩缩容等复杂场景,可通过安装 prometheus-adapter 来实现自动扩缩容,详情见 在 TKE 上使用自定义指标进行弹性伸缩

2.2 调度

Kubernetes 调度机制是 Kubernetes 原生提供的一种高效优雅的资源分配机制,它的核心功能是为每个 Pod 找到最适合它的节点,在 TKE 场景下,调度机制帮助实现了应用层弹性伸缩到资源层弹性伸缩的过渡。通过合理利用 Kubernetes 提供的调度能力,根据业务特性配置合理的调度策略,也能有效提高集群中的资源利用率。

倘若您的某个业务是 CPU 密集型,不小心被 Kubernetes 的调度器调度到内存密集型的节点上,导致内存密集型的 CPU 被占满,但内存几乎没怎么用,会造成较大的资源浪费。如果您能为节点设置一个标记,表明这是一个 CPU 密集型的节点,然后在创建业务负载时也设置一个标记,表明这个负载是一个 CPU 密集型的负载,Kubernetes 的调度器会将这个负载调度到 CPU 密集型的节点上,这种寻找最合适的节点的方式,将有效提升资源利用率。

创建 Pod 时,可以设置节点亲和性,即指定 Pod 想要调度到哪些节点上(这些节点是通过 K8s Label)来指定的。

节点亲和性使用场景

节点亲和性非常适合在一个集群中有不同资源需求的工作负载同时运行的场景。例如,腾讯云的 CVM(节点) 有 CPU 密集型的机器,也有内存密集型的机器。如果某些业务对 CPU 的需求远大于内存,此时使用普通的 CVM 机器,势必会对内存造成较大浪费。此时可以在集群里添加一批 CPU 密集型的 CVM,并且把这些对 CPU 有较高需求的 Pod 调度到这些 CVM 上,这样可以提升 CVM 资源的整体利用率。同理,还可以在集群中管理异构节点(例如 GPU 机器),在需要 GPU 资源的工作负载中指定需要 GPU 资源的量,调度机制则会帮助您寻找合适的节点去运行这些工作负载。

TKE 上的节点亲和性

TKE 提供与原生 Kubernetes 完全一致的亲和性使用方式,您可通过控制台或配置 YAML 的方式使用此项功能,详情见 资源合理分配

2.3 离在线业务混部

如果您既有在线 Web 服务业务,又有离线的计算服务业务,借助 TKE 的离在线业务混部技术可以动态调度和运行不同的业务,提升资源利用率。

在传统架构中,大数据业务和在线业务往往部署在不同的资源集群中,这两部分业务相互独立。但大数据业务一般更多的是离线计算类业务,在夜间处于业务高峰,而在线业务与之相反,夜间常常处于空载状态。云原生技术借助容器完整(CPU,内存,磁盘 IO,网络 IO 等)的隔离能力,及 Kubernetes 强大的编排调度能力,实现在线和离线业务混合部署,从而使离在线业务充分利用在线业务空闲时段的资源,以提高资源利用率。

离在线业务混部使用场景

在 Hadoop 架构下,离线作业和在线作业往往分属不同的集群,然而在线业务、流式作业具有明显的波峰波谷特性,在波谷时段,会有大量的资源处于闲置状态,造成资源的浪费和成本的提升。在离线混部集群,通过动态调度削峰填谷,当在线集群的使用率处于波谷时段,将离线任务调度到在线集群,可以显著的提高资源的利用率。然而,Hadoop Yarn 目前只能通过 NodeManager 上报的静态资源情况进行分配,无法基于动态资源调度,无法很好的支持在线、离线业务混部的场景。

TKE 上的离在线混部

在线业务具有明显的波峰浪谷特征,而且规律比较明显,尤其是在夜间,资源利用率比较低,这时候大数据管控平台向 Kubernetes 集群下发创建资源的请求,可以提高大数据应用的算力,详情见 大数据系统云原生渐进式演进最佳实践

如何权衡资源利用率与稳定性

在企业的运维工作中,除了成本,系统的稳定性也是十分重要的指标。如何在两者间达到平衡,可能是很多运维人员心中的“痛点”。一方面,为了降低成本,资源利用率当然是越高越好,但是资源利用率达到一定水位后,负载过高极有可能导致业务 OOM 或 CPU 抖动等问题。
为了减小企业成本控制之路上的顾虑,TKE 还提供了重调度器来保障集群负载水位在可控范围内。重调度器与动态调度器的关系可以参考下图,重调度器主要负责“保护”节点中已经负载比较“危险”的节点,优雅驱逐这些节点上的业务。

TKE 上的重调度器

您可以在扩展组件中安装和使用重调度器,安装组件详情见 DeScheduler 说明

更多关于重调度器的使用指南,可参考《TKE 重磅推出全链路调度解决方案》

目录