【摘要】云原生运维中,可能会经常遇到某个集群看起来明明有很多资源却遭遇调度失败的情况。私有云原生环境,资源总是有限的,提升资源利用率以降低成本始终是需要考虑的问题,减少资源碎片、优化调度配置是提升资源利用率的有效手段。
【作者】汪照辉,专注于容器云、微服务、DevOps、数据治理、数字化转型等领域,对相关技术有独特的理解和见解。擅长于软件规划和设计,提出的“平台融合”的观点越来越得到认同和事实证明。发表了众多技术文章探讨容器平台建设、微服务技术、DevOps、数字化转型、数据治理、中台建设等内容,受到了广泛关注和肯定。
云原生运维实践过程中,可能会经常遇到某个集群看起来明明有很多资源却遭遇调度失败问题。比如说,有个容器request 4C8G 的资源,整个集群剩余的资源可能有几十C上百G,但容器调度却失败了。
什么原因呢?一个集群就是一个资源池,但这个资源池最终还由若干个独立的节点(不管虚拟或物理节点)组成,每个节点都是有一定配置量的资源。所以具体到某个节点时,其资源是有限的,其剩余的资源不足以部署和运行容器服务时,这些剩余的资源就成了资源碎片。节点越多,资源碎片就越多,其累计的量就越大。所以虽然看起来集群有很多资源,却无法成功调度某些容器(资源需求小的容器有可能调度成功,取决于资源碎片大小和容器对资源需求大小)。
这也产生了一个需求,是否可以动态进行资源碎片整理或优化?类似Windows 磁盘的资源碎片整理一样,通过动态调整和迁移容器到合适的节点上,以更有效的使用基础设施资源,提升资源利用率。
资源碎片产生原因
资源碎片是在某些环境中,所有节点或服务器中,每个节点或服务器所剩余的资源不足以部署或调度当前服务或不满足当前服务的资源调度需求,但整体剩余资源总量看起来还很充裕,这些每个节点或服务器所剩余的不足以部署或调度服务的资源,就是资源碎片。
资源充足的情况下,不需要考虑资源碎片问题。但大量的资源空闲,本身就是极大的浪费,因此,通常会使资源使用率达到一定的要求。不过实际的环境中,各种场景需求和各种规格的节点资源配置,会导致大量的资源无法充分利用。特别对GPU资源的使用,如果不合理调度导致大量闲置,其本身的成本就非常高昂,也影响智能化应用的处理效率。因此,通过对资源碎片的关注和分析,是有效优化资源调度和提升资源利用率的前提。
资源碎片产生的原因包括不合理的节点资源配比、碎片化的资源隔离、不合理的服务资源配额、调度算法未能优化等。因此可以关注这几个方面:
1、容器节点的资源配比
容器的重要特性是轻量化、无状态,因此微服务化应用适合在容器中运行。不过,在实际的环境中,业务应用的资源需求规格各不相同,有的Pod 运行需要很少的资源,有的需要很多的资源,有的还需要GPU资源,比如一些模型服务等。而节点资源的配置通常是满足通用需求的,私有化很少会像公有云服务一样配置不同类型和特性的资源以满足特定场景的需求。如果节点资源配比不合理,比如16C 16G 这样一个虚拟节点资源配比,很可能只能运行一个大的Pod 实例( 4C 12G) ,或者调度了几个实例(合计4C 8G)之后,看起来还有不少资源,却无法再调度一个大的P od 实例(3C 10G)。如果一个集群中所有节点都是这样的情况,那么在遇到部署一个大的实例时,就会出现调度失败。因此,节点的资源配比是首先需要考虑的问题。
在具体实践中,通用节点资CPU 和内存源配比大概在1:4-1:5 就好。每个节点不宜配置太低,32C 128G 或 64C 256G 的虚拟配置或96 C 512G的物理服务配置应该是比较合适的。另外,每个容器或容器中的微服务不宜太小,否则 Pod 数会很多,每个节点部署的容器理论上不超过110 个,小Pod 多,资源往往也无法充分利用,特别对于物理机节点,会很浪费。此外,也可能需要考虑不同配置规格的节点,类似不同大小、长短的箱子,方便打包(调度)不同的货物(Pod)。
节点的磁盘空间配置同样很重要。需要考虑日志量、加载镜像文件、可运行的Pod 量等。CPU、内存大的节点,磁盘也需要更大。实际环境中,物理节点可配置2 -4T ssd 盘,虚拟节点800G-1.5T左右磁盘。如果磁盘空间不足,会导致Pod 频繁被驱逐。
此外,在GPU资源管理中,需要实现以GPU卡、虚拟v GPU 为单位的资源隔离方式。GPU节点的GPU 卡数量、配置和其CPU 、内存配置也需要合理。CPU +GPU 异构计算架构是目前的主要方式,如果CPU 和内存配置不合理,也会影响GPU的利用效率。
2、资源隔离
资源隔离有多种不同的实现方式,比如说租户隔离、Namesapce隔离、资源分区(资源组)隔离、集群隔离等。理论上,资源池越大,资源碎片就相对会少,资源使用率相对比较高,不过理论上安全性会降低。隔离的越细,理论上安全性越高,但资源浪费往往就越严重。从云共享的角度考虑,资源不应该隔离,而可以从租户端或应用层进行软隔离。
租户隔离是通过租户账户体系实现的一种虚拟资源隔离方式,租户有自己的独立的系统空间,但底层资源可能是共享的。理论上,租户不用关注自己的服务或应用部署或运行在哪里。不过云原生环境和虚拟化 IaaS 层环境隔离还是不一样,IaaS环境可以通过虚拟机实现安全的隔离,而云原生环境的资源隔离更复杂些,安全性挑战也更大。比如说,两个租户的服务可以运行在一张GPU卡上,但是租户只能看到自己的服务的运行状况,不能看到其他租户的信息,资源的隔离、故障隔离、数据隔离和安全隔离要求就高很多,资源调度管理也复杂很多。如果资源隔离隔离过细,则会导致很多资源无法有效被调度和利用,从而造成浪费。
Namespace 是 K8s 的命名空间,是一种逻辑软隔离方式。命令空间属于K8s 集群,不能跨集群。如果要是实现跨集群管理Namespace ,就需要PaaS 平台能力的扩展和抽象。在实际应用中,Namespace通常映射为租户或应用,从而实现租户层或应用层资源的隔离。分配给Namespace 的空间相当于预留空间,其他租户或应用不能占用已分配的资源。因此Namespace的资源分配通常是根据需求动态调整的,不能一次分配大量的资源闲置。
资源分区是逻辑资源组,在K8s 通常是以节点为单位的资源分组方式。可以定义共享分区和独享分区等,是一种可以实现从节点物理隔离资源的方式。通常尽可能不定义独享分区,除非业务特别重要,否则可能会导致独享分区的资源不好共享,利用效率就相对低。
多集群场景通常是多环境、灾备、高可用等部署需求,以隔离不同的环境。由于集群资源比较多,因此集群往往会部署于不同的数据中心或网络域。
资源碎片调度优化
云原生环境我们关注节点CPU 、内存、磁盘、GPU等的合理配比,以更高效的利用资源。不过合理的资源配比只是第一步,还需要实现动态的资源调度和优化。要实现动态调度和优化,资产资源梳理和调整、优化节点配置是前提,选择指标实现动态监控是就绪准备,然后才能实现资源的动态优化调度。
1、资产资源梳理,查漏补缺
首先需要对云原生环境的资产和资源进行梳理,知道有什么资产、有多少资产,每项资产有多少资源。比如说,传统x86 有几个集群,多少节点,每个节点的CPU 、内存、磁盘、GPU算力、显存等配置,信创x86 、信创ARM等的资产资源等。还需要知道节点的OS、版本、内核版本、节点型号、IP、主机名等信息,以及节点的系统配置如节点最大文件描述符配置、网络端口范围、最大连接数、进程数等。这些配置参数等是进行优化调度的基础。
2、节点配置合理优化
有些节点配置可能不合理,比如利旧的机器配置是64C 64G,对于容器环境来说,内存配置就显的低了。在云原生容器环境,虽然不同的业务对资源需求不一样,但基于实际的资源需求情况看,CPU 和内存1:1的规格配置明显就不是很合理。或者有些机器的磁盘非常小,或者磁盘分区划分不合理,比如/var 分区只有20G ( 容器默认使用/ var/lib/docker 目录 ) ,或根/分区只有50G,这些不合理的配置不但会使容器被驱逐而导致不稳定和业务错误,也无法有效利用资源,因此可能需要适当做些调整。
3、选择指标、动态监控和计算
资产资源实现可见、可观测,并且合理调整完节点配置是有效资源利用的前提。然后需要对资源的使用情况进行监控,需要实时、准确地知道资源的分配、使用和余量及资源使用特点等。比如说节点分配出去的CPU 、内存、GPU 、显存,CPU /内存分配比、CPU 、GPU 、显存实际使用、内存实际使用,DISK剩余空间、节点的TCP 连接数、进程数、Pod 数等等,这些都可以作为优化调度的指标。确定了指标,需要对这些指标进行采集并计算处理。指标数据采集时间间隔很重要,间隔短太频繁会产生性能压力等,间隔太长达不到优化调控的目的,不过还是要基于实际的环境来设定,比如5分钟或者30 分钟。在获取指标数据时,尽可能采用可观测思想,由源端主动发布,目标端监听接收指标数据(这样目标端可以是多个)。也可以使用已采集的数据,例如从prometheus 中获取指标数据,进行二次计算。
这些获取的指标数据需要保存,最好用内存数据库在内存中维护资产资源的运行状况,并对这些指标进行权重设置,动态地统计、排序等。排序是以节点为粒度的,因为pod 的调度是调度到节点上的。同时可能需要维护多个序列,比如按CPU余量节点排序、按内存余量排序、CPU/内存使用均衡比等,从而可以知道节点资源的使用情况。另外需要对节点上运行的服务的资源分配和使用情况进行计算分析,这可能需要至少一周或数周的运行数据,能够比较获得相对规律的统计数据,从而可以设置合适的资源配额,可以动态知晓节点上服务的资源使用和排序,从而在资源不足以调度新pod 时,可以选择合适的pod进行热迁移。
最后可能需要考虑是否启用资源超分机制,如果启用,超分机制如何实现等。超分是提升资源利用率的一种方式,不过也可能会带来一些问题,所以需要谨慎使用。其实总的来说应用服务、资产资源的可观测能力非常重要。
4、调度优化、动态调整
有了响应的指标实时运行数据,就可以动态掌握平台资源的使用状况,按需实现动态调整和优化。资源调度优化是一个并不轻松的工作,资源调度算法有很多种。K8s 提供了两阶段调度策略,但k8s 无法实现动态的资源调度调整,比如说,有一个大的pod 需要调度,但所有节点都不满足这个pod 的资源需求,这就需要平台能够根据节点资源配置、资源使用、节点上的pod 等情况来调度(或热迁移)某个pod到另外的节点以空出足够的资源来调度这个大的pod,从而实现了资源碎片的整理,提升了资源的利用率。
在资源充足的情况下,资源的调度策略也可以设置为均衡调度策略,也是k8s 默认的调度策略。在可分配资源比较紧张时,可以优先采用节点紧凑调度策略,一个节点资源占满后,再调度使用另外一个节点。这样,可以比较好的避免过多的资源碎片。
不过实际的环境需求往往要复杂很多,比如说,应用服务的优先级问题,高优先级服务具备优先使用资源或高性能资源权限,那么低优先级的服务就需要被热迁移或调度到其他资源上运行或peng ding 运行,所以资源的调度策略和算法可能需要根据实际运行状况不断改进和优化。实际生产中,总会遇到这样那样的问题,举例说,节点的tcp 连接未关闭,连接数可能达到最大值了,出现超时、消息丢失等问题,需要不断的总结和持续的改进,才能更好地利用资源,提升资源的利用率。
总结
云作为底座提供基础设施服务,但私有云原生环境,资源总是有限的,提升资源利用率以降低成本始终是需要考虑的问题。减少资源碎片、优化调度配置是提升资源利用率的有效手段。虽然实际的环境要复杂很多,实现起来并不是很容易,不过逐步优化和提升,对云原生环境的资源利用可以提升到一个比较高的程度。