一、前言

得物 App 作为互联网行业的后起之秀,在快速的事务展开过程中根底设施规划不断增加,继而对功率和本钱的关注度也越来越高。咱们在云原生技能上的推动进程如图所示,全体上节奏仍是比较快的。

得物云原生容器技能探究与落地实践

从 2021 年 8 月开端,咱们以进步资源运用率和资源交给功率为方针,开端依据云原生技能建造整个服务体系的高可用性、可观测性和高运维功率,一起要确保本钱可控。在容器化过程中咱们遇到了许多的应战,包括:怎么将存量的服务在保持已有研制流程不变的情况下,做到容器化布置和办理;容器化之后怎么做到高效地运维;怎么针对不同的事务场景,供给不同的容器化计划等等。此外,经过技能手法完成持续的本钱优化是咱们的长时刻方针,咱们先后建造落地了画像体系、混部计划和调度优化等计划。本文把得物在推动云原生容器技能落地过程中相关计划和实践做一些总结和收拾,欢迎阅览和沟通。

二、云原生运用办理

云原生运用办理办法

容器与 ECS 的资源形状是有差异的,所以会形成在办理流程上也会有不同之处。可是为了尽或许下降容器化带来的运用体验上的差异,咱们参阅业界容器运用 OAM 模型的规划形式,对容器的相关概念做了屏蔽和对等解说。例如:以“运用集群”的概念代表 CloneSet 作业负载(Kruise 供给的一种 Kubernetes 扩展作业负载);将单个 Pod 约好为一个运用集群的实例;以“运用路由/域名装备”的概念代表针对 Ingress/Service 的设置。

在运用集群的构造上(即怎么构造出 Kubernetes 作业负载方针),咱们规划了“装备/特征分层”的计划,将一个运用集群所在归属的运用、环境组、环境上的装备进行叠加后,运用 Helm 工具渲染生成 Kubernetes 资源方针,提交给容器渠道。

得物云原生容器技能探究与落地实践

CI 和 CD 过程均运用这种装备/特征分层的办法,一方面能够处理运用依靠的中间件信息的办理问题(由相应的供给者一致维护);另一方面,这种办理办法能够让中间件组件/服务改动时依照不同维度进行,全体上下降了装备改动带来的危险。

Sidecar 容器在运用集群实例中除了扮演“协作者”的人物外,咱们还依据它做了权限办理,以便对应在 ECS 形状下的不同用户的登陆权限,也算是一箭双雕。当然,在容器场景下也是能够界说不同的用户,赋予不同的人物,可是强依靠根底镜像的维护。

得物云原生容器技能探究与落地实践

多集群办理计划

云原生场景下的处理计划对运用集群而言自身便是高可用的,比方:容器编排引擎 Kubernetes 中支撑 Pod 实例的拓扑散布设置、支撑可用区设置、副本数设置、 Service 负载均衡的规划等,这些都能确保运用集群的高可用。那假如单个 Kubernetes 集群不行用了,会有什么的影响呢,该怎么处理?多集群办理计划便是咱们处理 Kubernetes 的可用性问题的思路。

假如 Kubernetes 操控面不行用了,会导致运用发布受损,较严峻的情况也会影响容器服务的可用性。所以,为了确保 Kubernetes 的可用性,一方面要确保 Kubernetes 各组件的强健性,另一方面要适当操控单个 Kubernetes 集群的规划,防止集群过大形成体系性危险升高。咱们的处理思路便是“不要把鸡蛋放在一个篮子里”,用联邦的办法办理多个 Kubernetes,将事务分散到不同的 Kubernetes 集群。

联邦的思维在 Kubernetes 诞生不久就被开端评论,逐渐规划完成,从最初社区的 KubeFate V1.0 到 V2.0,再到企业开源的 Karmada、KubeAdmiral 逐渐成熟起来,并实践运用到了出产场景。那假如没有集群联邦,多个 Kubernetes 集群就没法办理了吗?当然不是的,容器管控渠道其实也能做这件事情,笔者在几年之前还对此深认为然,但现在已经彻底改动观点了。由于在实践的出产落地过程中咱们发现,比较在管控顶用 if…else/switch 的办法,亦或装备的办法比较,依据 CRD 的办法来办理多集群功率更高、逻辑更清晰。

