OpenAI故障覆盤|如何保障大規模K8s叢集穩定性

阿里妹導讀
本文透過OpenAI近期遭遇的重大服務中斷事件作為案例,深入分析了Kubernetes (K8s) 架構在大規模叢集環境下的穩定性挑戰,以及阿里雲容器服務與可觀測產品如何保障大規模K8s叢集穩定性的。
作者:
阿里雲容器服務團隊:佳旭、行疾
阿里雲可觀測團隊:凌竹、丹雀、左知
一、前言
Kubernetes(K8s)架構已經是當今IT架構的主流與事實標準[CNCF Survey][1]。隨著承接的業務規模越來越大,使用者也在使用越來越大的K8s叢集。Kubernetes官方建議的最大叢集規模是5000節點[2]。甚至,如OpenAI透過技術最佳化,曾將K8s叢集擴充套件至7500節點[Scaling Kubernetes to 7,500 nodes][3]。這種千級別節點的大規模K8s叢集,會容易引起分散式系統內部瓶頸,但也增加了系統的脆弱性。
1.1. OpenAI故障覆盤分析
近日OpenAI 旗下 AI 聊天機器人平臺 ChatGPT、影片生成工具 Sora 及其面向開發人員的 API 自太平洋時間12月11日下午 3 點左右起發生嚴重中斷。故障的根因是在上線獲取叢集控制面監控資料的新的新可觀測功能時,可觀測的元件會在每個叢集節點上對K8s Resource API發起訪問,突發造成巨大的Kubernetes API負載,導致K8s控制平面癱瘓,進而使DNS服務發現功能中斷,最終影響到了業務。[OpenAI故障報告][4]
1.2. 阿里雲如何保障大規模K8s叢集穩定性,以應對如此故障
這次故障在阿里雲產品體系中直接相關的是阿里雲容器服務(Kubernetes),以及阿里雲可觀測產品(Prometheus、Telemetry)產品。
故,我們對本次OpenAI故障高度重視,希望藉此機會介紹我們在大規模K8s場景下我們的建設與沉澱。以及分享對類似故障問題的應對方案:包括在K8s和Prometheus的高可用架構設計方面、事前事後的穩定性保障體系方面。
阿里雲容器服務團隊(負責Kubernetes雲產品)與阿里雲可觀測團隊(負責Prometheus雲產品)旨在為使用者提供穩定可靠的K8s叢集環境,以及使用可觀測體系幫助使用者構建全面的穩定性保障體系。我們的客戶也有非常多上千節點的大規模K8s叢集環境,在大規模K8s叢集的穩定性保障體系方面有一定經驗沉澱。
OpenAI的大規模叢集故障也是我們很好的學習案例,這裡本文想借助這次案例為契機:
  1. 介紹阿里雲容器服務(K8s)、可觀測團隊(Prometheus)的大規模叢集穩定性建設。
  2. 以及使用者在大規模K8s叢集場景下的最佳實踐,使用者也需要採用正確的使用方式才能一起保障大規模K8s叢集的穩定性。
