本文爲《螞蟻金服 Service Mesh 大規模落地系列》第七篇 - 控制面篇,該系列將會從核心、RPC、消息、無線網關、控制面、安全、運維、測試等模塊對 Service Mesh 雙十一大規模落地實踐進行詳細解析。文末包含往期系列文章。node
Service Mesh 是螞蟻金服下一代架構的核心,本次主題主要分享在螞蟻金服當前的體量下,控制面平穩支撐大規模 Sidecar 的落地實踐。聚焦控制面核心組件 Pilot 和 Citadel,分享螞蟻金服雙十一控制面如何管理並服務好全站 Sidecar。git
本次分享主要分爲兩大部分,分別是:github
在開始分享落地實踐以前,咱們先來看看 Istio 的架構圖:緩存
理想很豐滿,現實很骨感。因爲性能等方面的綜合考慮,咱們在落地過程當中,將控制面的組件精簡爲 Pilot 和 Citadel 兩個組件了,不使用因性能問題爭議不斷的 Mixer,不引入 Galley 來避免多一跳的開銷。安全
在架構圖中,控制面組件 Pilot 是與 Sidecar 交互最重要的組件,負責配置轉化和下發,直面 Sidecar 規模化帶來的挑戰。這也是雙十一大促中,控制面最大的挑戰。性能優化
規模化的問題在生產實踐中,是一個組件走向生產可用級的必經之路。接下來將會分別從穩定性、性能優化、監控這三個方面分別展開。網絡
咱們先梳理下 Pilot 提供的服務能力,從功能實現上來看,Pilot 是一個 Controller + gRPC Server 的服務,經過 List/Watch 各種 K8s 資源,進行整合計算生成 XDS 協議的下發內容,並提供 gRPC 接口服務。本次分享咱們先把關注點放在 gRPC 接口服務這個環節,如何保證接口服務支撐大規模 Sidecar 實例,是規模化的一道難題。架構
負載均衡app
要具有規模化能力,橫向擴展能力是基礎。Pilot 的訪問方式咱們採用經常使用的 DNSRR 方案,Sidecar 隨機訪問 Pilot 實例。因爲是長鏈接訪問,因此在擴容時,原有的鏈接沒有重連,會形成負載不均。爲解決這個問題,咱們給 Pilot 增長了鏈接限流、熔斷、按期重置鏈接功能,並配合 Sidecar 散列重連邏輯,避免產生鏈接風暴。負載均衡
爲了下降大量 MOSN 同時鏈接同一個 Pilot 實例的風險,在 gRPC 首次鏈接時,Pilot 增長基於令牌桶方案的流控能力,控制新鏈接的處理響應,並將等待超時的鏈接主動斷連,等待 Sidecar 下一次重連。
基於使用場景的壓測數據,限制單實例 Pilot 同時可服務的 Sidecar 數量上限,超過熔斷值的新鏈接會被Pilot 主動拒絕。
爲了實現負載均衡,對於已經存在的舊鏈接,應該怎麼處理呢?咱們選擇了 Pilot 主動斷開鏈接,不過斷開鏈接的週期怎麼定是個技術活。要考慮錯開大促峯值,退避擴縮容窗口之類,這個具體值就不列出來了,你們按各自的業務場景來決定就行了。
最後還有一點是 Client 端的配合,咱們會控制 Sidecar 重連 Pilot 時,採用退避式重試邏輯,避免對 DNS 和 Pilot 形成負載壓力。
規模化的另外一道難題是怎麼保證服務的性能。在 Pilot 的場景,咱們最關注的固然是配置下發的時效性了。性能優化離不開細節,其中部分優化是通用的,也有部分優化是面向業務場景定製的,接下來會分享下咱們優化的一些細節點。
社區方案裏 Pilot 是經過 Pod.Status 來獲取 Pod 的 IP 信息,在小集羣的測試中,這個時間基本秒級內能夠完成。然而在大集羣生產環境中,咱們發現 Status 的更新事件時間較慢,甚至出現超過 10s 以上的狀況,並且延遲時間不穩定,會增長 Pilot 首次下發的時延。咱們經過與基礎設施 K8s 打通,由 PaaS 側將 Pod 分配到的 IP 直接標記到Pod.Annotation 上,從而實如今第一次獲取 Pod 事件時,就能夠獲取到 IP,將該環節的時延減小到0。
這是一個面向 DBMesh 業務場景的定製性優化,是基於按需獲取的邏輯來實現的。其目的在於解決 DBMesh CR 數量過多,過大致使的性能問題,同時避免 Pilot 因爲 List/Watch CR 資源致使 OOM 問題,Pilot 採用按需緩存和過時失效的策略來優化內存佔用。
社區方案中當 Pilot List/Watch 的資源發生變動時,會觸發所有 Sidecar 的配置推送,這種方案在生產環境大規模集羣下,性能開銷是巨大的。舉個具體例子,若是單個集羣有 10W 以上的 Pod 數量,任何一個 Pod 的變動事件都會觸發所有 Sidecar 的下發,這樣的性能開銷是不可接受的。
優化的思路也比較簡單,若是可以控制下發範圍,那就能夠將配置下發限制在須要感知變動的 Sidecar 範圍裏。爲此,咱們定義了 ScopeConfig CRD 用於描述各種資源信息與哪些 Pod 相關,這樣 Pilot 就能夠預先計算出配置變動的影響範圍,而後只針對受影響的 Sidecar 推送配置。
強管控能力是大促基本配備,咱們給 Pilot Admin API 補充了一些額外能力,支持動態變動推送頻率、推送限流、日誌級別等功能。
安全生產的基本要求是要具有快速定位和及時止血能力,那麼對於 Pilot 來講,咱們須要關注的核心功能是配置下發能力,該能力有兩個核心監控指標:
針對下發的時效性,咱們在社區的基礎上補充完善了部分下發性能指標,以下發的配置大小分佈,下發時延等。
而對於配置準確性驗證是相對比較複雜的,由於配置的準確性須要依賴 Sidecar 和 Pilot 的配置雙方進行檢驗,所以咱們在控制面裏引入了 Inspector 組件,定位於配置巡檢,版本掃描等運維相關功能模塊。
配置巡檢的流程以下:
因爲 Sidecar 的數量較大,Inspector 在巡檢時,支持基於不一樣的巡檢策略執行。大致能夠分爲如下兩類:
Sidecar 基於社區 SDS 方案 (Secret Discovery Service),支持證書動態發現和熱更新能力。同時螞蟻金服是一家金融科技公司,對安全有更高的要求,不使用 Citadel 的證書自簽發能力,而是經過對接內部 KMS 系統獲取證書。同時提供證書緩存和證書推送更新能力。
咱們先來看看架構圖,請看圖:
對總體架構有個大體理解後,咱們分解下 Sidecar 獲取證書的流程,一圖勝千言,再上圖:
補充說明下圖中的每一步環節:
國密通訊是基於 TLS 通訊實現的,採用更復雜的加密套件來實現安全通訊。該功能核心設計是由 Policy 和 Certificate 兩部分組成:
在落地過程當中,僅依靠社區的 PERMISSIVE TLS MODE 還不能知足螞蟻金服可灰度、可監控、可應急的三板斧要求。因此在社區方案的基礎上,引入 Pod 粒度的 Sidecar 範圍選擇能力(也是基於 ScopeConfig ),方案基本以下圖所示:
流程以下:
Citadel Agent 經過 Citadel 去同步 POD 及 CRD 等信息,雖然避免了 Node 粒度部署的 Citadel Agent 對 API Server 的壓力。可是使用 MCP 協議同步數據時,咱們遇到了如下兩個挑戰:
爲了解決以上兩個問題,就須要對 MCP 實現進行改造。改造的目標很明確,那就是減小同步信息量,下降推送頻率。爲此,咱們強化了社區 MCP 的實現,補充了這些功能:
本次大促的控制面的重心在於解決規模化問題,後續控制面將會在服務發現、精細化路由、Policy As Code 等領域深刻探索。咱們將與社區深度合做,控制面將支持經過 MCP 對接多種註冊中心(SOFARegistry(已開源), Nacos等)進行服務發現信息同步,解決大規模服務註冊發現問題,支持增量推送大量 endpoint。同時控制面還能經過加強配置下發能力,爲應用啓動提速,將在 Serverless 極速啓動場景獲取技術紅利。控制面還將結合 Policy As Code,從而更具想象空間,具有極簡建站,默認安全等能力。
到此,本次分享的內容就結束了。Istio 生產級實踐機會可貴,而且任重道遠。最後,歡迎有志之士加入咱們,一塊兒打造世界級規模的 Service Mesh。
本文做者:彭澤文(花名:封塵),螞蟻金服 Mesh 控制面主站負責人,主要 Focus 領域:Service Mesh(SOFAMosn、Istio)。