背景介紹
騰訊雲智聆口語評測(Smart Oral Evaluation,SOE)是騰訊雲推出的中英文語音評測產品,支援從兒童到成人全年齡覆蓋的語音評測,提供單詞、句子、段落、自由說等多種評測模式,從發音精準度、流利度、完整度等全方位打分機制,與專家打分相似度達 95% 以上,可廣泛應用於中英文口語教學場景中。
在降本增效的大環境下,業務積極尋求成本更優的解決方案,且由於已經積累了 IDC 物理機、雲上虛擬機器和雲上 Serverless 容器服務等多套部署環境,業務架構十分臃腫,運維難度非常高,業務急需一套更加統一的方案降低系統複雜度。
問題與挑戰
產品側的降本訴求
問題
在當前降本增效大環境下,如何控制產品成本成為一個越來越重要的命題,經歷了兩個發展時期後,我們不得不試著上手抽絲剝繭,嘗試解決這個問題
挑戰
因為業務發展歷史及業務架構原因,當前資源 buffer 較多,資源利用率較低,系統成本居高不下,主要有以下兩個問題
擴容成本非常高 - 由於本身是 AI 評測類業務,依賴大量 GPU 資源,而 GPU 機器從資源申請到交付,再到服務部署除錯與流量接入,週期通常是天級的,無法應對早晚高峰的尖峰流量,所以需要為高峰期預留大量 buffer
資源流轉效率低 - 同時業務側存在中英文評測服務,AI 引擎是兩套模型,而模型間的部署切換成本也比較高,這也導致我們需要預留雙份的 buffer
客戶側日漸豐富的流量模型
問題
日漸豐富的業務場景 - 在工作日非工作日、早晚高峰和中英文評測的多種條件組合下產生了非常多場景,透過提前備量去 cover 所有場景成本是不可行的
無法預估的業務增量 - 部分客戶的量受疫情影響非常大,且經常是不可預期的,客戶自己也無法預估評測用量會達到什麼量級,這也導致我們無法精準地提前備量
削不掉的尖峰流量 - 部分客戶存在非常明顯的尖峰流量,使用者會集中在晚高峰的某幾個時間點進行評測,尖峰流量通常是平峰期的10倍以上,且客戶依賴實時結果返回,無法透過非同步評測的方式削峰
挑戰
運維難度高 - 當前架構下無法支援業務側高效地進行資源流轉、更無法快速完成彈性擴容
服務質量難保障 - 引擎服務故障節點剔除依賴人工操作,無法快速完成故障自愈;引擎服務部署方式多樣,物理機/虛擬機器/容器方案並存,無法搭建統一的可觀測體系
3. 新架構
需求
資源利舊:業務側絕大部分機器還在 IDC 物理機房,且物理機價效比高於虛擬機器,上雲過程中期望能把這部分機器利用起來,降低整體成本
網路連通:雲上雲下服務網路需打通,且業務側跨地域排程流量容災的需求,引擎層需要能夠被多叢集接入層訪問。同時,由於不同機型不同規格的引擎層消費能力不同,至少需要支援自定義權重的靜態負載均衡策略
擁抱雲原生:升級系統架構,落地混合雲方案,全面擁抱雲原生。雲原生生態下已經有非常多最佳實踐與解決方案,業務面臨的許多問題在雲原生場景下都能找到很好地解法,把業務搬遷上雲不是目的,上雲是更高效、優雅的解決業務面臨的服務擴縮容、服務故障自愈、服務可觀測等問題的手段
選型 - TKE 註冊節點叢集
能力介紹
註冊節點(原第三方節點)是騰訊雲容器服務團隊針對混合雲部署場景,全新升級的節點產品形態,允許使用者將非騰訊雲的主機,託管到容器服務 TKE 叢集,由使用者提供計算資源,容器服務 TKE 負責叢集生命週期管理。業務側可以透過註冊節點的特性,將 IDC 主機資源新增到 TKE 公有云叢集,確保在上雲過程中存量伺服器資源得到有效利用,同時支援在單叢集內同時排程註冊節點、雲上 CVM 節點及雲上超級節點,便於將雲下業務擴充至雲上,無需引入多叢集管理。
新增了註冊節點的叢集,可能包含眾多不同網路環境的計算節點,如 IDC 網路環境和公有云 VPC 網路環境的計算節點。為了遮蔽底層不同網路環境的差異,TKE 容器團隊推出了基於 Cilium Overlay 的混合雲容器網路方案。實現在容器層面看到的是統一的網路平面,使得 Pod 無需感知其是執行在 IDC 的計算節點還是公有云的計算節點,加上雲梯環境與內網環境本就是互通的,這也就奠定了智聆業務上雲選型的基礎
TKE註冊節點架構
(圖自[註冊節點-網路模式]官網文件:https://cloud.tencent.com/doc...))
業務架構方案
在新架構各層部署方式較平臺期時期都有了較大改變:
1、接入層部署在超級節點上,充分利用資源彈效能力;
2、引擎層服務透過不同的 Deployment 部署在 IDC 節點、CVM 節點和超級節點上,均以 Pod 的形式對外服務,遮蔽掉部署環境的區別;
3、基於第二點移除了 Serverless 容器服務 Pod 的流量接入層,減少一次轉發,最佳化流量排程。
流量路徑
客戶流量就近接入雲 API 閘道器後,雲 API 閘道器透過北極星名字服務進行服務發現,實現流量就近接入業務側 CLB。業務側 CLB 直連線入層 Pod,流量到達業務側後,接入層服務再次根據名字服務透過北極星進行服務發現,獲取 RS IP 後請求引擎層消費。新方案在接入層遮蔽了引擎部署環境和各資源池的區別,接入層僅透過配置去北極星獲取對應 RS IP 後請求即可,降低了流量排程的複雜度
服務部署
接入層
接入層透過節點親和性排程至超級節點部署,透過 HPA 配置利用雲上彈性擴縮容能力進行削峰填谷,對比部署在 CVM 節點上的方案有以下幾個優勢
1、擴縮容更方便、更靈敏。若部署在 CVM 節點上需要配置 Cluster Autoscaler 使用,需要先擴容出 CVM 節點,再擴容 Pod,耗時會達到分鐘級,而超級節點可以實現秒級擴容
2、成本更優。CVM 節點加入叢集后需要扣除叢集管理預留的部分,且叢集元件本身有超10個 DaemonSet,也會額外再佔用一部分資源,實際資源使用率明顯低於超級節點
3、管理複雜度更低。不需要維護節點資源,超級節點可按需新增,根據業務情況靈活調整
引擎層
引擎層則需要充分利用 TKE 叢集註冊節點能力,透過節點親和性配置分別部署在 IDC 節點、CVM 節點和超級節點上,其中 IDC 節點為利舊資源,CVM 節點為後續常備的基礎資源,超級節點為彈性伸縮資源
既然前面接入層部署時講了那麼多超級節點的優點,那引擎層部署時為什麼又需要 CVM 節點呢?
成本更優:引擎服務不僅依賴於 GPU 資源,對 CPU/MEM 也有高的需求,而超級節點支援的 GPU 節點規格有限,推理型 GI3X 機型相對於 Serverless 容器服務 彈性出來的 T4 卡規格具有更強的 CPU 和更多的 CPU/MEM 配比,對於業務側的價效比更高。
服務發現
北極星
接入層與引擎層整體均藉助北極星進行服務發現,但根據接入層與引擎層需求選取了多種暴露服務的方式。
接入層
接入層透過內網 LoadBalancer 型 Service 暴露服務,北極星繫結 LB IP。業務還採用了 LB 直連 Pod 的模式減少 NodePort 轉發,這裡其實最開始沒有采用直連的形式,也是踩了個坑,後文中會提到。
引擎層
IDC 節點與 CVM 節點上的引擎容器透過 Docker Host Network 網路模式與節點共享網路堆疊,使得容器暴露埠可直接對映到節點上,故北極星直接繫結 Pod IP(也是節點 IP)即可,而超級節點上的 Pod IP 為真實的內網 IP,也能直接在北極星上繫結 Pod IP,透過這樣選型可以遮蔽掉 Pod 排程到不同節點上的差異,統一上報為容器 IP。
事實上如果要實現以上效果方案是比較多的,這裡也大致對比了下,可以根據實際情況進行選擇。業務側剛好單個 IDC/CVM 節點僅執行一個引擎 Pod,且節點上也不會再執行其他服務,故不存在埠爭用的問題,對比下來業務側選擇了效能更優,實施也更為簡潔的 hostNetwork 方案。
實現方案 | hostNetwork | hostPort | NodePort Service |
---|---|---|---|
備註 | - | - | 需配置新增以下配置防止流量排程至其他 Node上 .spec.externalTrafficPolicy: True |
優點 | 效能最優 | - | 應用廣泛,也是 K8s 官方更推薦的方案不存在埠爭用的問題,支援一個 Node 上執行多個 Pod 的情況 |
缺點 | 可能存在埠爭用的問題 | 可能存在埠爭用的問題; 需要業務側自行維護 Node 與 Pod 的對映關係; 多一次轉發,會有一定的效能損耗 | 需要業務側自行維護 Node 與 Pod 的對映關係; 多一次轉發,會有一定的效能損耗 |
服務運維
灰度釋出
接入層
前文中提到使用 Service 來暴露接入層服務,而 Service 透過 Label Selector 來選取 Pod,我們可以透過兩個 Deployments 來管理這組 Pod,然後透過調整 Pods 數量來調整流量比例,從而實現灰度釋出的功能。
需要關注的是我們採用 LB 直連 Pod 的方案,這種方案下預設僅在 Pod 被刪除後才會從 LB RS 中移除,為實現服務優雅停機需新增兩條配置,這樣在 Pod 處於 terminating 狀態時就會把 CLB RS 的權重調0,防止流量持續接入。
kind: Service
apiVersion: v1
metadata:
annotations:
service.cloud.tencent.com/direct-access: "true" ## 開啟直連 Pod 模式
service.cloud.tencent.com/enable-grace-shutdown: "true" # 表示使用優雅停機
name: my-service
spec:
selector:
app: MyApp
引擎層
引擎層的實現更為簡單,前文中也提到引擎服務的註冊與反註冊是由服務自身完成的,我們只需要與接入層一樣調整兩組 Deployment 的數量就能實現灰度比例控制。
服務可觀測
日誌
日誌方案統一使用 CLS 採集,並且透過 CLS 跨地域採集的功能採集至同一個日誌 topic 中進行檢索分析,簡化現網日誌檢索複雜度。
監控
監控方案統一為雲監控方案,透過雲 Prometheus 採集基礎指標及業務指標進行展示分析,減少多套監控體系學習與維護成本。
基礎監控 - 雲 Prometheus 接入叢集監控後自帶多個皮膚,基本符合需求,業務側只需要完成 GPU 資料的採集上報即可。
業務監控 - 業務側引入 Prometheus SDK 暴露並配置 job 進行採集即可。
告警
告警方案也統一為雲監控告警,藉助雲監控的能力覆蓋郵件、企微微信、電話等多種渠道,減少告警渠道維護成本與多套告警規則配置學習成本。
異常節點剔除
當 Pod 異常時應該及時切斷流量,保證流量不會持續進到異常pod內導致現網服務受損,提供兩種方案,經調研業務側選擇方案二:
方案一:Liveness Probe
配置存活探針,業務健康檢查異常時直接殺死 Pod,而後進入上文提到的 Pod 優雅退出流程,阻斷流量進入異常 Pod。
方案二(推薦):Readiness Probe + Readiness Gate
配置就緒探針,業務健康檢查異常時將 Pod 狀態置為 Not Ready,配合 ReadinessGate 機制,當檢測到 Pod 狀態為 Not Ready 時將相應 LB RS 權重調0,阻斷流量進入異常 Pod。
該方案的好處是能夠保留事故現場用於 debug,便於快速定位問題,配合雲監控告警即可實現快速感知。
排程方案
服務排程-動態擴縮容能力
業務側之所以選擇自研 scheduler 服務是因為業務側有靈活的擴縮容訴求,除了常規的 HPA&HPC 的能力,scheduler 服務還有以下功能:
1、HPA&HPC 規則均作用於資源池級別,原生 HPA&HPC 僅支援 Deployment/StatefulSet 級別;
2、業務側有資源流轉的需求,如北京地域早高峰中文評測的量很高,而英文早高峰相對較低,需要支援透過調整中英文引擎 Pod 數量的方式提高資源整體利用率;
3、業務側有保障擴容成功率的需求,由於業務側需要的 GPU 資源數量較多,故需要透過切換規格和切換地域等方式提高擴容成功率。
流量排程-資源隔離
引擎層資源隔離藉助北極星動態路由的能力實現,服務(大池子)、別名(公共池/各大客戶專有池)和別名路由(池子劃分規則)需要提前建立好。自研 scheduler 服務根據配置為引擎 Pod 打標並注入別名列表,接入層在拿到對應別名後向北極星獲取 RS IP 請求即可,不需要感知流量路由到哪個池子。
前置工作
1、建立統一的北極星服務;
2、建立各資源池北極星別名;
3、在北極星服務下建立各別名路由規則,選取對應 label 的 RS。
引擎啟動註冊流程
1、引擎服務啟動後自行註冊至統一的北極星名字服務下;
2、scheduler 服務監聽到存在未打 label 的 RS 則根據規則及各資源池當前負載情況進行打標,用於標記是哪個資源池;
3、scheduler 服務根據規則判斷當前資源池是否生效,若生效則注入接入層訪問引擎層的別名列表。
使用者請求流程
1、接入層獲取別名;
2、接入層透過別名向北極星獲取 RS IP;
3、接入層請求 RS IP。
取得效果
降本增效
服務擴容到流量接入耗時最佳化至分鐘級,自研 scheduler 服務結合 EKS 彈性擴容能力進行削峰填谷,降低超30%系統成本,節約2個運維人力
自研 scheduler 服務進行資源流轉,早高峰期將閒置的英文節點資源轉換為中文節點資源,減少北京地域近90%早高峰擴容需求
(上圖是最佳化後效果,早高峰僅擴容少量資源,下圖是最佳化前效果,早高峰需要擴容大量中文節點)
服務質量提升
接入層異常節點剔除
接入層透過業務側配置的 Readiness Probe 探測服務存活,當心跳失敗時配合 ReadinessGate 機制將 CLB 中對應 RS 的流量路由權重置0,以此實現異常節點自動剔除,保障現網服務質量
引擎層異常流量剔除
引擎層透過北極星心跳上報的形式探測服務存活,當心跳失敗時北極星自動將對應 RS 狀態置為異常,以此實現異常節點自動剔除,保障現網服務質量
過程遇到的問題
大叢集方案未能實現
期望
最初設想是由一個 TKE 叢集納管所有節點(IDC 節點、雲上 CVM 節點、雲上超級節點),以此來簡化整體服務部署,提高叢集間資源流轉效率,進一步降低整體方案複雜度。
問題
當前叢集暫不支援繫結多地域 CLB,也暫不支援加入多地域超級節點,導致無法實現服務就近接入和彈性多地資源。
妥協方案
當前單地域大叢集的方案,各地域均部署一個叢集。
5.2. CVM轉發效能瓶頸
問題表現
高峰期出現 connection reset by peer 的報錯,報錯比例低於0.01%,經排查均來自某個 CLB IP。
問題成因
檢視 CLB、Pod 的監控均正常,在 Pod 內部署抓包也沒發現異常的握手請求,而且業務側 LB 是內網四層 LB,當前流量應該遠沒有達到 LB 的效能瓶頸。
正在一籌莫展之際開始重頭排查整條鏈路,發現業務雖然選擇的是 LB 型 Service,且 Pod 部署在超級節點上,但是 LB RS 卻是 CVM 節點,流量還是透過 NodePort 的形式進入叢集,再由 K8s 內部網路轉發至對應服務 Pod,接入層 Pod 能夠藉助超級節點的能力彈性擴縮容,但是 CVM 節點數量卻是固定的,就成為了系統的效能瓶頸。
知道有這麼條鏈路之後再登入 CVM 節點驗證,發現確實是 CVM 節點的連線數被打滿了,導致部分連線被拒絕。
(圖自容器服務官網文件)
解決方案
到這兒解決方案也非常清晰了,藉助 TKE 提供的 CLB 直連 EKS Pod 的能力去掉 NodePort 轉發,流量均勻的打到 Serverless 容器服務 Pod 上, Serverless 容器服務 Pod 又可以彈性擴縮容,以此就解決了效能瓶頸的問題。
(圖自容器服務官網文件)
總結
在不同的業務發展階段需要選擇合適的架構,沒有完美的方案,需要隨著技術迭代不斷調整,固步自封只會讓研發成為業務的短板。業務上雲最終導向都應該是業務成功,服務於降本增效、提高服務質量等目標,上雲後業務能夠背靠騰訊雲,藉助各雲產品強大的能力快速實現業務需求,降低技術使用門檻。
【騰訊雲原生】雲說新品、雲研新術、雲遊新活、雲賞資訊,掃碼關注同名公眾號,及時獲取更多幹貨!!