二、當K8s叢集規模過大會遇到哪些風險與挑戰
K8s叢集控制面/資料面數據流圖
2.1. K8s叢集的本質是分散式系統,剖析其中瓶頸才能對症下藥
首先我們要簡單介紹下K8s叢集控制面、資料面的大致架構:
控制面負責叢集的 API 層、排程、資源管理、雲資源管理等控制面功能,K8s 元件:
apiserver/etcd/scheduler/kube-controller-manger/cloud-controller-manager。
資料面負責叢集的節點管理、Pod 生命週期管理、Service 實現等資料面功能,承載業務Pod的主體。包含:K8s 元件,kubelet/kube-proxy;系統元件,日誌、監控、安全等元件;其他元件,使用者業務元件。
控制面、資料面和雲資源是有機結合的整體!叢集的全鏈路中,任何一個元件、子鏈路成為瓶頸,都可能影響到叢集的整體穩定性。
我們需要從 K8s 系統中發現瓶頸、治理以及最佳化瓶頸,最終實現 K8s 系統在給定雲資源情況下的穩定、高效的利用。
三、穩定性增強 – 阿里雲在大規模K8s叢集場景的保障增強
3.1. 大規模容器服務ACK叢集的穩定性保障機制增強
大規模ACK叢集透過高可用配置、託管元件穩定性增強和系統元件最佳化等綜合技術,對叢集的的穩定性進行全面最佳化和提升。
透過控制面可用區級別和節點級別的高可用配置,全部控制面元件實現高可用打散。以 APIServer 為例,多副本跨 AZ、跨節點高可用部署方式,任何一個 AZ 失效不影響服務可用性。在 3AZ 地域,ACK 託管叢集控制面的 SLA 是 99.95%。對於不具備 3AZ 的地域,ACK 託管叢集控制面 SLA 是 99.5%(不具備單可用區的故障容忍)。
託管核心元件進行彈性、資源隔離、限流、請求處理能力等方面的穩定性最佳化,例如:APIServer支援自動彈性VPA+HPA、etcd支援基於推薦資源畫像的VPA、APIServer的動態限流等等。
ACK系統元件嚴格按照最佳規範進行最佳化和改造,降低對控制面的壓力,包括:對控制面的 LIST 請求、消除對控制面資源消耗大的請求;對非 CRD 資源的 API 序列化協議不使用 JSON,統一使用 Protobuf等等。
3.2. 阿里雲Prometheus對大規模叢集場景的增強
本次導致OpenAI故障的根因是上線新的可觀測能力時發生的,這裡在阿里雲體系中,直接對應著可觀測團隊容器監控產品-阿里雲Prometheus。
阿里雲Prometheus與容器服務一直以來深度合作,對上千節點的大規模K8s場景也有很多深入的沉澱和建設。
不管是本次OpenAI故障直接相關的容器服務K8s控制面觀測能力[5],還是資料可靠性上,還是可觀測元件本身對叢集造成的負載上,都有重點最佳化建設。以下是一些具體的工作內容:

3.2.1. 更智慧的服務發現與多副本採集架構 – 消除熱點

阿里雲 Prometheus 結合支撐眾多阿里雲產品、阿里集團內部大規模生產叢集中可觀測能力建設的多年經驗,首先對採集探針架構完成了升級改造,實現控制本次 OpenAI 所遇到故障爆炸半徑與影響面的目標。
我們採用兩級角色體系解耦了 Prometheus 採集過程中的兩類關注點:
  • Master 角色負責即時地服務發現、任務排程與配置分發
    • 所有標準型別的資源物件資料均透過二進位制 Protobuf 編碼獲取,以便在大規模環境中獲得更好的效能
    • 預設僅一個 Pod 例項對 K8s API Server 建立 List && Watch 通訊,降低 API Server 訪問壓力
    • 在必要情況下透過主備雙副本實現高可用工作
  • Worker 角色負責高效地指標採集、Metric Relabel 處理與資料上報
    • 可依據採集目標規模以及各個目標上暴露的指標量規模進行 Scale Out
    • 由於 Worker 不直接對 K8s API Server 通訊,擴大角色例項數量對 API Server 無影響
(阿里雲Prometheus部署、資料流架構圖)
這正是阿里雲 Prometheus 採集探針相對於目前業界眾多社群開源或商業版本探針的重要區別,該架構實現保障了採集能力的擴充套件絕不會對 API Server 等關鍵元件造成衝擊——並不是直接引入 StatefulSet、DaemonSet 工作負載模式實現多副本的採集。
特別地,透過“配置管理中心”的服務端能力建設解除了配置分發行為對 K8s API Server 的依賴,進一步降低訪問壓力。此外,Master 與 Worker 的自監控指標同步上報雲端儲存,供雲產品工程師即時掌握各採集探針的執行狀況、效能水位與異常資訊,確保及時對故障叢集進行告警與應急。

