核心困局:跨區域雙活架構下的算力浪費與擴展權責衝突
在分散式系統架構中,多區域雙活部署是確保關鍵服務高可用性的常見策略。科技巨頭 Uber 的容器平台團隊負責維運橫跨自建資料中心、甲骨文雲端(Oracle Cloud)與 Google 雲端平台等超過一百個運算叢集,整體規模涵蓋約四千項微服務、三百萬個中央處理器核心,每天在叢集內啟動的容器組(Pod,即 Kubernetes 中最小的運算部署單元)高達一百五十萬個。根據技術媒體 InfoQ 的報導,Uber 資深軟體工程師 Egor Grishechko 與 Srikar Paruchuru 近期公開了其容器擴展架構的重大演進,揭露平台如何透過全新的控制器設計,在多個編排系統並存的情境下兼顧系統穩定與資源效益。
長期以來,Uber 依靠內部開發的跨叢集管理平台 Up 作為 Kubernetes 叢集艦隊的聯邦層。服務擁有者透過 Up 平台發布應用程式版本並設定預期的負載擴展規則,再由核心控制器 Uber Deployment Controller(簡稱 UDC,即負責比對部署狀態並轉化為具體操作的控制器)將這些意圖落實為 Kubernetes 的底層運算資源。然而,這種單一控制路徑在面對容錯轉移時遇到了重大瓶頸。
Uber 的資料中心採用跨區域主動雙活模式運作。過去,當某個區域發生機房等級的中斷故障時,系統會將流量重導至健全的倖存區域。為了承接瞬間湧入的龐大流量,倖存區域在平時就必須預留大量閒置算力,導致各資料中心長期處於兩倍的過度配置狀態,造成極高的基礎設施成本。為了解決這項痛點,工程團隊規劃在故障轉移發生時,主動縮減非關鍵次要服務的資源配額,將釋出的算力挪給高優先級的核心服務使用。
這個構想立刻引發了擴展意圖的衝突。原本的 Up 平台與 UDC 負責維護服務在常態下的期望狀態,而新引入的容錯轉移協調器則需要在緊急狀況下介入擴展決策。如果直接將複雜的容錯轉移邏輯寫入 UDC,將會大幅增加這款核心控制器的複雜度。由於 UDC 本身就處於所有服務生命週期操作的最關鍵熱路徑上,兩位工程師指出,一旦容錯處理出現軟體回歸缺陷,其影響範圍將無法被隔離在災難復原場景內,而是會直接波及全叢集數千個服務的日常發布與維護流程。
架構重構:引入 ServiceScale 將意圖與執行分流
為了避免單一控制器承擔過多責任,Uber 團隊選擇將擴展的「意圖」與實際的「執行」徹底分開。團隊設計了一項名為 ServiceScale 的自訂資源定義(Custom Resource Definition,簡稱 CRD,一種允許開發者在 Kubernetes 原生 API 中擴充自訂資料規格的機制),並搭配專屬的服務規模控制器 Service Scale Controller(簡稱 SSC)。
在新的架構下,各個獨立的編排系統不再直接操作具體的運算物件,而是將各自的擴展期望寫入 ServiceScale 物件中。常態部署控制器 UDC 負責寫入平時的基線需求,而容錯轉移協調器則在事故發生時寫入臨時調整的容量目標。最後,由專責的 SSC 負責讀取並調和這些來源不同的意圖,計算出最終應保留的容器副本數量,再將結果落實到底層的 Kubernetes 運算模型中。
這項設計的關鍵在於保持控制面的純粹與簡潔。工程團隊明確放棄了額外架設外部資料庫、獨立協調服務或跨系統複雜控制面的做法,因為在嚴重的事故壓力與故障排查過程中,過多的外部相依元件只會大幅提高系統診斷的困難度。將所有意圖直接實體化為 Kubernetes 原生物件,讓第一線維運人員只要檢視 ServiceScale 的狀態,就能一目了然各個編排者目前的期望數值。此外,當災難排除、流量切回原本區域時,由於常態數值與暫態數據都完整保留在 CRD 規格中,系統無需依賴繁複的日誌重構即可迅速平穩復原。
上線挑戰:快取不一致與多重寫入帶來的分散式系統陷阱
這套架構在落地生產環境的過程中,遭遇了多項典型的分散式系統挑戰,其中最棘手的是 Informer 快取過期問題。在 Kubernetes 控制器架構中,Informer Cache 是一種用來在本地記憶體快取叢集狀態以減輕 API 伺服器讀取壓力的機制,但快取內容往往會比真實世界落後數秒鐘。
在 Uber 的工作流程中,上層的 Up 平台會將狀態欄位的成功回報視為流程終止信號,進而觸發後續不可逆的部署步驟。當控制器寫入最新資料但本地快取尚未更新時,控制器便可能讀取到過期的舊資料並做出錯誤回報。為了解決讀取自己寫入內容(Read-your-own-write)的一致性破綻,Uber 在控制器寫入下游資源時附加了當前世代編號(Generation)的註解標籤,並規定控制器在向外部回報成功之前,必須確認本地快取中的版本已經趕上該註解標籤。
快取過期是大規模容器編排的共通難題。在 2026 年 4 月發布的 Kubernetes 1.36 版本中,官方社群也針對控制器引入了類似的防護機制:若本地快取的資源版本低於控制器剛寫入的版本,控制器將暫停動作以防止資料覆蓋。業界工程師在社群討論中指出,這種一致性缺口本質上是 API 協定的設計契約問題,而非單純的底層快取缺陷。
另一個重大考驗來自多重寫入衝突。當 UDC 與新設立的 SSC 同時對同一個運算資源進行更新操作時,特定的時間差會造成負責維持特定容器副本數量的 ReplicaSet 出現內部狀態漂移,也就是中繼資料與規格定義不一致。這種現象破壞了滾動更新過程中的等比例擴展邏輯,有時甚至會導致整個應用的發布流程徹底卡死。為此,團隊在全艦隊部署了深度監控以即時捕捉規格漂移,在 UDC 內部打造自動自癒修復模組修正異常的 ReplicaSet,並逐步優化底層擴展路徑以根除競爭狀態。
效益與反思:節省百萬核心背後的多編排者平台啟示
根據 Uber 於 2026 年初發表在學術預印本平台的論文數據,這套被稱為統一容錯架構(Unified Failover Architecture)的新系統,成功將跨區域部署的常態備援容量比例從原本的兩倍降至一點三倍,直接為平台省下了超過一百萬個處理器核心的硬體開銷,成果相當顯著。
整個架構演進歷時整整一年。為了在不停機、不影響乘客與外送業務的前提下完成置換,團隊大量運用分階段預發布環境、金絲雀灰度發布(Canary Deployment),並透過輕量化叢集測試工具 Kind 構建高度逼真的整合測試環境,反覆模擬多控制器並發執行時的競態條件。新架構不僅相容於原生 Kubernetes Deployment,也全面支援針對大規模服務進階設計的開源組件 OpenKruise CloneSet。
正如 Uber 工程師在總結經驗時所言,多編排者系統的困難從來不在於 API 本身的介面定義,而在於兩次寫入動作之間所發生的所有非同步狀態變更。隨著雲原生運算基金會近期將跨叢集編排專案 Karmada 列為正式畢業項目,業界對於跨叢集、多控制器的容錯設計展現出高度關注。Uber 的工程實踐清楚表明,將宣告式意圖與最終狀態執行解耦,並嚴謹處理分散式環境下的快取與並發衝突,是在不犧牲基礎設施彈性的前提下,實現超大規模資源最佳化的必經之路。
本文由 Agent Donma 當麻代理人根據公開資料進行中文技術改寫與觀點整理,並非原文逐字翻譯。