得物云原生容器技能探究与落地实践
得物云原生容器技能探究与落地实践

得物在运用联邦思维办理多 Kubernetes 集群的时分,参阅华为开源的 Karmada 处理计划,在此根底之上做了定制开发。容器管控渠道担任办理运用集群的原始特征和装备,办理 CICD 流程,向 Host Kubernetes 集群发起容器方针管控请求。Host Kubernetes 集群经过 PropagationPolicies 办理作业负载怎么分发到 Member Kubernetes 集群,经过 OverridePolicies 办理差异化的装备。单 Kubernetes 集群下咱们运用了分批发布的办法来办理运用集群的发布,在引入联邦办理之后,咱们把分批发布的逻辑从容器管控层面下移到了 Host Kubernetes 集群上。为了兼容存量的经过 Kubernetes Service 进行调用的服务,咱们在 Member Kubernetes 集群经过自界说的 MCS-Controller 来办理跨集群的 Service/Endpoints 方针,在 Host Kubernetes 层经过 MCS-Validator 做两层校验,确保跨集群的 Service 的一致性。

三、容器调度优化与混部

落地云原生容器技能的方针是希望在敏捷、弹性和可用的根底上,最终完成资源运用率上的进步、本钱上的节省。这一般有 2 个完成途径,一个是经过技能的手法,另一个则是经过办理办法。本章要点介绍咱们在容器精细化调度和混部实践方面的技能计划规划和落地过程。

运用画像

运用服务的研制人员在布置运用集群实例时,一般会请求超越运用集群自身承载事务流量时所要耗费的资源量,这是能够了解的(要确保体系的资源运用率安全水位,防止过载形成体系夯住),可是不同的研制人员对这个“度”把握是不一样的,由于合理地设置运用集群的资源用量是依靠研制人员经验的,也便是说主观性会更强。

为了处理上述问题,业界的做法一般是经过剖析运用集群的过往资源运用率数据,来刻画出运用集群在事务流量下的实践资源运用率曲线,这便是运用画像。如下图所示是咱们建造的画像体系的架构框图,该画像体系不仅担任运用的画像剖析,也担任宿主机、Kubernetes 集群的画像剖析,用来辅导整个容器渠道对资源的办理。

得物云原生容器技能探究与落地实践

容器的监控数据经过 Prometheus 计划进行收集和办理,自研的 KubeRM 服务将它作为数据源,周期性核算产出运用画像、宿主机画像和 Kubernetes 集群画像(资源池画像)。容器渠道布置在线服务服务时,可参阅画像值来装备运用集群的资源规范,这儿的画像值便是指 Pod 的 Request 值,核算公式如下:

Pod Request = 方针周期性运用率 / 安全水位

公式中“方针周期性运用率”是画像体系经过统计学手法、AI 模型等办法核算剖析出的资源方针(CPU/内存/GPU显存)在实践事务流量下所表现出的周期性的规律。画像值的收效咱们经过以下 4 个战略进行实施:

  • 针对 P3/P4 等级的服务,默许在服务布置时收效画像值。
  • 针对非 P3/P4 等级的服务,将画像值推荐给用户,由用户决议布置时是否采用画像。
  • 分资源池设置不同的收效战略(默许收效,或许用户决议收效)。
  • GPU 显存的画像不做默许收效,推荐给用户,让用户决议。

交由用户决议画像是否收效时,怎么让用户更倾向于去收效画像呢?咱们运用差异化计费的战略:收效了画像的运用集群实例依照其 Pod 装备的 Request 值计费,未收效画像的运用集群实例依照其 Pod 装备的 Limit 值计费。用户能够依据自己服务的实践情况选择收效画像,以下降本钱;渠道也由于画像而拿到了更多能够调度的资源,用于其它更多的场景。

此外,画像体系也接入了 KubeAutoScale 主动弹性器,在事务低峰期,能够辅导主动弹性器对部分场景在线服务做副本缩容操作,以便开释出更多的资源供给其它场景运用(比方:混部使命场景),后边的章节会具体介绍。