3.2.2. 適應大規模叢集的 Exporters 最佳化改造 – 減少負載

完成採集探針自身改造,支撐萬級目標穩定高效採集的同時,我們也對 Kubernetes + Prometheus 社群生態中常見 Exporter 在大規模叢集中的執行穩定性進行了重寫與最佳化。
以 kube-state-metrics 為例,作為 K8s 叢集資源可觀測事實意義上的標準,它在面臨海量資源物件(不僅僅 Pod,還有 ConfigMap、Ingress、Endpoint 等)情況下需要更多的記憶體執行資源來避免 OOMKilled,當節點規格限制不足以執行 VPA 操作時,官方推薦方案仍然是透過 StatefulSet 工作負載拉起多個 kube-state-metrics 副本,並且每個例項都對 K8s API Server 執行完整的 List & Watch 訪問後,再透過 Shard Hash 的方式來實現 HPA 的目標——這同樣會釀成本次 OpenAI 的故障。
為此,我們也積極擁抱大資料社群的前沿技術,如:通用記憶體列式資料格式,對 kube-state-metrics 進行重構改寫,獲得更高的資料壓縮比,透過單副本執行即可實現大規模叢集中資源狀態指標的穩定產出,避免造成對 K8s API Server 的訪問壓力。

3.2.3. 實現業務故障隔離的託管採集探針 – 旁路採集方案

傳統 Prometheus 採集探針直接部署在使用者容器叢集內,對叢集內服務發現的採集目標定期抓取指標資料並上報阿里雲 Prometheus 資料閘道器。
雖然雲產品工程師具備對採集探針專業化的運維監控技能,但由於沒有直接操作叢集環境的許可權,以往線上技術支援流程,都依賴將命令發給使用者執行操作,不僅效率低,並且可能遇到交流中理解不一致導致的排查方向錯誤。
另外當災難發生時,由於採集探針與業務同叢集無法正常工作,但災難階段又正是使用者最需要一雙“眼睛”來觀測系統與業務的受損程度的時候。
因而,我們著手轉向 Serverless 這種服務模型。Prometheus 採集探針本質上是個 Probe,不一定要部署在使用者叢集,只要滿足網路打通的條件,所有探針執行在雲產品託管的叢集池中,即可將採集能力 Serverless 化,不僅可降低使用者叢集資源負擔,也有助於提升元件運維的靈活度。

在 OpenAI 本次故障中,由可觀測元件引起 K8s API Server / CoreDNS 服務不可用,同時導致叢集內所有的觀測活動陷入癱瘓,在最需要可觀測的時刻,卻進入了盲區。而使用託管探針模式,則將觀測元件本身與叢集的故障隔離開來。儘管由於 API Server 不可用,無法及時發現新的監控目標,但已排程下發的採集任務仍可繼續執行,資料上報至雲端儲存也不再依賴於叢集內的 CoreDNS。

綜上,使用託管形態的阿里雲 Prometheus 容器監控服務可以遮蔽使用者環境複雜性,元件執行穩定性得到了更好的保障,為更快的災難恢復提供架構支撐,在這種災難性故障下,託管探針模式的阿里雲 Prometheus 容器監控服務依然能夠確保一定程度的資料完整性。

3.2.4. 可靠的資料鏈路 – "out-of-band" 帶外資料鏈路建設

可觀測性的另一個挑戰是,監控採集元件如果部署在使用者叢集側,當叢集環境出現問題時,監控系統也會一併宕掉,不能起到觀測異常現場的作用。
阿里雲容器服務透過建設“帶外資料鏈路(out-of-band)”來解決此問題。

3.2.4.1. ControlPlane元件自身監控資料的帶外資料鏈路

