作者 | 韓堂、柘遠、沉醉
來源 | 阿里巴巴雲原生公眾號
前言
臺灣作家林清玄在接受記者採訪的時候,如此評價自己 30 多年寫作生涯:“第一個十年我才華橫溢,‘賊光閃現’,令周邊黯然失色;第二個十年,我終於‘寶光現形’,不再去搶風頭,反而與身邊的美麗相得益彰;進入第三個十年,繁華落盡見真醇,我進入了‘醇光初現’的階段,真正體味到了境界之美”。
長夜有窮,真水無香。領略過了 K8s“身在江湖”的那種驚心動魄以及它那生態系統的繁花似錦,該是回過頭來體味高可用體系境界之美的時候了。畢竟僅能經得起敲打還是不能獨步武林的!
在 K8s 高可用領域有一個問題被大家所熟知,那就是 K8s 單集群規模帶來的 SLO 問題,如何持續保障?今天就以單集群的規模增長帶來的高可用挑戰來作為引子來給大家一個體感。
ASI 單集群規模支撐超過社區的 5000 臺,這是個非常有意思且具備極大挑戰的事情,對需要進行 K8s 生產化的同學,甚至具備 K8s 生產化經驗的同學來說,一定會是個感興趣的話題。回看 ASI 單集群規模從 100 到 10000 的發展之路,伴隨著業務的增長和創新帶來的每一次集群規模增長,都在逐步使我們的壓力和挑戰發生質變。
ASI:Alibaba Serverless infrastructure,阿里巴巴針對雲原生應用設計的統一基礎設施,ASI 是阿里公共雲服務 ACK 的阿里集團企業版。
大家知道 K8s 社區只能夠支撐五千個節點,當超過這個規模時,會出現各種性能瓶頸問題,比如:
- etcd 出現大量的讀寫延遲。
- kube-apiserver 查詢 pods/nodes 延時很高,甚至導致 etcd oom。
- 控制器無法及時感知數據變化,如出現 watch 數據延遲。
以電商場景為例,100 節點增長到 4 千節點的時候,我們提前針對 ASI apiserver 的客戶端和服務端做了大量的性能優化,從 apiserver 客戶端的角度優先訪問本地 cache,在客戶端去做負載均衡;apiserver 服務端主要做了 watch 優化和 cache 索引優化;在 etcd 內核上利用併發讀提升單 etcd 集群讀處理能力,基於 hashmap 的 freelist 管理新算法提高 etcd 存儲上限,基於 raft learner 技術來提高多備能力等等。
從 4 千節點增長到 8 千節點,我們又做了 qps 限流管理和容量管理優化、etcd 單資源對象存儲拆分、組件規範全生命週期落地通過客戶端的規範約束降低對 apiserver 的壓力和以及穿透到 etcd 的壓力等等。
終於迎來 8 千節點增長到上萬節點的時刻,我們開始如火如荼地開展 etcdcompact 算法優化;etcd 單節點多 multiboltdb 的架構優化,apiserver 的服務端數據壓縮,通過組件治理降低 etcd 寫放大等;同時開始打造常態化的壓測服務能力,持續回答 ASI 的 SLO。
這些例子在高可用挑戰中司空見慣,列出的能力也只是其中一小部分,你也許很難看到能力之間的關聯和底層的演進邏輯。當然,更多的能力建設沉澱到了我們的系統和機制當中。本篇文章會作為一個開始,以綜述的形式分享我們在建設 ASI 全局高可用體系中的幾個關鍵部分,再往後會有針對性地對進行技術點和演進路線的詳解。如果大家有什麼問題或者希望瞭解的部分,歡迎在評論區留言。
ASI 全局高可用概述
高可用是個比較複雜的命題,任何日常的變化例如服務升級、硬件更新、數據遷移、流量突增等都可能造成服務 SLO 受損,甚至不可用。
ASI 作為容器平臺,並非孤立存在,而是與雲底層及公共服務形成完備的生態系統。要解決 ASI 的高可用問題,需要縱觀全局,找出每層的最優解,最終串聯組成最優的整體解決方案。涉及到的層面包括:
- 雲基礎相關管理,包括可用區的選擇,規劃和硬件資產的管理
- 節點的管理
- ASI 集群管理
- 公共服務
- 集群運維
- 應用研發
特別是在 ASI 這個場景下,要支撐的業務集群數量龐大,涉及到的研發運維人員眾多,功能發佈頻繁的迭代開發模式以及業務種類繁多帶來的運行時的複雜多變,相比其他容器平臺來看,ASI 高可用面臨更多的挑戰,其難度不言而喻。
ASI 全局高可用設計
如下圖所示,現階段高可用能力建設整體策略以 1-5-10(故障 1 分種發現、5 分鐘定位、10 分鐘止損)為目標牽引,注重將能力沉澱到系統或機制中,讓 SRE/Dev 能夠無差別的 oncall。
儘量避免發生問題、儘快發現、定位及恢復問題,是實現目標的關鍵,為此我們將 ASI 全局高可用體系的實現分三大部分展開:一是基礎能力建設;二是應急體系建設;三是通過常態化壓測以及故障演練等完成上述能力的保鮮和持續演進。
通過 3 個部分的輪轉驅動,實現一個 ASI 全局高可用體系的構建,其頂層是 SLO 體系和 1-5-10 應急體系。在應急體系和數據驅動的體系背後,我們建設了大量高可用基礎能力,包括防禦體系、高可用架構升級、故障自愈體系、以及持續改進機制。與此同時,我們建立了多個基礎性平臺為高全用體系提供配套能力,如常態化故障演練平臺、全鏈路仿真壓測平臺、告警平臺、預案中心等等。
全局高可用基礎能力建設
在建設全局高可用能力之前,我們的系統在迅速發展和變化下不斷出現事故和險情,需要隔三差五去應急,導致讓問題追身的局面,並且追身後沒高效應對的手段,面臨著幾個嚴峻的挑戰:
- 如何在架構和能力上去提升我們的可用性,降低系統發生故障的概率和影響面?
- 如何在核心鏈路性能和架構上做一些突破,能夠支撐這麼複雜多變的業務場景和業務增長的通用需求?
- 如何讓問題不再追身,做好預防工作,避免應急?
- 如何在應急發生時,能夠快速發現,快速診斷,快速止損?
針對這些問題,並且總結出以下幾個核心原因:
- 可用性能力不足:在集團場景下,組件不斷在變化,不斷增加系統的壓力和複雜度,ASI 在生產可用性的能力上缺失,如限流降級、負載均衡等,組件容易亂用造成低級錯誤,影響集群可用性。
- 系統風控和 pod 保護能力不足:在人為誤操作或系統 bug 時, 容易造成業務 pod 無辜受損或者大面積受損。
- 容量風險:集群數量幾百,組件接近一百;另外歷史問題因 podCIDR 和節點 IP 數的配置,大多 ASI 元集群的節點規模被約束在 128 臺以內,隨著業務快速發展,對容量風險而言存在較大挑戰。
- 單集群規模受限,加上橫向擴展能力不足影響業務發展:單集群不斷增長規模,以及業務類型變化,組件變化都對單集群支撐的最大規模產生影響,對 SLO 持續穩定產生影響。
1. 高可用基礎能力頂層設計
針對這些解決的問題,我們做了高可用基礎能力的頂層設計,這些基礎能力建設整體主要分為幾個部分:
- 性能優化和高可用架構建設:主要是從性能優化和架構升級的角度來提升整個集群支撐的業務類型和業務量。
- 組件規範全生命週期管理:主要從規範的角度在組件的整個生命週期去落地,從出生啟用和集群准入開始,到每一次變更,到下線整個生命週期都要防止組件亂用、野蠻生長、無限膨脹,控制組件在系統可承受範圍之內。
- 攻防體系建設:主要從 ASI 系統本身觸發,在從攻擊和防禦的角度來提升系統的安全,防禦和風控能力。
下面針對我們的一些痛點進行幾個關鍵能力建設的描述。
2. K8s 單集群架構的痛點
- 對 ApiServer 的掌控能力不夠,應急能力不足,我們自己的經歷,歷次集群 Master 出現異常的次數超過 20+,歷次恢復時間最長超過 1 小時。
- ApiServer 是 APIServer 集群的單點,爆炸半徑大。
- 單集群規模大, Apiserver 內存水位比較高,壓力來源於頻繁的查詢,寫入更多更大的資源對象。
- 在業務層缺少跨機房的容災能力,當 ASI 不可用的時候,只能依賴 ASI 的恢復能力。
- 集群規模的持續擴大,離線任務的大量創建和刪除對集群的造成更大壓力。
這裡面從兩個大的角度可以去提高集群架構的可用性,除了在單集群進行架構優化以及性能突破外,還要通過多集群這樣的橫向擴展能力去支撐更大的規模。
- 一是通過聯邦這樣的多集群能力來解決單集群的橫向擴展能力以及單地域跨集群容災能力。
- 另外一個單集群本身的架構還可以從隔離和優先級策略的架構角度來進行差異化 SLO 保障。
3. ASI 架構升級落地
1)APIServer 多路架構升級
核心方案就是通過對 apiserver 進行分組,通過不同的優先級策略進行對待,從而對服務進行差異化 SLO 保障。
-
通過分流以降低主鏈路 apiserver 壓力(核心訴求)
- P2 及以下組件接入旁路 apiserver,並可以在緊急情況(如自身穩定性收到影響)下,做整體限流。
-
旁路 apiserver 配合主鏈路做藍綠、灰度(次級訴求)
- 旁路 apiserver 可以使用獨立版本,增加新功能灰度維度,如使用獨立的限流策略,如開啟新的 feature 功能驗證。
-
SLB 災備(次級訴求)
- 旁路 apiserver 可以在主 apiserver 發生異常時,對外提供服務(需 controller 自行切換目標地址)。
2)ASI 多集群聯邦架構升級
目前張北中心的一個機房就幾萬節點,如果不解決多集群的管理問題,帶來的問題如下:
- 容災層面:把核心交易應用的中心單元部署在一個集群的風險是很大的,最壞情況下集群不可用導致整個應用服務不可用。
- 性能層面:對於業務來說,如因核心應用在某一時點使用時極其敏感而設定各種單機最大限制、CPU 互斥獨佔保證,如果都部署在一個集群的話,會因為集群節點規模限制,導致應用發生堆疊,造成 cpu 熱點,性能不滿足要求;對於 ASI 管控 Master 來說,單集群無限制擴大,性能總會出現瓶頸,總有一天會無法支撐。
- 運維層面:當某個應用擴容發現沒資源,SRE 還得考慮節點加到哪個集群,額外加大了 SRE 集群管理的工作。
因此 ASI 需要達成統一的多集群管理解決方案,幫助上層各個 Pass、SRE、應用研發等提供更好的多集群管理能力,通過它來屏蔽多集群的差異、方便的進行多方資源共享。
ASI 選擇基於社區聯邦 v2 版本來開發滿足我們的需求。
4. K8s 集群遭遇規模增長帶來的極大性能挑戰
在一個大規模的 K8s 集群中性能會遇到哪些問題呢?
- 首先是查詢相關問題。在大集群中最重要的就是如何最大程度地減少 expensive request。對百萬級別的對象數量來說,按標籤、namespace 查詢 Pod,獲取所有 Node 等場景時,很容易造成 etcd 和 kube-apiserver OOM 和丟包,乃至雪崩等問題發生。
- 其次是寫入相關問題。etcd 適用場景是讀多寫少,大量寫請求可能會導致 db size 持續增長、寫性能達到瓶頸被限速、影響讀性能。如大量的離線作業需要頻繁的創建和刪除 pod,通過 ASI 鏈路對 pod 對象的寫放大,最終對 etcd 的寫壓力會放大幾十倍之大。
- 最後是大資源對象相關問題。etcd 適合存儲較小的 key-value 數據,在大 value 下,性能急速下降。
5. ASI 性能瓶頸突破
ASI 性能優化的方向
ASI 的性能優化可以從 apiserver 客戶端、apiserver 服務端、etcd 存儲 3 個方面來進行優化。
- 客戶端側,可以做 cache 優化,讓各個 client 優先訪問本地 informer cache,也需要做負載均衡優化,主要包括對 apiserver,etcd 的負載均衡。同時針對客戶端的各種優化,可以通過組件性能規範,在組件啟用,准入的時候進行校驗是否滿足。
- APIServer 側,可以從訪問層,緩存層,存儲層 3 個層次進行優化。在緩存層,我們重點建設了 cache 的索引優化以及 watch 優化,在存儲層上重點通過 snappy 壓縮算法對 pod 進行數據壓縮,在訪問層上重點建設了限流能力。
- etcd 存儲側的優化,我們也從幾個方面做了很多工作,包括 etcd 內核層面各種算法優化工作,還有通過將不同資源拆分到不同 etcd 集群的能力實現了基本的水平拆分能力,同時也在 etcd server 層做 multi boltdb 的擴展能力提升。
6. K8s 集群的預防能力薄弱
在 K8s 中,kube-apiserver 作為統一入口,所有的控制器/client 都圍繞 kube-apiserver 在工作,儘管我們 SRE 通過組件的全生命週期進行規範約束卡點改進,比如通過在組件的啟用和集群准入階段進行了卡點審批,通過各個組件 owner 的全面配合改造後,大量的低級錯誤得到防範,但還是有部分控制器或部分行為並不可控。
除了基礎設施層面的故障外,業務流量的變化,是造成 K8s 非常不穩定的因素,突發的 pod 創建和刪除,如果不加以限制,很容易把 apiserver 打掛。
另外非法的操作或代碼 Bug 有可能造成業務 pod 影響,如不合法的 pod 刪除。
結合所有風險進行分層設計,逐層進行風險防控。
7. ASI 單集群的預防能力加強
1)支持 API 訪問層的多維度(resource/verb/client)精細化限流
社區早期採用的限流方式主要通過 inflight 控制讀寫總體併發量,我們當時在 apf 沒有出來之前就意識到限流能力的不足,沒有能力去對請求來源做限流。而 apf 通過 User 來做限流(或者說要先經過 authn filter)存在一些不足,一方面因為Authn 並不是廉價的,另外一方面它只是將 API Server 的能力按配置來做分配,並不是一種限流方案和應急預案。我們需要緊急提供一種限流能力,以應對緊急情況,自研了 ua limiter 限流能力,並基於 ua limiter 簡單的配置方式實現了一套限流管理能力,能夠很方便在幾百個集群當中進行默認限流管理,以及完成應急限流預案。
下面是我們自研的 ua limiter 限流方案和其他限流方案的詳細對比:
ua limiter、APF、sentinel 在限流上的側重點是不一樣的:
- ua limiter 是根據 ua 提供一個簡單的 QPS hard limit。
- apf 更加側重於併發度的控制,考慮的是流量的隔離和隔離後的公平性。
- sentinel 功能全面,但是對於公平性的支持並沒有 APF 全面,同時複雜度有一些過高。
考慮我們現階段的需求和場景,發現 ua limiter 落地最為合適,因為我們通過 user agent 的不同,來對於組件進行限流。當然後續進行更加精細的限流,還是可以考慮結合使用 APF 等方案進一步加強。
限流策略如何管理,數百套集群,每套集群規模都不太一樣,集群節點數、pod 數都是不同的,內部組件有近百個,每個組件請求的資源平均有 4 種,對不同資源又有平均 3 個不同的動作,如果每個都做限流,那麼規則將會爆炸式增長,即便做收斂後維護成本也非常的高。因此我們抓最核心的:核心資源 pod\node、核心動作(創建、刪除、大查詢);最大規模的:daemonset 組件、PV/PVC 資源。並結合線上實際流量分析,梳理出二十條左右的通用限流策略,並將其納入到集群交付流程中實現閉環。
當新的組件接入,我們也會對其做限流設計,如果比較特殊的,則綁定規則並在集群准入和部署環節自動下發策略,如果出現大量的限流情況,也會觸發報警,由 SRE 和研發去跟進優化和解決。
2)支持業務 POD 級別的精細化限流
所有 pod 相關的操作都會對接 Kube Defender 統一風控中心,進行秒級別、分鐘級、小時級、天級別的流控。該全局風控限流組件,實行中心端部署,維護各場景下的接口調用限流功能。
defender 是站在整個 K8s 集群的視角,針對用戶發起的或者系統自動發起的有風險的操作進行防護(流控、熔斷、校驗)和審計的風控系統。之所以做 defender,主要從以下幾個方面考慮:
- 類似 kubelet/controller 這樣的組件,在一個集群中存在多個進程,任一單一進程都無法看到全局的視圖,無法進行準確的限流。
- 從運維視角,分散在各個組件中的限速規則難以配置與審計,當部分操作因為限流原因失敗時,排查鏈路過長影響問題定位的效率。
- K8s 面向終態的分佈式設計,每個組件都有決策的能力,那麼就需要一個集中的服務對那些危險決策進行風控。
defender 的框架圖如下所示:
- defender server 是 K8s 集群級的服務,可以部署多個,其中一個 active,其餘 standby。
- 用戶可以通過kubectl配置風控規則。
- K8s 中的組件,例如 controller,kubelet,extension-controller 等,都可以通過 defender sdk 接入 defender(改動很小),在進行危險操作前請求 defender 進行風控,根據風控結果決定是否繼續該危險操作。defender 作為一個集群級的風控防護中心,為 K8s 集群的整體穩定性進行保駕護航。
3)數字化容量治理
在只有幾個 core 集群的場景下,依靠專家經驗管理容量完全可以輕鬆搞定,但隨著容器業務的快速發展,覆蓋泛交易、中間件、新生態、新計算以及售賣區等業務在接入 ASI,短短几年時間就發展了幾百個集群,再發展幾年數以千計萬計?如此多的集群依靠傳統的人肉資源管理方式難以勝任,人力成本越來越高,特別是面臨諸如以下問題,極易造成資源使用率低下,機器資源的嚴重浪費,最終造成部分集群容量不足導致線上風險。
- 組件變更不斷,業務類型和壓力也在變化,線上真實容量(到底能扛多少 qps)大家都不得而知,當業務需要增大流量時是否需要擴容?是否橫向擴容也無法解決問題?
- 早期申請容器資源隨意,造成資源成本浪費嚴重,需要基於容器成本耗費最小化明確指導應該合理申請多少資源(包括 cpu,內存及磁盤)。同一個地域,同一個元集群的業務集群,一個集群浪費了資源就會造成其他集群資源的緊張。
在 ASI 中,組件變化是常態,組件容量如何自適應這種變化也是一個非常大的挑戰。而日常的運維及診斷須要有精準的容量數據來作為備容支撐。
因此我們決定通過數據化指導組件申請合理的(成本低,安全)容器資源。通過數據化提供日常運維所需要的容量相關數據,完成備容,在生產水位異常時,完成應急擴容。
目前我們完成了水位監控、全量風險播報、預調度、profile 性能數據定時抓取、進而通過組件規範中推進 CPU 內存以及 CPU 內存比例優化。正在做的包括自動化的規格建議,節點資源補充建議,以及自動化導入節點,結合 chatops 正在打造釘群“一鍵備容”閉環。另外還在結合全鏈路壓測服務數據,得出各個組件的基線對比,通過風險決策,進行發佈卡點,確保組件上線安全。同時未來會結合線上真實的變更,來持續回答真實環境的 SLO 表現,精準預測容量。
全局高可用應急能力建設
高可用基礎能力的建設可以為 ASI 提供強有力的抗風險保障,從而在各種風險隱患出現時,儘可能保證我們服務的可用性。但是在風險出現後,如何快速介入消滅隱患,或者在高可用能力無法覆蓋的故障出現後,進行有序止損,就變成了一個非常具有技術深度和橫向複雜度的工程難題,也讓 ASI 的應急能力建設成為我們非常重要的投入方向。
在建設應急體系之初,我們的系統由於迅速的發展和變化,不斷出現的事故和險情,明顯的暴露出當時我們面臨的幾個嚴重的問題:
- 為什麼客戶總是早於我們發現問題?
- 為什麼恢復需要這麼長的時間?
- 為什麼同樣的問題會重複出現?
- 為什麼只有幾個人能處理線上的問題?
針對這些問題,我們也進行了充分的腦暴和探討,並且總結出以下幾個核心原因:
- 發現問題手段單一:只有 metrics 數據作為最基本暴露問題的手段。
- 定位問題能力缺乏:只有少數監控大盤,核心組件的可觀測能力建設程度沒有統一。
- 恢復手段缺乏體系:線上問題的修復需要臨時敲命令,寫腳本,效率低且風險大。
- 應急缺少體系規範:缺乏與業務方聯動,工程師思維嚴重,不是以止損為第一目標,對問題嚴重度缺乏意識。
- 長期問題缺乏跟蹤:線上發現的隱患,或者事故覆盤的跟進項,缺乏持續跟進能力,導致重複踩坑。
- 缺乏能力保鮮機制:業務變化非常快速,導致一些能力在一段時間後,進入一個“不會用也不敢用,也不能保證一定能用”的尷尬境地。
1. 應急能力建設頂層設計
針對這些亟待解決的問題,我們也做了應急能力的頂層設計,架構圖如下:
應急能力建設整體可以分為幾個部分:
- 1-5-10 應急體系:針對線上出現的任何突發風險,都能做到“一分鐘發現,五分鐘定位,十分鐘恢復”的底層能力和機制。
- 問題追蹤跟進:針對線上發現的所有風險隱患,無論嚴重與否,都能持續跟蹤推進的能力。
- 能力保鮮機制:針對建設的 1-5-10 能力,鑑於其使用頻率比較低的本質特性。
2. 應急能力建設子模塊建設
針對頂層設計中的每個子模塊,我們都已經做出了一些階段性的工作和成果。
1)一分鐘發現:問題發現能力
為了解決無法早於客戶發現問題的難題,我們的工作最重要的目標就是要做到:讓一切問題都無處遁形,被系統主動發現。
所以這就像是一場持久戰,我們要做的,就是通過各種可能的手段去覆蓋一個又一個新的問題,攻佔一個又一個城池。
在這個目標的驅使下,我們也總結出一套非常行之有效的“戰略思想”,即「1+1 思想」。它的核心觀點在於,任何發現問題的手段,都可能因為對外部的依賴或者自身穩定性的缺陷,導致偶發的失效,所以必須有能夠作為互備的鏈路來進行容錯。
在這個核心思想的指導下,我們團隊建設了兩大核心能力,即黑盒/白盒報警雙通道,這兩個通道的各有各的特點:
- 黑盒通道:基於黑盒思想,從客戶視角把 ASI 整體當做黑盒,直接發出指令,探測正向功能;比如直接擴容一個 statefulset。
- 白盒通道:基於白盒思想,藉助系統內部暴露出來的各種維度的可觀測性數據的異常波動來發現潛在問題;比如 APIServer 的內存異常上漲。
黑盒通道對應的具體產品叫做 kubeprobe,是由我們團隊脫胎於社區 kuberhealthy 項目的思想上進行更多的優化和改造形成的新產品,並且也成為我們判斷集群是否出現嚴重風險的重要利器。
白盒通道的建設相對更為複雜,它需要建設在完備的可觀測數據的基礎之上,才能夠真正發揮它的功力。所以為此我們首先從 metrics、日誌、事件 3 個維度分別基於 SLS 建設 3 種數據通道,將所有可觀測數據統一到 SLS 上管理。另外我們也建設了告警中心,負責完成對當前上百套集群的告警規則的批量管理,下發能力,最終構造了出了一個數據完備,問題覆蓋廣泛的白盒告警系統。最近還在進一步將我們的告警能力向 SLS 告警 2.0 遷移,實現更加豐富的告警功能。
2)五分鐘定位:問題根因自動定位能力
隨著線上問題排查經驗的不斷豐富,我們發現有很多問題會比較頻繁地出現。它們的排查方法和恢復手段基本已經比較固化。即便某個問題背後的原因可能有多種,但是隨著線上排查經驗的豐富,基本都可以慢慢迭代出對這個問題的排查路線圖。如下圖所示,是針對 etcd 集群不健康的告警設計的排查路線:
如果把這些相對比較確認的排查經驗固化到系統中,在問題出現後可以自動觸發形成決策,勢必可以大幅減少我們對線上問題的處理耗時。所以在這個方面,我們也開始了一些相關能力的建設。
從黑盒通道方面,kubeprobe 構建了一套自閉環的根因定位系統,將問題排查的專家經驗下沉進系統中,實現了快速和自動的問題定位功能。通過普通的根因分析樹以及對失敗巡檢探測事件/日誌的機器學習分類算法(持續開發投入中),為每一個 KubeProbe 的探測失敗 Case 做根因定位,並通過 KubeProbe 內統一實現的問題嚴重性評估系統(目前這裡的規則仍比較簡單),為告警的嚴重性做評估,從而判斷應該如何做後續的處理適宜,比如是否自愈,是否電話告警等等。
從白盒通道方面,我們通過底層的 pipeline 引擎的編排能力,結合已經建設的數據平臺中的多維度數據,實現了一個通用的根因診斷中心,將通過各種可觀測數據從而排查問題根因的過程通過 yaml 編排的方式固化到系統中,形成一個根因診斷任務,並且在觸發任務後形成一個問題的診斷結論。並且每種結論也會綁定對應的恢復手段,比如調用預案、自愈等等。
兩種通道都通過釘釘機器人等手段實現類似 chatops 的效果,提升 oncall 人員的處理問題速度。
3)十分鐘恢復:恢復止損能力
為了能夠提升運行時故障的止損恢復速度,我們也把恢復止損能力的建設放在第一優先級,這個方面我們的核心準則是兩個:
- 止損能力要系統化,白屏化,可沉澱。
- 一切以止損為目標,而不是以找到絕對的根因為目標。
所以在這兩個準則的驅使下,我們做了兩個方面的工作:
- 建設預案中心:中心化沉澱我們所有的止損能力到系統中,白屏管理,接入,運行。一方面也可以將以前散落在各個研發手中或者文檔中的預案統一收攏中心端統一管理,實現了對預案的中心化管控。另一方面預案中心也開發了支持用戶通過 yaml 編排的方式來錄入預案的能力,從而實現低成本接入。
- 建設通用止損手段集:根據過往歷史經驗,結合 ASI 的特有特性,建設多種通用的止損能力集合,作為應急時的重要抓手。包括了組件原地重啟,組件快速擴容,controller/webhook 快速降級,集群快速切換隻讀等等常用功能。
4)問題持續跟蹤機制 BugFix SLO
針對缺乏跟進能力的問題,我們提出了 BugFix SLO 機制。正如名字所描述的那樣,我們認為每個發現的問題都是一個要被修復的 “Bug”,並且針對這種 Bug 我們做了一下工作:
- 一方面,定義了一系列分類方法保證問題能夠明確到團隊和具體的一個負責人。
- 一方面,定義解決優先級,即解決這個問題的 SLO,L1 - L4,不同優先級代表不同的解決標準,L1 代表必須當天內迅速跟進並且解決。
每兩週,通過過去一段時間收集的新的問題,我們會產出一份穩定性週報,進行問題解決程度的通晒以及重點問題的同步。另外也會在每兩週進行一次全員拉會對齊,對每個新問題的負責人確定,優先級確認進行對齊。
5)能力驗收保鮮機制
由於穩定性風險是相對低頻發生的,所以對穩定性能力的最好的保鮮手段就是演練,所以在這個基礎之上我們設計或者參與了兩種演練方案,分別是:
- 常態化故障演練機制
- 生產突襲演練機制
【常態化演練機制】
常態化故障演練機制的核心目的在於以更頻繁的頻率對 ASI 系統相關的故障場景以及針對這個故障的恢復能力進行持續驗收,從而既發現某些組件的在穩定性方面的缺陷,也可以驗收各種恢復手段預案的有效性。
所以為了能夠儘可能提升演練頻率,我們:
- 一方面開始建設自身的故障場景庫,將所有場景進行入庫,分類,管理,保證場景的覆蓋面夠全面。
- 另一方面同質量保證團隊合作,充分利用其 chorus 平臺提供的注入故障能力將我們的設計場景逐個落地,並且配置為後臺持續運行。我們還藉助該平臺靈活的插件豐富能力,將平臺同我們的告警系統,預案系統進行 API 對接,在故障場景被觸發注入後,可以完全通過後臺自動調用的模式完整的針對這個場景的注入、檢查、恢復都通過後臺運行完成。
鑑於常態化演練的演練頻率如此之高,我們通常在一個專用的集群中進行持續的後臺演練場景觸發,以降低因為演練帶來的穩定性風險。
【生產突襲演練機制】
常態化故障演練即便做的再頻繁,我們也不能完全保證在生產集群真的出現同樣的問題,我們是否能夠以同樣的方式進行應對;也沒有辦法真正確認,這個故障的影響範圍是否與我們預期的範圍一致;這些問題最根本的原因還是在於我們在常態化故障演練中的集群一般是沒有生產流量的測試集群。
所以在生產環境進行故障模擬才能夠更加真實的反應線上的實況,從而提升我們對恢復手段的正確性的信心。在落地方面,我們通過積極參與到雲原生團隊組織的季度生產突襲活動,將我們一些相對複雜或者比較重要的演練場景實現了在生產環境的二次驗收,與此同時也對我們的發現速度,響應速度也進行了側面評估,不僅發現了一些新的問題,也為我們如何在測試集群設計更符合線上真實情況的場景帶來了很多參考輸入。
寫在最後
本篇僅作為開篇從整體上介紹了 ASI 全局高可用體系建設上一些探索工作以及背後的思考,後續團隊會針對具體的領域比如 ASI 應急體系建設,ASI 預防體系建設,故障診斷與恢復、全鏈路精細化 SLO 建設和運營、ASI 單集群規模的性能瓶頸突破上等多個方面進行深入的解讀,敬請期待。
ASI 作為雲原生的引領實施者,它的高可用,它的穩定性影響著甚至決定著阿里集團和雲產品的業務的發展。ASI SRE 團隊長期招人,技術挑戰和機會都在,感興趣的同學歡迎來撩:[email protected],[email protected]。
數字時代,如何更好地利用雲的能力?什麼是新型、便捷的開發模式?如何讓開發者更高效地構建應用?科技賦能社會,技術推動變革,拓展開發者的能量邊界,一切,因雲而不同。點擊立即報名活動,2021 阿里雲開發者大會將會帶給你答案。