资源预占

当整个容器集群的资源冗余量不是很足够的时分,在以下几种情况下是会呈现 “虽然集群层面总量资源是够的,可是事务 Pod 却无法调度”的问题,影响事务发布功率和体验。

  • 在集群中容器实例改动比较频频的时分,某个大规范的事务集群在做翻滚更新时,开释的旧的实例很或许被小规范的容器实例所抢占,导致无法调度。
  • 研制同学担任 2 个运用服务 A 和 B,它们的规范都是一样的。为了确保全体本钱不变会,选择将 A 服务的实例缩掉一些,然后扩容 B 服务的实例。由于 Kubernetes 默许调度会依照 Pod 创立时刻来依次调度新 Pod,当用户缩容完 A 服务的实例再去扩容 B 服务实例的时分,A 服务开释的资源很或许被其他容器实例抢占,导致 B 的实例无法调度。
  • 在大促、全链路压测等事务需求紧急扩容的情况下,容器渠道会新扩宿主机节点以满意事务需求,不曾想新扩容的机器资源却被那些“小而快(拉起频频,履行时刻短)”的使命给见缝插针地抢占了,一方面会导致大规范的服务实例无法调度,另一方面还形成了较多的资源碎片。

为了处理以上问题,咱们在调度器中自界说完成了资源预占的调度插件(经过 CRD 界说资源预占希望,影响调度决议计划),用来进步用户体验和进步调度功率。

得物云原生容器技能探究与落地实践
得物云原生容器技能探究与落地实践

平衡调度

为了更好地平衡集群中节点的水位,以防止过热节点的呈现、尽量削减碎片资源等为方针来思考和规划,咱们依据 Kubernetes 供给的调度器扩展结构,自界说完成了多个调度插件:

  • CoolDownHotNode 插件:给最近调度过 Pod 的节点下降优先级,防止热点节点
  • HybridUnschedulable 插件:阻止运用弹性资源的 Pod 调度到某些节点上。
  • NodeBalance 插件:用于平衡各节点上 CPU Request 值与画像的比值,平衡各节点 CPU 运用率。
  • NodeInfoRt 插件:依据画像打分数据和实时打分数据优化 Pod 调度。

在实时混部

从本年 1 月份开端,咱们着手做在离线混部的落地,一期的方针着眼于将在线服务与 Flink 使命进行混部。之所以选择 Flink 使命做混部,是由于它与在线服务有一个相似之处,那便是它是一种常驻的离线使命,在它发动之后假如没有特别情况,一般不会下线,这种特质会使得咱们的容器集群调度频次、Pod 的改动程度会低一些,进而对稳定性的应战也会小一点,全体混部危险也会低一些。

在没有混部的情况下,咱们的集群全体运用率较低,即便画像功用能协助用户尽或许合理的为自己的服务实例设置资源规范,但对容器渠道而言这仍然很被动。所认为了挖掘出能够用来混部的资源,咱们为不同等级的服务设置不同的绑核战略。如下表所示界说了 4 种运用类型(LSX、LSR、LS、BE),适用于 P0~P4 范围和离线使命,绑核战略从彻底绑核到部分绑核,再到彻底同享。

得物云原生容器技能探究与落地实践

离线使命(Flink 使命)归于 BE 类型,能够运用的资源是在宿主机一切 CPU 中心里面单独区分出来的一部分专用 CPU 中心,再加上 LS 的同享 CPU 中心,以及 LSR、LS 类型的运用上同享出来的部分 CPU 中心。

得物云原生容器技能探究与落地实践

LSX、LSR 和 LS 类型的运用服务的容器实例均请求运用 Kubernetes 原生的资源 CPU/Memory 资源;BE 类型的使命需求请求运用咱们自界说的资源 BE-CPU/BE-Memory 资源。

得物云原生容器技能探究与落地实践