反映叢集穩定性的關鍵指標、ControlPlane元件的監控指標[6]資料,透過託管側的元件透出資料,不受叢集本身環境影響,我們內部稱為“帶外資料鏈路(out-of-band)”。當叢集本身異常時,只會影響和叢集內部環境相關的“帶內鏈路(in-band)”,而不會影響這些“帶外資料鏈路(out-of-band)”。保證了叢集穩定性的關鍵資料的可靠性。
阿里雲容器服務託管叢集,透過部署單獨的元件監控ControlPlane元件自身的監控資料。當關鍵控制面元件異常時,保證監控資料的可靠性。

3.2.4.2. 容器層以下的節點的虛擬機器、硬體、作業系統層問題的帶外資料鏈路

同理,叢集關鍵元件的事件、能感知叢集中的節點(ECS)底層異常的主動運維事件,也透過“帶外資料鏈路”(out-of-band)直接寫入到使用者的SLS事件中心中。
以此方案形成與使用者叢集環境完全解耦的資料來源、資料採集鏈路,保證監控資料的可靠性。
參考文件:容器服務託管節點池[7]對ECS系統事件[8]的透出。
四、最佳實踐 – 使用者如何正確地使用大規模K8s叢集
K8s本質是一個非常易用的分散式系統,分散式系統由於PAC原則,永遠都存在承載能力的上限。
這裡就還是需要K8s叢集的使用者,不管作為K8s元件開發者,還是K8s運維人員,採用正確的使用方式來使用K8s叢集,才能在千級別節點的大規模K8s叢集中保證叢集的穩定性。
在此經過阿里雲容器服務團隊的經驗沉澱,我們提供涵蓋事前預防觀測、事後快速定位和恢復的成熟產品能力,幫助使用者構建叢集穩定性運維體系。
4.1. 叢集規模控制(容量規劃) & 正確的釋出流程(安全釋出流程)
首先,站在運維的角度來看,我們需要時刻考慮減小爆炸半徑。
首先當用戶的業務規模還未發展成需要一個大規模K8s叢集來承載的程度時,我們建議使用者透過合理的容量規劃來控制叢集規模的大小,如可以透過微服務架構等方式,拆分業務的部署結構在不同的叢集上,以此來減小K8s規模。
其次,站在釋出的安全生產流程上,我們需要考慮可灰度、可回滾、可監控的安全釋出最佳實踐。且每批灰度間隔需要充分觀測邏輯是否符合預期,且在觀測到異常問題後應該馬上回滾。
4.2. 事前 – 觀測能力 與 關鍵報警配置

4.2.1. 成熟的叢集控制面觀測能力

首先使用者可以透過我們阿里雲容器服務提供的叢集ControlPlane觀測能力,清晰感知到叢集控制面元件的當前狀態。我們提供ACK叢集控制面監控大盤[9],以及控制面元件日誌監控[10]功能,幫助使用者清晰透明地觀測叢集穩定性問題。
檢視ACK叢集控制面監控大盤)[11]
在我們遇到的典型大規模叢集故障場景,如下圖:
  • 場景1:使用者側元件異常請求氾濫,導致APIServer負載過高;
  • 場景2:大請求導致的K8s叢集SLB頻寬被打滿,導致APIServerRT飆升、或者只讀請求飆升。
我們可以透過叢集控制面觀測能力剖析問題,樣例如下:
上面可觀測能力可以幫助決策出精準的診斷路徑:
【問題快速發現】依據 API-Server指標水位進行問題定位。
【根因快速定位】依據 API-Server 訪問日誌定位問題瓶頸應用,並精準降級,詳見本文4.3.4節,如何快速定位對控制面元件造成主要壓力的“元兇”請求元件,並快速降級。
【止血 / 閉環問題】停止 / 最佳化應用的List-Watch 資源行為、效能,最佳實踐參考本文4.2.3節,阿里雲的元件穩定性最佳化。

4.2.2. 經歷經驗沉澱的關鍵報警規則

