得物云原生容器技術(shù)探索與落地實(shí)踐
一、前言
得物 App 作為互聯(lián)網(wǎng)行業(yè)的后起之秀,在快速的業(yè)務(wù)發(fā)展過(guò)程中基礎(chǔ)設(shè)施規(guī)模不斷增長(zhǎng),繼而對(duì)效率和成本的關(guān)注度也越來(lái)越高。我們?cè)谠圃夹g(shù)上的推進(jìn)歷程如圖所示,整體上節(jié)奏還是比較快的。
圖片
從 2021 年 8 月開(kāi)始,我們以提升資源使用率和資源交付效率為目標(biāo),開(kāi)始基于云原生技術(shù)建設(shè)整個(gè)服務(wù)體系的高可用性、可觀測(cè)性和高運(yùn)維效率,同時(shí)要保證成本可控。在容器化過(guò)程中我們遇到了很多的挑戰(zhàn),包括:如何將存量的服務(wù)在保持已有研發(fā)流程不變的情況下,做到容器化部署和管理;容器化之后如何做到高效地運(yùn)維;如何針對(duì)不同的業(yè)務(wù)場(chǎng)景,提供不同的容器化方案等等。此外,通過(guò)技術(shù)手段實(shí)現(xiàn)持續(xù)的成本優(yōu)化是我們的長(zhǎng)期目標(biāo),我們先后建設(shè)落地了畫(huà)像系統(tǒng)、混部方案和調(diào)度優(yōu)化等方案。本文把得物在推進(jìn)云原生容器技術(shù)落地過(guò)程中相關(guān)方案和實(shí)踐做一些總結(jié)和梳理,歡迎閱讀和交流。
二、云原生應(yīng)用管理
云原生應(yīng)用管理方式
容器與 ECS 的資源形態(tài)是有差異的,所以會(huì)造成在管理流程上也會(huì)有不同之處。但是為了盡可能降低容器化帶來(lái)的使用體驗(yàn)上的差異,我們參考業(yè)內(nèi)容器應(yīng)用 OAM 模型的設(shè)計(jì)模式,對(duì)容器的相關(guān)概念做了屏蔽和對(duì)等解釋。例如:以“應(yīng)用集群”的概念代表 CloneSet 工作負(fù)載(Kruise 提供的一種 Kubernetes 擴(kuò)展工作負(fù)載);將單個(gè) Pod 約定為一個(gè)應(yīng)用集群的實(shí)例;以“應(yīng)用路由/域名配置”的概念代表針對(duì) Ingress/Service 的設(shè)置。
在應(yīng)用集群的構(gòu)造上(即如何構(gòu)造出 Kubernetes 工作負(fù)載對(duì)象),我們?cè)O(shè)計(jì)了“配置/特征分層”的方案,將一個(gè)應(yīng)用集群所處歸屬的應(yīng)用、環(huán)境組、環(huán)境上的配置進(jìn)行疊加后,使用 Helm 工具渲染生成 Kubernetes 資源對(duì)象,提交給容器平臺(tái)。
圖片
CI 和 CD 過(guò)程均使用這種配置/特征分層的方式,一方面可以解決應(yīng)用依賴的中間件信息的管理問(wèn)題(由相應(yīng)的提供者統(tǒng)一維護(hù));另一方面,這種管理方式可以讓中間件組件/服務(wù)變更時(shí)按照不同維度進(jìn)行,整體上降低了配置變更帶來(lái)的風(fēng)險(xiǎn)。
Sidecar 容器在應(yīng)用集群實(shí)例中除了扮演“協(xié)作者”的角色外,我們還基于它做了權(quán)限管理,以便對(duì)應(yīng)在 ECS 形態(tài)下的不同用戶的登陸權(quán)限,也算是一舉兩得。當(dāng)然,在容器場(chǎng)景下也是可以定義不同的用戶,賦予不同的角色,但是強(qiáng)依賴基礎(chǔ)鏡像的維護(hù)。
圖片
多集群管理方案
云原生場(chǎng)景下的解決方案對(duì)應(yīng)用集群而言本身就是高可用的,比如:容器編排引擎 Kubernetes 中支持 Pod 實(shí)例的拓?fù)浞植荚O(shè)置、支持可用區(qū)設(shè)置、副本數(shù)設(shè)置、 Service 負(fù)載均衡的設(shè)計(jì)等,這些都能保證應(yīng)用集群的高可用。那如果單個(gè) Kubernetes 集群不可用了,會(huì)有什么的影響呢,該如何解決?多集群管理方案就是我們解決 Kubernetes 的可用性問(wèn)題的思路。
如果 Kubernetes 控制面不可用了,會(huì)導(dǎo)致應(yīng)用發(fā)布受損,較嚴(yán)重的情況也會(huì)影響容器服務(wù)的可用性。所以,為了保證 Kubernetes 的可用性,一方面要保證 Kubernetes 各組件的健壯性,另一方面要適當(dāng)控制單個(gè) Kubernetes 集群的規(guī)模,避免集群過(guò)大造成系統(tǒng)性風(fēng)險(xiǎn)升高。我們的解決思路就是“不要把雞蛋放在一個(gè)籃子里”,用聯(lián)邦的方式管理多個(gè) Kubernetes,將業(yè)務(wù)分散到不同的 Kubernetes 集群。
聯(lián)邦的思想在 Kubernetes 誕生不久就被開(kāi)始討論,逐步設(shè)計(jì)實(shí)現(xiàn),從最初社區(qū)的 KubeFate V1.0 到 V2.0,再到企業(yè)開(kāi)源的 Karmada、KubeAdmiral 逐漸成熟起來(lái),并實(shí)際應(yīng)用到了生產(chǎn)場(chǎng)景。那如果沒(méi)有集群聯(lián)邦,多個(gè) Kubernetes 集群就沒(méi)法管理了嗎?當(dāng)然不是的,容器管控平臺(tái)其實(shí)也能做這件事情,筆者在幾年之前還對(duì)此深以為然,但現(xiàn)在已經(jīng)完全改變看法了。因?yàn)樵趯?shí)際的生產(chǎn)落地過(guò)程中我們發(fā)現(xiàn),相比在管控中用 if...else/switch 的方式,亦或配置的方式相比,基于 CRD 的方式來(lái)管理多集群效率更高、邏輯更清晰。
圖片
圖片
得物在使用聯(lián)邦思想管理多 Kubernetes 集群的時(shí)候,參考華為開(kāi)源的 Karmada 解決方案,在此基礎(chǔ)之上做了定制開(kāi)發(fā)。容器管控平臺(tái)負(fù)責(zé)管理應(yīng)用集群的原始特征和配置,管理 CICD 流程,向 Host Kubernetes 集群發(fā)起容器對(duì)象管控請(qǐng)求。Host Kubernetes 集群通過(guò) PropagationPolicies 管理工作負(fù)載如何分發(fā)到 Member Kubernetes 集群,通過(guò) OverridePolicies 管理差異化的配置。單 Kubernetes 集群下我們使用了分批發(fā)布的方式來(lái)管理應(yīng)用集群的發(fā)布,在引入聯(lián)邦管理之后,我們把分批發(fā)布的邏輯從容器管控層面下移到了 Host Kubernetes 集群上。為了兼容存量的通過(guò) Kubernetes Service 進(jìn)行調(diào)用的服務(wù),我們?cè)?Member Kubernetes 集群通過(guò)自定義的 MCS-Controller 來(lái)管理跨集群的 Service/Endpoints 對(duì)象,在 Host Kubernetes 層通過(guò) MCS-Validator 做雙重校驗(yàn),確??缂旱?Service 的一致性。
三、容器調(diào)度優(yōu)化與混部
應(yīng)用畫(huà)像
應(yīng)用服務(wù)的研發(fā)人員在部署應(yīng)用集群實(shí)例時(shí),通常會(huì)申請(qǐng)超過(guò)應(yīng)用集群本身承載業(yè)務(wù)流量時(shí)所要消耗的資源量,這是可以理解的(要確保系統(tǒng)的資源利用率安全水位,防止過(guò)載造成系統(tǒng)夯?。遣煌难邪l(fā)人員對(duì)這個(gè)“度”把握是不一樣的,因?yàn)楹侠淼卦O(shè)置應(yīng)用集群的資源用量是依賴研發(fā)人員經(jīng)驗(yàn)的,也就是說(shuō)主觀性會(huì)更強(qiáng)。
為了解決上述問(wèn)題,業(yè)內(nèi)的做法通常是通過(guò)分析應(yīng)用集群的過(guò)往資源利用率數(shù)據(jù),來(lái)刻畫(huà)出應(yīng)用集群在業(yè)務(wù)流量下的實(shí)際資源利用率曲線,這就是應(yīng)用畫(huà)像。如下圖所示是我們建設(shè)的畫(huà)像系統(tǒng)的架構(gòu)框圖,該畫(huà)像系統(tǒng)不僅負(fù)責(zé)應(yīng)用的畫(huà)像分析,也負(fù)責(zé)宿主機(jī)、Kubernetes 集群的畫(huà)像分析,用來(lái)指導(dǎo)整個(gè)容器平臺(tái)對(duì)資源的管理。
圖片
容器的監(jiān)控?cái)?shù)據(jù)通過(guò) Prometheus 方案進(jìn)行采集和管理,自研的 KubeRM 服務(wù)將它作為數(shù)據(jù)源,周期性計(jì)算產(chǎn)出應(yīng)用畫(huà)像、宿主機(jī)畫(huà)像和 Kubernetes 集群畫(huà)像(資源池畫(huà)像)。容器平臺(tái)部署在線服務(wù)服務(wù)時(shí),可參考畫(huà)像值來(lái)配置應(yīng)用集群的資源規(guī)格,這里的畫(huà)像值就是指 Pod 的 Request 值,計(jì)算公式如下:
Pod Request = 指標(biāo)周期性利用率 / 安全水位
公式中“指標(biāo)周期性利用率”是畫(huà)像系統(tǒng)通過(guò)統(tǒng)計(jì)學(xué)手段、AI 模型等方法計(jì)算分析出的資源指標(biāo)(CPU/內(nèi)存/GPU顯存)在實(shí)際業(yè)務(wù)流量下所表現(xiàn)出的周期性的規(guī)律。畫(huà)像值的生效我們通過(guò)以下 4 個(gè)策略進(jìn)行實(shí)施:
- 針對(duì) P3/P4 等級(jí)的服務(wù),默認(rèn)在服務(wù)部署時(shí)生效畫(huà)像值。
- 針對(duì)非 P3/P4 等級(jí)的服務(wù),將畫(huà)像值推薦給用戶,由用戶決定部署時(shí)是否采用畫(huà)像。
- 分資源池設(shè)置不同的生效策略(默認(rèn)生效,或者用戶決定生效)。
- GPU 顯存的畫(huà)像不做默認(rèn)生效,推薦給用戶,讓用戶決定。
交由用戶決定畫(huà)像是否生效時(shí),如何讓用戶更傾向于去生效畫(huà)像呢?我們使用差異化計(jì)費(fèi)的策略:生效了畫(huà)像的應(yīng)用集群實(shí)例按照其 Pod 配置的 Request 值計(jì)費(fèi),未生效畫(huà)像的應(yīng)用集群實(shí)例按照其 Pod 配置的 Limit 值計(jì)費(fèi)。用戶可以根據(jù)自己服務(wù)的實(shí)際情況選擇生效畫(huà)像,以降低成本;平臺(tái)也因?yàn)楫?huà)像而拿到了更多可以調(diào)度的資源,用于其它更多的場(chǎng)景。
此外,畫(huà)像系統(tǒng)也接入了 KubeAutoScale 自動(dòng)伸縮器,在業(yè)務(wù)低峰期,可以指導(dǎo)自動(dòng)伸縮器對(duì)部分場(chǎng)景在線服務(wù)做副本縮容操作,以便釋放出更多的資源供給其它場(chǎng)景使用(比如:混部任務(wù)場(chǎng)景),后面的章節(jié)會(huì)詳細(xì)介紹。
資源預(yù)占
當(dāng)整個(gè)容器集群的資源冗余量不是很充足的時(shí)候,在以下幾種情況下是會(huì)出現(xiàn) “雖然集群層面總量資源是夠的,但是業(yè)務(wù) Pod 卻無(wú)法調(diào)度”的問(wèn)題,影響業(yè)務(wù)發(fā)布效率和體驗(yàn)。
- 在集群中容器實(shí)例變更比較頻繁的時(shí)候,某個(gè)大規(guī)格的業(yè)務(wù)集群在做滾動(dòng)更新時(shí),釋放的舊的實(shí)例很可能被小規(guī)格的容器實(shí)例所搶占,導(dǎo)致無(wú)法調(diào)度。
- 研發(fā)同學(xué)負(fù)責(zé) 2 個(gè)應(yīng)用服務(wù) A 和 B,它們的規(guī)格都是一樣的。為了保證總體成本不變會(huì),選擇將 A 服務(wù)的實(shí)例縮掉一些,然后擴(kuò)容 B 服務(wù)的實(shí)例。因?yàn)?Kubernetes 默認(rèn)調(diào)度會(huì)按照 Pod 創(chuàng)建時(shí)間來(lái)依次調(diào)度新 Pod,當(dāng)用戶縮容完 A 服務(wù)的實(shí)例再去擴(kuò)容 B 服務(wù)實(shí)例的時(shí)候,A 服務(wù)釋放的資源很可能被其他容器實(shí)例搶占,導(dǎo)致 B 的實(shí)例無(wú)法調(diào)度。
- 在大促、全鏈路壓測(cè)等業(yè)務(wù)需要緊急擴(kuò)容的情況下,容器平臺(tái)會(huì)新擴(kuò)宿主機(jī)節(jié)點(diǎn)以滿足業(yè)務(wù)需求,不曾想新擴(kuò)容的機(jī)器資源卻被那些“小而快(拉起頻繁,執(zhí)行時(shí)間短)”的任務(wù)給見(jiàn)縫插針地?fù)屨剂?,一方面?huì)導(dǎo)致大規(guī)格的服務(wù)實(shí)例無(wú)法調(diào)度,另一方面還造成了較多的資源碎片。
為了解決以上問(wèn)題,我們?cè)谡{(diào)度器中自定義實(shí)現(xiàn)了資源預(yù)占的調(diào)度插件(通過(guò) CRD 定義資源預(yù)占期望,影響調(diào)度決策),用來(lái)提升用戶體驗(yàn)和提高調(diào)度效率。
圖片
圖片
平衡調(diào)度
為了更好地平衡集群中節(jié)點(diǎn)的水位,以避免過(guò)熱節(jié)點(diǎn)的出現(xiàn)、盡量減少碎片資源等為目標(biāo)來(lái)思考和設(shè)計(jì),我們基于 Kubernetes 提供的調(diào)度器擴(kuò)展框架,自定義實(shí)現(xiàn)了多個(gè)調(diào)度插件:
- CoolDownHotNode 插件:給最近調(diào)度過(guò) Pod 的節(jié)點(diǎn)降低優(yōu)先級(jí),避免熱點(diǎn)節(jié)點(diǎn)。
- HybridUnschedulable 插件:阻止使用彈性資源的 Pod 調(diào)度到某些節(jié)點(diǎn)上。
- NodeBalance 插件:用于平衡各節(jié)點(diǎn)上 CPU Request 值與畫(huà)像的比值,平衡各節(jié)點(diǎn) CPU 使用率。
- NodeInfoRt 插件:基于畫(huà)像打分?jǐn)?shù)據(jù)和實(shí)時(shí)打分?jǐn)?shù)據(jù)優(yōu)化 Pod 調(diào)度。
在實(shí)時(shí)混部
從今年 1 月份開(kāi)始,我們著手做在離線混部的落地,一期的目標(biāo)著眼于將在線服務(wù)與 Flink 任務(wù)進(jìn)行混部。之所以選擇 Flink 任務(wù)做混部,是因?yàn)樗c在線服務(wù)有一個(gè)相似之處,那就是它是一種常駐的離線任務(wù),在它啟動(dòng)之后如果沒(méi)有特殊情況,一般不會(huì)下線,這種特質(zhì)會(huì)使得我們的容器集群調(diào)度頻次、Pod 的變更程度會(huì)低一些,進(jìn)而對(duì)穩(wěn)定性的挑戰(zhàn)也會(huì)小一點(diǎn),整體混部風(fēng)險(xiǎn)也會(huì)低一些。
在沒(méi)有混部的情況下,我們的集群整體利用率較低,即便畫(huà)像功能能幫助用戶盡可能合理的為自己的服務(wù)實(shí)例設(shè)置資源規(guī)格,但對(duì)容器平臺(tái)而言這依然很被動(dòng)。所以為了挖掘出可以用來(lái)混部的資源,我們?yōu)椴煌燃?jí)的服務(wù)設(shè)置不同的綁核策略。如下表所示定義了 4 種應(yīng)用類型(LSX、LSR、LS、BE),適用于 P0~P4 范圍和離線任務(wù),綁核策略從完全綁核到部分綁核,再到完全共享。
圖片
離線任務(wù)(Flink 任務(wù))屬于 BE 類型,可以使用的資源是在宿主機(jī)所有 CPU 核心里面單獨(dú)劃分出來(lái)的一部分專用 CPU 核心,再加上 LS 的共享 CPU 核心,以及 LSR、LS 類型的應(yīng)用上共享出來(lái)的部分 CPU 核心。
圖片
LSX、LSR 和 LS 類型的應(yīng)用服務(wù)的容器實(shí)例均申請(qǐng)使用 Kubernetes 原生的資源 CPU/Memory 資源;BE 類型的任務(wù)需要申請(qǐng)使用我們自定義的資源 BE-CPU/BE-Memory 資源。
圖片
基于 Kubernetes 的 Device-Plugin 機(jī)制我們自研實(shí)現(xiàn)了 Kube-Agent 組件,該組件在集群中的所有節(jié)點(diǎn)上以 Damonset 的方式部署,一方面負(fù)責(zé)根據(jù)自定義策略將本節(jié)點(diǎn)上可用的 BE 資源上報(bào)給 API-Server(通過(guò) Kubelet 組件間接上報(bào)),另一方面負(fù)責(zé)執(zhí)行 CPU 綁核操作。隨著混部的深入,該組件也承擔(dān)了更多的工作內(nèi)容(例如:執(zhí)行 CPU 算力壓制操作、參數(shù)動(dòng)態(tài)調(diào)整操作,執(zhí)行 VPA 操作等)。
在離線混部
一期的混部在應(yīng)用級(jí)別劃分的基礎(chǔ)上,應(yīng)用了 CPU 核劃分策略來(lái)實(shí)現(xiàn)混部。站在 CPU 核心的角度來(lái)看,通過(guò) CPU 核劃分策略之后,每個(gè) CPU 核心已經(jīng)有了自己的負(fù)載歸屬,能否充分利用取決于分配到它上面的業(yè)務(wù)特性。但站在整機(jī)的利用率上來(lái)看(或者站在整個(gè)集群的利用率角度來(lái)看),依然有很大的提升的空間?;觳慷诘臅r(shí)候,我們考慮對(duì)BE資源進(jìn)行二次超賣,以另一種新的自定義資源(OT 資源)進(jìn)行分配使用。使用 OT 資源的任務(wù)不獨(dú)占綁核,而是共享劃分給 BE 資源的所有 CPU 核心。
圖片
我們使用 OT 資源來(lái)混部 AI 訓(xùn)練任務(wù)、其它數(shù)據(jù)處理任務(wù),為了消除訓(xùn)練任務(wù)對(duì)在線業(yè)務(wù)的影響,通過(guò)以下策略進(jìn)行保證:
- 設(shè)置宿主機(jī)安全水位,通過(guò)調(diào)度插件防止過(guò)熱節(jié)點(diǎn)出現(xiàn)。
- 通過(guò) CPU Group Identity 進(jìn)行優(yōu)先級(jí)競(jìng)爭(zhēng),保障離線任務(wù)的調(diào)度優(yōu)先級(jí)絕對(duì)低于在線服務(wù)。
- 對(duì)離線任務(wù)進(jìn)行獨(dú)立掛盤,避免影響在線服務(wù)的磁盤 IO。
- 夜間時(shí)段通過(guò) KubeAutoScaler 進(jìn)行對(duì)在線服務(wù)進(jìn)行彈性縮容,等比例提升內(nèi)存的空閑率,保障離線任務(wù)有足夠的內(nèi)存資源。
彈性伸縮
- HPA:Horizontal Pod Autoscaling,水平方向的 Pod 副本擴(kuò)縮容。
- VPA:Vertical Pod Autoscaling,垂直方向的 Pod 規(guī)格擴(kuò)縮容。
Kubernetes 中通過(guò)資源對(duì)象 HorizontalPodautoScalers 來(lái)支持工作負(fù)載的水平擴(kuò)縮容,在較早的版本中只支持 CPU 和內(nèi)存這兩個(gè)資源指標(biāo),較新版本中也開(kāi)始支持自定義指標(biāo)了。針對(duì) VPA 的需求,目前 Kubernetes 層面還沒(méi)有比較穩(wěn)定的可用功能,因?yàn)閷?duì)一個(gè) Pod 實(shí)例做資源規(guī)格的調(diào)整,會(huì)涉及到宿主機(jī)上資源賬本的管理問(wèn)題、監(jiān)控問(wèn)題,也會(huì)涉及到 Pod 的重建/容器重啟動(dòng)作,影響面會(huì)比較大,目前社區(qū)中依然在討論。但企業(yè)在 VPA 方面,也都是躍躍欲試,會(huì)設(shè)計(jì)自己的個(gè)性化 VPA 方案,本文前述應(yīng)用畫(huà)像功能,就是我們得物在 VPA 方案上探索的第一步。
此外,我們?cè)趯?shí)際的支撐業(yè)務(wù)云原生化轉(zhuǎn)型過(guò)程中發(fā)現(xiàn),與通過(guò)服務(wù)的資源使用率指標(biāo)來(lái)幫助業(yè)務(wù)來(lái)決策服務(wù)實(shí)例副本數(shù)的調(diào)整的方式相比,定時(shí)擴(kuò)縮容反而能讓研發(fā)同學(xué)更有信心,研發(fā)同學(xué)可以根據(jù)自己負(fù)責(zé)的業(yè)務(wù)服務(wù)的流量特征,來(lái)設(shè)置定時(shí)地縮容或者擴(kuò)容自己的服務(wù)實(shí)例數(shù)量。
為了滿足彈性伸縮場(chǎng)景的所有需求,我們?cè)O(shè)計(jì)實(shí)現(xiàn)了 KubeAutoScaler 組件,用來(lái)統(tǒng)一管理 HPA、VPA、定時(shí)伸縮等彈性伸縮策略配置。此外,如前所述,該組件與畫(huà)像系統(tǒng)相互協(xié)作,在混部場(chǎng)景下可以幫助在夜間對(duì)部分低流量的服務(wù)做縮容操作,釋放更多的資源供離線任務(wù)使用。
彈性伸縮方案在 GPU 服務(wù)場(chǎng)景幫我們避免了很多的資源浪費(fèi),特別是在測(cè)試環(huán)境。如圖所示,我們?yōu)?GPU 服務(wù)注入了一個(gè)名為 Queue-Proxy 的 Sidecar 容器,用來(lái)采集服務(wù)流量,當(dāng)流量低于某個(gè)閾值時(shí),會(huì)按照比例減少實(shí)例數(shù);當(dāng)流量為 0 并持續(xù)了一段時(shí)間之后,會(huì)完全縮零。當(dāng)冷啟動(dòng)時(shí),請(qǐng)求會(huì)經(jīng)過(guò)激活器 Activator,激活器再通知 KubeAutoScaler 進(jìn)行服務(wù)擴(kuò)容。生產(chǎn)環(huán)境的部分服務(wù)也開(kāi)啟了這一套機(jī)制,但在流量低峰期不會(huì)完全縮容至零,會(huì)維持一個(gè)最小的副本數(shù)。
圖片
四、容器資源和成本治理優(yōu)化
為了更好地提升整體的資源利用、降低基礎(chǔ)設(shè)施成本,與技術(shù)方案的落地周期長(zhǎng)、復(fù)雜度高的特點(diǎn)比起來(lái),通過(guò)治理方法往往能在較短時(shí)間內(nèi)達(dá)到不錯(cuò)的效果,特別是在應(yīng)用服務(wù)容器化部署改造進(jìn)行到后期的時(shí)候。我們通過(guò)以下 5 個(gè)方面的治理實(shí)踐,降本效果明顯。
機(jī)型替換
因?yàn)闅v史原因,我們的模型推理服務(wù)在剛開(kāi)始的時(shí)候使用的是 V100 的機(jī)型,該機(jī)型顯存較大、GPU 算力較優(yōu),更適合用在訓(xùn)練場(chǎng)景,在推理場(chǎng)景的話有點(diǎn)大材小用了。經(jīng)過(guò)機(jī)型對(duì)比分析,我們選用了一個(gè)性價(jià)比較高的 A10 機(jī)型,推理服務(wù)的成本整體降低了 20% 左右,而且因?yàn)?A10 機(jī)型配備的 CPU 架構(gòu)有升級(jí),對(duì)前后處理有較高要求的推理服務(wù)而言穩(wěn)定性和性能均有提升。從 V100 切換到 A10,主要的工作在于基礎(chǔ)鏡像的替換,因?yàn)椴糠帜P头?wù)可能使用了較低版本的 CUDA,但是 A10 卡的算力需要配備較高的 CUDA。另外,因?yàn)閮煞N卡的 GPU 算力也是有差異的,替換之后需要對(duì)推理結(jié)果做對(duì)比驗(yàn)證才可以上線。我們基于流量回放的思路,設(shè)計(jì)了 AB 實(shí)驗(yàn)功能幫助業(yè)務(wù)做切換測(cè)試。
圖片
在使用 CPU 計(jì)算資源的場(chǎng)景上,我們對(duì)算力要求一般、對(duì) CPU 指令集因無(wú)特殊要求、對(duì)單核/多核性能無(wú)要求的服務(wù),均將其使用的機(jī)型從 Intel 的切換到了 AMD 的,整體成本降低 14% 左右。
資源池管理
不得不承認(rèn)的是容器化初期業(yè)務(wù)方是占據(jù)主動(dòng)的,業(yè)務(wù)側(cè)會(huì)基于穩(wěn)定性、資源供給量上的考量要求容器平臺(tái)獨(dú)立建集群,或者資源池,容器平臺(tái)也會(huì)選擇粗放式管理而應(yīng)承這些需求。隨著容器化的推進(jìn),業(yè)務(wù)側(cè)的信心也會(huì)增強(qiáng),容器平臺(tái)對(duì)資源的把控程度也會(huì)更好,我們逐步采取以下幾個(gè)動(dòng)作來(lái)收斂資源的管理,提高整體的資源分配率:
- 冗余量控制:業(yè)務(wù)的發(fā)布是有周期的,我們會(huì)根據(jù)發(fā)布周期,動(dòng)態(tài)調(diào)整容器平臺(tái)管理的資源冗余量。在保證日常的迭代開(kāi)發(fā)的同時(shí),盡可能縮小冗余量。
- 集群合并:統(tǒng)一規(guī)劃 Kubernetes 集群,按照區(qū)域(上海、杭州、北京等)、網(wǎng)絡(luò)環(huán)境類型(測(cè)試、預(yù)發(fā)、生產(chǎn))、業(yè)務(wù)形態(tài)(普通業(yè)務(wù)、中間件、基礎(chǔ)設(shè)施、管控集群等)等維度討論和決策,下線不必要的集群。
- 資源池合并、規(guī)整機(jī)型:合并資源需求特征比較相近的資源池(例如:計(jì)算型的、內(nèi)存型的),選擇合適的機(jī)型。與業(yè)務(wù)溝通,下線或者合并利用率過(guò)低的小資源池。
- 碎片整理:?jiǎn)慰空{(diào)度器的優(yōu)化,在調(diào)度時(shí)盡可能避免碎片力量有限。加上在線服務(wù)的變更頻率一般比較低,如果不做重調(diào)度,長(zhǎng)時(shí)間累積下來(lái),集群中會(huì)存在大量碎片。所以,針對(duì)多副本的應(yīng)用集群,在健壯的優(yōu)雅停機(jī)機(jī)制基礎(chǔ)上,我們適當(dāng)進(jìn)行了一些碎片整理任務(wù)(重建 Pod 自由調(diào)度、重調(diào)度、宿主機(jī)騰挪等),有效地減少了資源碎片。
工作負(fù)載規(guī)格治理
用戶自定義工作負(fù)載的規(guī)格在云原生場(chǎng)景下也是一個(gè)常用的做法,這看似對(duì)用戶友好的做法卻對(duì)容器平臺(tái)造成了一些挑戰(zhàn),因?yàn)槿绻麑?duì)用戶設(shè)置規(guī)格的自由度不做一些限制,很可能出現(xiàn)一些非常不合理的規(guī)格設(shè)置(例如:6C120G、20C4G),會(huì)產(chǎn)生調(diào)度碎片、成本分?jǐn)傆?jì)算標(biāo)準(zhǔn)也難統(tǒng)一。
為了解決規(guī)格的問(wèn)題,我們對(duì)在線服務(wù)的資源規(guī)格做了限制,不允許用戶隨意指定,而是由平臺(tái)給出規(guī)格列表,由用戶選擇使用。規(guī)格列表可以分資源池設(shè)計(jì)、也可以分業(yè)務(wù)場(chǎng)景設(shè)置。針對(duì)任務(wù)型的工作負(fù)載,我們定義了 3 種 CPU 類型的資源規(guī)格(普通型、計(jì)算型、內(nèi)存型,分別對(duì)應(yīng)不同的 CPU:內(nèi)存比例)。針對(duì)特殊的任務(wù)需求,我們約定了資源規(guī)格當(dāng)中 CPU:內(nèi)存的范圍。針對(duì)使用 GPU 的任務(wù),因每種 GPU 卡的 CPU/內(nèi)存/顯存規(guī)格配比都是不一樣的,我們定義了針對(duì)每種 GPU 卡的 CU 單位,用戶只需要選擇相應(yīng)的 CU,填寫 CU 數(shù)量即可。規(guī)格約定之后,我們針對(duì)不同的規(guī)格做了差異化計(jì)費(fèi),保證了規(guī)格申請(qǐng)和成本分?jǐn)偵系暮侠硇浴jP(guān)于規(guī)格的定義和計(jì)費(fèi)標(biāo)準(zhǔn),詳見(jiàn)下表。
圖片
產(chǎn)品自建
得物的基礎(chǔ)設(shè)施是在云上,所以在業(yè)務(wù)發(fā)展過(guò)程中,部分服務(wù)能力我們是會(huì)直接選用云上產(chǎn)品的。算法側(cè)的模型訓(xùn)練任務(wù),最開(kāi)始的時(shí)候就是選用云上產(chǎn)品,隨著容器化的推進(jìn),我們自建的 AI 平臺(tái)(KubeAI 平臺(tái))逐步承接模型訓(xùn)練任務(wù),使得訓(xùn)練任務(wù)的成本大幅下降。
自建 KubeAI 平臺(tái),使得我們將訓(xùn)練使用的資源與在線服務(wù)、其它離線任務(wù)場(chǎng)景使用的資源納入了統(tǒng)一的管理體系,便于從全局的視角去合理地調(diào)度分配資源,為 AI 模型訓(xùn)練場(chǎng)景拿到更多的可用資源。本文前述 2.5 小節(jié),我們就是通過(guò)混部的方式,將在線服務(wù)的資源供給了訓(xùn)練任務(wù)使用,當(dāng)前已經(jīng)在常態(tài)混部。
圖片
多云策略
作為云上用戶,多云策略是我們的長(zhǎng)期目標(biāo)。在多云之間獲得議價(jià)主動(dòng)權(quán)、符合合規(guī)性要求、獲得更充足的資源供給。尤其今年 4 月份以來(lái),隨著 GPT/AIGC 方面的爆發(fā)、政策因素導(dǎo)致單個(gè)云商的 GPU 資源對(duì)我們供給不足,阻礙業(yè)務(wù)發(fā)展。我們及時(shí)采用多云策略,將 GPU 業(yè)務(wù)分散到不同的云供應(yīng)商,保障業(yè)務(wù)正常開(kāi)展。當(dāng)然,多云的接入不是一蹴而就的,而是需要分業(yè)務(wù)場(chǎng)景逐步推進(jìn),周期較長(zhǎng),難度較大,我們需要考慮以下問(wèn)題:
- 梳理業(yè)務(wù),找到適合多云的業(yè)務(wù)場(chǎng)景,或者找到適合在多云之間靈活遷移的業(yè)務(wù)場(chǎng)景。
- 因不同云供應(yīng)上的機(jī)房可能在不同的區(qū)域,所以需要考慮跨地域服務(wù)訪問(wèn)、中間件依賴問(wèn)題。
- 跨云供應(yīng)商的數(shù)據(jù)訪問(wèn)和傳輸問(wèn)題,涉及到專線建設(shè)、成本問(wèn)題。
五、云原生AI場(chǎng)景建設(shè)
我們期望云原生容器技術(shù)的落地是要覆蓋全場(chǎng)景的,要將云原生技術(shù)在普通服務(wù)、中間件產(chǎn)品和特殊的業(yè)務(wù)場(chǎng)景上都能發(fā)揮其巨大優(yōu)勢(shì)。目前 MySQL、Redis、Miluvs、ElasticSearch 等產(chǎn)品都已經(jīng)在推進(jìn)容器化。云原生 AI 場(chǎng)景的建設(shè),我們通過(guò) KubeAI 平臺(tái)的建設(shè)在持續(xù)推進(jìn)。
圖片
KubeAI 是得物 AI 平臺(tái),是我們將云原生容器技術(shù)落地得物全站業(yè)務(wù)過(guò)程中,逐步收集和挖掘公司各業(yè)務(wù)域在AI模型研究和生產(chǎn)迭代過(guò)程中的需求,逐步建設(shè)而成的一個(gè)云原生 AI 平臺(tái)。KubeAI 以模型為主線提供了從模型開(kāi)發(fā),到模型訓(xùn)練,再到推理(模型)服務(wù)管理,以及模型版本持續(xù)迭代的整個(gè)生命周期內(nèi)的解決方案。此外,隨著 AIGC 的火熱發(fā)展,我們經(jīng)過(guò)調(diào)研公司內(nèi)部 AI 輔助生產(chǎn)相關(guān)需求,上線了 AIGC/GPT 服務(wù),為得物豐富的業(yè)務(wù)場(chǎng)景提供了 GAI 能力,助力業(yè)務(wù)效果提升。關(guān)于 KubeAI 平臺(tái)相關(guān)解決方案,我們之前發(fā)布過(guò)一些文章,歡迎大家閱讀交流,這里不再贅述。
- 一文讀懂得物云原生AI平臺(tái)-KubeAI的落地實(shí)踐過(guò)程
- 得物AI平臺(tái)-KubeAI推理訓(xùn)練引擎設(shè)計(jì)和實(shí)踐
- 得物大模型平臺(tái),業(yè)務(wù)效果提升實(shí)踐
- GPU推理服務(wù)性能優(yōu)化之路
六、展望
云原生容器技術(shù)在得物的落地開(kāi)展還是比較快的,業(yè)務(wù)覆蓋面也比較廣泛。經(jīng)過(guò) 2 年時(shí)間的實(shí)踐落地,已經(jīng)全面深入資源管理系統(tǒng)、預(yù)算/成本管理機(jī)制、應(yīng)用服務(wù)發(fā)布流程、AI 算法等管理體系和業(yè)務(wù)場(chǎng)景。接下來(lái):
- 在容器化,我們會(huì)繼續(xù)推進(jìn)中間件產(chǎn)品的容器化,進(jìn)一步提升基礎(chǔ)設(shè)施的資源效率。
- 我們會(huì)繼續(xù)鞏固混部方案,繼續(xù)探索彈性容量、調(diào)度優(yōu)化等方案,進(jìn)一步提升資源效率。
- 在穩(wěn)定性方面,我們會(huì)繼續(xù)關(guān)注容器平臺(tái)/Kubernetes 本身的穩(wěn)定性建設(shè),防范風(fēng)險(xiǎn),切實(shí)保證業(yè)務(wù)平穩(wěn)運(yùn)行。
- 與業(yè)務(wù)場(chǎng)景一起探索快速接入多云,以及多云之間的快速切換能力,保障業(yè)務(wù)規(guī)模在持續(xù)增長(zhǎng)的情況下,容器基礎(chǔ)設(shè)施切換靈活、堅(jiān)如磐石。