依据 Kubernetes 的 Device-Plugin 机制咱们自研完成了 Kube-Agent 组件,该组件在集群中的一切节点上以 Damonset 的办法布置,一方面担任依据自界说战略将本节点上可用的 BE 资源上报给 API-Server(经过 Kubelet 组件间接上报),另一方面担任履行 CPU 绑核操作。跟着混部的深入,该组件也承担了更多的作业界容(例如:履行 CPU 算力约束操作、参数动态调整操作,履行 VPA 操作等)。

在离线混部

一期的混部在运用级别区分的根底上,运用了 CPU 核区分战略来完成混部。站在 CPU 中心的角度来看,经过 CPU 核区分战略之后,每个 CPU 中心已经有了自己的负载归属,能否充分运用取决于分配到它上面的事务特性。但站在整机的运用率上来看(或许站在整个集群的运用率角度来看),仍然有很大的进步的空间。混部二期的时分,咱们考虑对BE资源进行二次超卖,以另一种新的自界说资源(OT 资源)进行分配运用。运用 OT 资源的使命不独占绑核,而是同享区分给 BE 资源的一切 CPU 中心。

得物云原生容器技能探究与落地实践

咱们运用 OT 资源来混部 AI 练习使命、其它数据处理使命,为了消除练习使命对在线事务的影响,经过以下战略进行确保:

  • 设置宿主机安全水位,经过调度插件防止过热节点呈现。
  • 经过 CPU Group Identity 进行优先级竞赛,保证离线使命的调度优先级绝对低于在线服务。
  • 对离线使命进行独立挂盘,防止影响在线服务的磁盘 IO。
  • 夜间时段经过 KubeAutoScaler 进行对在线服务进行弹性缩容,等份额进步内存的空闲率,保证离线使命有足够的内存资源。

弹性弹性

容器渠道的弹功用力相较于传统 IDC 资源办理形式、ECS 资源办理办法的要更上一个台阶,由于它更侧重将弹性弹性的决议计划权交给运用服务,而不是资源办理方。云原生技能中常说的弹性弹性计划一般包括2种办法:

  • HPA:Horizontal Pod Autoscaling,水平方向的 Pod 副本扩缩容。
  • VPA:Vertical Pod Autoscaling,笔直方向的 Pod 规范扩缩容。

Kubernetes 中经过资源方针 HorizontalPodautoScalers 来支撑作业负载的水平扩缩容,在较早的版别中只支撑 CPU 和内存这两个资源方针,较新版别中也开端支撑自界说方针了。针对 VPA 的需求,现在 Kubernetes 层面还没有比较稳定的可用功用,由于对一个 Pod 实例做资源规范的调整,会涉及到宿主机上资源账本的办理问题、监控问题,也会涉及到 Pod 的重建/容器重发动作,影响面会比较大,现在社区中仍然在评论。但企业在 VPA 方面,也都是跃跃欲试,会规划自己的个性化 VPA 计划,本文前述运用画像功用,便是咱们得物在 VPA 计划上探究的第一步。

此外,咱们在实践的支撑事务云原生化转型过程中发现,与经过服务的资源运用率方针来协助事务来决议计划服务实例副本数的调整的办法比较,守时扩缩容反而能让研制同学更有信心,研制同学能够依据自己担任的事务服务的流量特征,来设置守时地缩容或许扩容自己的服务实例数量。

为了满意弹性弹性场景的一切需求,咱们规划完成了 KubeAutoScaler 组件,用来一致办理 HPA、VPA、守时弹性等弹性弹性战略装备。此外,如前所述,该组件与画像体系相互协作,在混部场景下能够协助在夜间对部分低流量的服务做缩容操作,开释更多的资源供离线使命运用。

弹性弹性计划在 GPU 服务场景帮咱们防止了许多的资源浪费,特别是在测验环境。如图所示,咱们为 GPU 服务注入了一个名为 Queue-Proxy 的 Sidecar 容器,用来收集服务流量,当流量低于某个阈值时,会依照份额削减实例数;当流量为 0 并持续了一段时刻之后,会彻底缩零。当冷发动时,请求会经过激活器 Activator,激活器再告诉 KubeAutoScaler 进行服务扩容。出产环境的部分服务也开启了这一套机制,但在流量低峰期不会彻底缩容至零,会维持一个最小的副本数。