雖然有強大的可觀測能力,但使用者不可能每時每刻盯著監控大盤,阿里雲容器服務報警中心功能[12]為客戶提供經過經驗沉澱的K8s叢集運維關鍵報警規則模版。
其中包括上文所提到的叢集核心元件異常報警規則,可以覆蓋如ControlPlane元件異常、APIServer的SLB頻寬打滿等場景的預警。
非常推薦使用者確保這些報警規則開啟並訂閱通知到負責叢集運維的SRE人員。您只需要購買叢集時預設開啟報警規則;或在容器服務控制檯,運維管理->報警配置中開啟規則並新增通知物件即可訂閱。

4.2.3. 開發K8s元件的最佳實踐

4.2.3.1. 規範元件 LIST 請求

必須使用全量 LIST 時新增 resourceVersion=0,從 APIServer cache 讀取資料,避免一次請求訪問全量擊穿到 etcd;從 etcd 讀取大量資料,需要基於 limit 使用分頁訪問。加快訪問速度,降低對控制面壓力。

4.2.3.2. 序列化編碼方式統一

對非 CRD 資源的 API 序列化協議不使用 JSON,統一使用 Protobuf,相比於 JSON 更節省傳輸流量。

4.2.3.3. 優選使用 Informer 機制

大規模場景下,頻繁 LIST 大量資源會對管控面 APIServer 和 etcd 產生顯著壓力。頻繁 LIST 的元件需要切換使用 Informer 機制。基於 Informer 的 LIST+WATCH 機制優雅的訪問控制面,提升訪問速度,降低對控制面壓力。

4.2.3.4. 客戶端訪問資源頻度

客戶端控制訪問大規模全量資源的頻度,降低對管控的資源和頻寬壓力。

4.2.3.5. 對 APIServer 訪問的中繼方案

大規模場景下,對於 Daemonset、ECI pod 等對 APIServer 進行訪問的場景,可以設計可橫向擴容的中繼元件,由中繼元件統一訪問 APIServer,其他元件從中繼元件獲取資料。例如 ACK 的系統元件 poseidon 在 ECI 場景下作為 networkpolicy 中繼使用。降低管控的資源和頻寬壓力,提升穩定性。
當前阿里雲Prometheus也是採用此類中繼邏輯來減少的叢集負載,從而避免隨K8s和部署應用的規模笛卡爾積式地增大對叢集的負載,當然此類中繼邏輯都需要針對元件定製開發。
4.3. 事後 – 快速恢復與止血
K8s故障的應急處理與快速恢復,不僅需要建立常態化的故障演練和應急支撐機制,還應涵蓋從故障發生到恢復的全鏈路響應流程,包括故障的即時監測、精準定位,以及問題的及時解決。

4.3.1. 定期演練和應急預案

需要透過定期開展演練與評估,持續最佳化和演進應急預案,可以提升整體故障應對能力和恢復速度,減少故障對業務的影響時長和嚴重程度。這種系統性的能力建設,將為K8s環境的穩定性和可靠性提供強有力的保障。
從具體應急措施的角度,控制面由於請求壓力過大導致出現無響應、OOM甚至雪崩,本質上需要限制請求,尤其是LIST大量資源的請求,這些請求處理的過程中對etcd和apiserver都會帶來顯著的開銷;apiserver作為etcd的一種快取,叢集中全部資源會快取在apiserver記憶體中,與此同時請求到達apiserver後,apiserver處理請求過程中產生的編解碼也會佔用快取,如果請求頻繁而且請求資源數量巨大,都會導致控制面apiserver記憶體驟增。
同時,在有條件的情況下,儘量擴容Master節點/元件記憶體和CPU資源。在實際應急中,這個措施出於硬體資源的限制不總是能滿足,此時就需要更加依靠限流策略應急。

4.3.2. 應急的限流策略

應急的限流策略包括(1) 降低apiserver inflight request引數,需要重啟APIServer 或者(2)根據監控發現訪問壓力過大的請求,下發在故障演練充分驗證過的APF限流規則,包括針對指定UA(例如OpenAI案例中的Telemetry元件對應的UA)實現動態生效的限流效果。

4.3.3. CoreDNS快取策略可能會造成誤導

注意,不建議做CoreDNS的永久快取[13](serve_stale開啟),當真實發生叢集控制面異常時,延長CoreDNS內的快取並不能延續業務Pod的正常運轉狀態,CoreDNS內過期快取的DNS解析關係會讓業務Pod發起的訪問觸達到完全錯誤的IP地址。
並且CoreDNS的快取時長會一定程度上掩蓋控制面元件已經異常的現象,造成叢集還正常運轉的假象,增加排查難度與排查時間。

4.3.4. 快速定位對控制面元件造成主要壓力的“元兇”請求元件,並快速降級

如何透過控制面監控大盤,定位到主要壓力來源。
透過daemonset方式部署的元件,並對叢集控制面有高頻率、大範圍的list、watch請求是我們所遇到的叢集控制面故障的最大元兇。
(阿里雲容器服務APIServer監控大盤的客戶端粒度分析)
阿里雲容器服務APIServer監控大盤,提供追溯呼叫來源方client/操作資源resource/操作行為verb等細粒度指標。
幫助K8s叢集使用者在出現控制面高負載預警或故障時能準確定位到大負載壓力的來源,並幫助決策快速降級掉“元兇”應用,快速恢復整個叢集穩定性。

4.3.5. admission controller (准入控制器) 造成的壓力

K8s提供動態准入(Dynamic Admission Control)能力,由admissionwebhook配置以及admissioncontroller組成,是K8s非常傑出的機制,能像AOP一樣幫助進行叢集資源生命週期的改造行為。
但是admissionwebhook是第二大部分我們遇到的叢集控制面故障的元兇,admissionwebhook由於會把使用者自定義行為加入到K8s關鍵的資源生命週期中,可能加大K8s叢集本身的不穩定性。同時由於admissionwebhook會攔截所有監聽的k8s物件的請求,若定義不當,admissionwebhook在大規模K8s叢集下會產生海量的APIServer負擔。阿里雲容器服務的控制面監控大盤專門設計,希望透過控制面監控大盤,定位到admission controller造成的壓力。
(阿里雲容器服務APIServer監控大盤的准入控制 admissionwebhook負載分析)
五、總結
K8s是業界主流的基礎設施架構,Prometheus也已經成為新一代指標監控的實施標準,我們面對的是巨大的客戶體量,超大規模的K8s叢集可能遇到的風險及挑戰是不可避免的。
我們只有持續關注故障沉澱下來的經驗,希望透過一次次故障事件學習並自審,不斷最佳化,才能在應對挑戰時更加從容,以求更好地為使用者提供更穩定、更可靠的基礎設施。
參考連結:

[1]https://www.cncf.io/reports/cncf-annual-survey-2023/

[2]https://aliyuque.antfin.com/op0cg2/nwsq63/Scaling%20Kubernetes%20to%207,500%20nodes

[3]https://openai.com/index/scaling-kubernetes-to-7500-nodes/

[4]https://status.openai.com/incidents/ctrsv3lwd797

[5]https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/monitor-control-plane-components/

[6]https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/monitor-control-plane-components/

[7]https://www.alibabacloud.com/help/zh/ack/ack-managed-and-ack-dedicated/user-guide/overview-of-managed-node-pools

[8]https://www.alibabacloud.com/help/zh/ecs/user-guide/overview-of-ecs-system-events

[9]https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/view-control-plane-component-dashboards-in-ack-pro-clusters

[10]https://www.alibabacloud.com/help/zh/ack/ack-managed-and-ack-dedicated/user-guide/collect-control-plane-component-logs-of-ack-managed-cluster

[11]https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/view-control-plane-component-dashboards-in-ack-pro-clusters

[12]https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/alert-management

[13]https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/dns-resolution-policies-and-caching-policies
線上業務一站式效能最佳化
使用DCDN來同時加速源站的動態資源和靜態資源,一方面透過全球分散式快取來提高靜態內容分發速度,另一方面透過動態選路技術來提高動態內容全鏈路傳輸速度。   
點選閱讀原文檢視詳情。

相關文章