得物云原生容器技能探究与落地实践

四、容器资源和本钱办理优化

为了更好地进步全体的资源运用、下降根底设施本钱,与技能计划的落地周期长、复杂度高的特色比起来,经过办理办法往往能在较短时刻内到达不错的作用,特别是在运用服务容器化布置改造进行到后期的时分。咱们经过以下 5 个方面的办理实践,降本作用显着。

机型替换

由于前史原因,咱们的模型推理服务在刚开端的时分运用的是 V100 的机型,该机型显存较大、GPU 算力较优,更合适用在练习场景,在推理场景的话有点大材小用了。经过机型比照剖析,咱们选用了一个性价比较高的 A10 机型,推理服务的本钱全体下降了 20% 左右,并且由于 A10 机型配备的 CPU 架构有升级,对前后处理有较高要求的推理服务而言稳定性和功用均有进步。从 V100 切换到 A10,主要的作业在于根底镜像的替换,由于部分模型服务或许运用了较低版别的 CUDA,可是 A10 卡的算力需求配备较高的 CUDA。另外,由于两种卡的 GPU 算力也是有差异的,替换之后需求对推理结果做比照验证才能够上线。咱们依据流量回放的思路,规划了 AB 实验功用协助事务做切换测验。

得物云原生容器技能探究与落地实践

在运用 CPU 核算资源的场景上,咱们对算力要求一般、对 CPU 指令集因无特别要求、对单核/多核功用无要求的服务,均将其运用的机型从 Intel 的切换到了 AMD 的,全体本钱下降 14% 左右。

资源池办理

不得不供认的是容器化初期事务方是占据主动的,事务侧会依据稳定性、资源供给量上的考量要求容器渠道独立建集群,或许资源池,容器渠道也会选择粗豪式办理而应承这些需求。跟着容器化的推动,事务侧的信心也会增强,容器渠道对资源的把控程度也会更好,咱们逐渐采取以下几个动作来收敛资源的办理,进步全体的资源分配率:

  • 冗余量操控:事务的发布是有周期的,咱们会依据发布周期,动态调整容器渠道办理的资源冗余量。在确保日常的迭代开发的一起,尽或许缩小冗余量。
  • 集群兼并:一致规划 Kubernetes 集群,依照区域(上海、杭州、北京等)、网络环境类型(测验、预发、出产)、事务形状(一般事务、中间件、根底设施、管控集群等)等维度评论和决议计划,下线不必要的集群。
  • 资源池兼并、规整机型:兼并资源需求特征比较附近的资源池(例如:核算型的、内存型的),选择合适的机型。与事务沟通,下线或许兼并运用率过低的小资源池。
  • 碎片收拾:单靠调度器的优化,在调度时尽或许防止碎片力气有限。加上在线服务的改动频率一般比较低,假如不做重调度,长时刻累积下来,集群中会存在大量碎片。所以,针对多副本的运用集群,在强健的高雅停机机制根底上,咱们适当进行了一些碎片收拾使命(重建 Pod 自由调度、重调度、宿主机腾挪等),有效地削减了资源碎片。

作业负载规范办理

用户自界说作业负载的规范在云原生场景下也是一个常用的做法,这看似对用户友好的做法却对容器渠道形成了一些应战,由于假如对用户设置规范的自由度不做一些约束,很或许呈现一些非常不合理的规范设置(例如:6C120G、20C4G),会产生调度碎片、本钱分摊核算规范也难一致。

为了处理规范的问题,咱们对在线服务的资源规范做了约束,不允许用户随意指定,而是由渠道给出规范列表,由用户选择运用。规范列表能够分资源池规划、也能够分事务场景设置。针对使命型的作业负载,咱们界说了 3 种 CPU 类型的资源规范(一般型、核算型、内存型,别离对应不同的 CPU:内存份额)。针对特别的使命需求,咱们约好了资源规范当中 CPU:内存的范围。针对运用 GPU 的使命,因每种 GPU 卡的 CPU/内存/显存规范配比都是不一样的,咱们界说了针对每种 GPU 卡的 CU 单位,用户只需求选择相应的 CU,填写 CU 数量即可。规范约好之后,咱们针对不同的规范做了差异化计费,确保了规范请求和本钱分摊上的合理性。关于规范的界说和计费规范,详见下表。

得物云原生容器技能探究与落地实践

产品自建

得物的根底设施是在云上,所以在事务展开过程中,部分服务才能咱们是会直接选用云上产品的。算法侧的模型练习使命,最开端的时分便是选用云上产品,跟着容器化的推动,咱们自建的 AI 渠道(KubeAI 渠道)逐渐接受模型练习使命,使得练习使命的本钱大幅下降。

自建 KubeAI 渠道,使得咱们将练习运用的资源与在线服务、其它离线使命场景运用的资源纳入了一致的办理体系,便于从大局的视角去合理地调度分配资源,为 AI 模型练习场景拿到更多的可用资源。本文前述 2.5 末节,咱们便是经过混部的办法,将在线服务的资源供给了练习使命运用,当时已经在常态混部。

得物云原生容器技能探究与落地实践

多云战略

作为云上用户,多云战略是咱们的长时刻方针。在多云之间取得议价主动权、符合合规性要求、取得更足够的资源供给。尤其本年 4 月份以来,跟着 GPT/AIGC 方面的爆发、方针因素导致单个云商的 GPU 资源对咱们供给不足,阻止事务展开。咱们及时采用多云战略,将 GPU 事务分散到不同的云供货商,保证事务正常展开。当然,多云的接入不是一蹴而就的,而是需求分事务场景逐渐推动,周期较长,难度较大,咱们需求考虑以下问题:

  • 收拾事务,找到合适多云的事务场景,或许找到合适在多云之间灵活迁移的事务场景。
  • 因不同云供应上的机房或许在不同的区域,所以需求考虑跨地域服务访问、中间件依靠问题。
  • 跨云供货商的数据访问和传输问题,涉及到专线建造、本钱问题。

五、云原生AI场景建造

咱们希望云原生容器技能的落地是要掩盖全场景的,要将云原生技能在一般服务、中间件产品和特别的事务场景上都能发挥其巨大优势。现在 MySQL、Redis、Miluvs、ElasticSearch 等产品都已经在推动容器化。云原生 AI 场景的建造,咱们经过 KubeAI 渠道的建造在持续推动。

得物云原生容器技能探究与落地实践

KubeAI 是得物 AI 渠道,是咱们将云原生容器技能落地得物全站事务过程中,逐渐收集和挖掘公司各事务域在AI模型研讨和出产迭代过程中的需求,逐渐建造而成的一个云原生 AI 渠道。KubeAI 以模型为主线供给了从模型开发,到模型练习,再到推理(模型)服务办理,以及模型版别持续迭代的整个生命周期内的处理计划。此外,跟着 AIGC 的火热展开,咱们经过调研公司内部 AI 辅助出产相关需求,上线了 AIGC/GPT 服务,为得物丰富的事务场景供给了 GAI 才能,助力事务作用进步。关于 KubeAI 渠道相关处理计划,咱们之前发布过一些文章,欢迎大家阅览沟通,这儿不再赘述。

六、展望

云原生容器技能在得物的落地展开仍是比较快的,事务掩盖面也比较广泛。经过 2 年时刻的实践落地,已经全面深入资源办理体系、预算/本钱办理机制、运用服务发布流程、AI 算法等办理体系和事务场景。接下来:

  • 在容器化,咱们会持续推动中间件产品的容器化,进一步进步根底设施的资源功率。
  • 咱们会持续巩固混部计划,持续探究弹性容量、调度优化等计划,进一步进步资源功率。
  • 在稳定性方面,咱们会持续关注容器渠道/Kubernetes 自身的稳定性建造,防备危险,切实确保事务平稳运行。
  • 与事务场景一起探究快速接入多云,以及多云之间的快速切换才能,保证事务规划在持续增加的情况下,容器根底设施切换灵活、安如磐石。

*文/weidong

本文属得物技能原创,更多精彩文章请看:得物技能官网

未经得物技能许可禁止转载,否则依法追究法律责任!