字節跳動混沌工程之雲原生場景實踐

語言: CN / TW / HK

本文將整體介紹字節跳動混沌工程在雲原生場景下的實踐,主要包括混沌工程背景介紹和發展歷程,以及應用韌性增強服務(Application Resilience Enhancement Service,ARES)產品和未來展望。其中將從技術架構、演練流程、核心功能介紹等多個維度,重點展開介紹混沌工程應用韌性增強服務。

混沌工程介紹

1. 混沌工程誕生

微服務拓撲圖

隨着公有云市場的高速增長和雲原生技術的發展,企業用户逐步向雲原生架構遷移,系統內的微服務進一步朝着分佈式的架構演進,微服務數量呈爆炸式增長,各服務間相互調用關係也變得更為繁雜,這對軟件的可靠性提出了更高的要求,而傳統的質量工程和軟件測試已無法檢測出生產環境中的意外故障和性能問題。為了應對愈發複雜的實際生產問題,混沌工程應運而生,它可以幫助用户提前檢測出生產環境中可能潛在的故障和性能問題。

2.混沌工程是什麼

混沌工程是一套通過在系統基礎設施上進行實驗,主動找出系統中脆弱環節的方法學。通過實驗性的方法,發現系統中潛在的、可以導致災難性故障、或讓用户受損的薄弱環節,並推動研發自主地進行問題修復、代碼優化,最終建設成為真正意義上的韌性架構,增加用户抵禦突發事件的能力與信心。

混沌工程最早由 Netflix 在 2008 年開始實踐,通過實踐,Netflix 總結出來混沌工程五大基本原則:

  • 建立服務的穩定狀態假設
  • 多樣化真實世界的事件
  • 生產環境進行實驗
  • 持續自動化運行試驗
  • 最小化“爆炸半徑”

混沌工程與傳統測試

傳統的測試或者 QA 通常包括以下環節:

  • 單元測試:驗證代碼片段的工作是否符合預期。
  • 集成測試:驗證代碼片段和系統中的其他模塊是否能夠一起正常工作。
  • 系統測試:驗證整個系統和設計的行為是否一致。

然而這些傳統的測試只能覆蓋一些應用層面的內容,並不能解決異常場景下更為複雜的問題,如:網絡發生延遲時,服務是否能夠正常工作;服務器宕機時,系統是否能夠切換到備份等。面對上述問題,混沌工程提供系統應對故障、從故障中恢復的能力,幫助我們預先發現潛在風險。

混沌工程與故障注入

混沌工程通常通過注入故障來模擬實驗場景,雖然混沌工程、故障注入和故障測試在側重點和工具集的使用上有一些重疊,但是混沌工程和故障注入本質上是不同的思維方式。

  • 故障注入: 故障注入是基於一個特定的條件、變量的驗證方法。首先要知道會發生什麼故障,然後一個一個地注入。然而在複雜分佈式系統中,無法窮舉所有可能的故障。
  • 混沌工程:混沌工程的思維方式是主動找故障,是探索性的,我們不知道摘掉一個節點、關掉一個服務會發生什麼故障,雖然按計劃做好了降級預案,但是關閉節點時卻引發了上游服務異常,進而引發雪崩,這不是靠故障注入或預先計劃能發現的,它是發現新故障信息的實踐過程。

混沌工程雲原生場景的誕生

混沌工程在字節跳動的實踐主要包括三個階段:

  • 容災演練平台:從 2016 年開始,字節跳動就已經開始建設內部容災演練平台,該平台的主要目標是解決故障注入問題,同時提供基於閾值的簡單指標分析與自動停止。當時容災演練使用的大多是通過網絡干擾模擬下游依賴故障,幫助頭條、抖音等業務方實現了生產環境的容災演練。
  • 混沌工程平台:2019 年字節跳動的混沌工程平台演進到了 2.0 版本。在架構上使得故障注入更加簡單可控,在模型抽象上使得故障注入的擴展性更強,同時結合自動化指標分析能力,嘗試進行強弱依賴分析、超時配置合理性驗證等新的實踐活動。更多字節的業務進行了混沌工程實踐,包括抖音,飛書,西瓜視頻等等。
  • 雲原生產品:在內部實踐中,我們發現很多用户場景是雲原生場景,因此,服務內部業務的同時,輸出了 ToB 高可用產品應用韌性增強服務(ARES)

混沌工程應用韌性增強服務

上面講了字節跳動混沌工程發展的三個階段,三個階段實現能力總結如下:

  • 在第一階段的容災演練平台中,主要聚焦於基本故障注入能力的建設,如網絡延遲,拒絕,丟包這些故障注入能力。
  • 在第二階段的混沌工程平台中,主要在故障注入的基礎上進一步擴展到混沌工程的理念,嘗試了強弱依賴分析,故障指標分析的功能,結合字節的業務進行了更多的實踐。
  • 在第三階段的建設當中,隨着越來越多的應用向着雲原生的架構演進,平台從原來相對單一的微服務場景和單機場景進一步擴展到雲原生場景。在面向雲原生的場景中,對系統架構進行了更加靈活的擴展和升級,比如,把更多平台能力通過雲原生的 controller、DaemonSet 組件來實現,故障定義也以 CRD(Custom Recource Definition)的形式來完成。除此以外,進一步把平台定位推向更加貼近混沌工程原生的理念當中,在平台的實驗編排、故障觀測、故障驗證、穩態假説等功能上進行迭代增強,期望給用户提供更加完整的混沌工程體驗。基於此需求和背景,我們研發了混沌工程應用韌性增強服務產品。

應用韌性增強服務( Application Resilience Enhancement Service,簡稱 ARES)是一款遵循混沌工程實驗原理並融合了內部多年業務實踐的產品。應用韌性增強服務提供豐富故障場景,能夠幫助分佈式系統提升容錯性和可恢復性,增強系統和應用的韌性,滿足用户對系統和應用的高可用需求。

下面將主要介紹 ARES 如何進行落地和實現,以及相關的技術突破。

演練流程

演練流程可以總結為準備實驗、實驗編排、開始實驗、執行實驗、故障結果分析、優化系統六大步驟,下面具體介紹下每個步驟:

  • 準備演練:準備演練方案、演練目標、演練場景、演練影響面等
  • 演練編排:編排要演練的服務、任務串並行、類型、執行情況、實驗時間、頻率等
  • 開始演練:可根據實驗編排,自動開始實驗
  • 執行任務:根據演練任務,對目標進行故障注入,並開啟演練指標採集
  • 結果分析:根據演練的前、中、後三個階段,展示和分析演練對象等相關的指標,自動分析演練結果的有效性
  • 優化系統:根據實驗結果,不斷優化優化,最終建設成為韌性系統

核心功能介紹

上圖主要列了產品的主要功能,支持實驗配置、實驗流程編排、故障觀測、實驗報告與風險統計、演練活動、高可用演練方案、個人工作台等幾大功能。

1. 多集羣演練

隨着服務規越來越大,單個 Kubernetes 集羣支撐的節點數有限,並且用户通常會將控制面和數據面進行分離等,把服務部署在多個集羣上。因此,混沌工程雲原生產品支持了多集羣同時演練的能力,還支持異地多活演練。並支持多集羣統一管理,可以動態增刪多個指定 Kubernetes 集羣,如下圖所示。

2. 多場景需求

分佈式服務和場景越來越複雜,有些用户服務已通過完成雲原生容器化部署和編排,而有些用户只有部分通過實現雲原生改造,部分服務還在虛擬機上。由於服務的特殊性和改造成本,有一大部分用户仍通過物理機或者虛擬機運行服務。針對用户的複雜使用場景和需求,產品支持了多場景的演練。

如上圖所示,ARES 既支持應用服務的演練,也支持基礎設施自身的高可用演練,適用於以下多種場景:

  • 應用服務維度:同時支持通過 Kubernetes 編排的微服務和單機(物理機/虛擬機)部署服務的服務演練
  • 基礎設施:支持 Kubernetes 自身組件(Pod/Service/Node)的演練和單機(物理機/虛擬機)機器的演練

通過故障場景的細分,我們可以精準地控制故障的爆炸半徑,同時我們也支持在數量、比例上進行精確的配置,能夠按照全部、隨機指定個數、指定數量、一定百分比四種模式進行目標選擇。

3. WebShell運維管理

上圖是 WebShell 管理的部分截圖,通常用户注入故障後,故障的有效性和指標,或者產生的日誌,需要登錄機器查看和操作。平台支持通過 WebShell 管理集羣服務的 Pod、Node 節點,並查看對應的日誌信息。可以快速驗證故障是否生效,方便定位問題。

4. 支持故障類型

當前支持的故障能力類型如上圖所示,主要支持網絡、Pod、系統、主機、DNS、Kubernetes、進程、接口、Java、Python、Golang、中間件、自定義故障等幾大故障類型,並且故障類型會持續不斷地豐富。

5. 靈活的用户演練範圍

在網絡服務演練中,根據用户不同需求和不同場景,用户可以選擇在服務的上游或者下游方向進行注入。

6. 流程編排

通過演練流程探索系統的穩定性和缺陷,在提供了核心的故障模擬能力與指標分析能力之後,可以通過演練流程將故障、指標分析、串行或並行執行。

演練流程具備相對固定的步驟:演練開始階段通過系統指令或對硬件設備進行人為干預注入干擾;演練進行中,觀察並收集各類指標的實時變化;演練結束後,分析對比收集的各類指標,評估系統的狀態變化。

7. 故障觀測

故障管控

上圖主要展示故障驗證的監護流程圖,對故障的管控主要分為兩個部分:

  • 故障生命週期管控:通過平台的管控頁面,可以實時看到每一個故障所在的宿主機和 Pod 信息,以及它的運行狀態、開始結束時間等等。通過可視化界面,用户可以用大盤的視角看到每一個故障實驗的運行狀態正常與否,更加安全、放心地進行混沌實驗。
  • 故障驗證:故障注入時,監控指標往往會發生變化,用户常常通過看監控來檢驗故障是否生效,然而在我們過去的實踐當中,常常出現“故障成功注入,但是監控指標卻沒有變化”的情況,原因有很多:比如用户自身的系統做了容災措施,當故障發生時,相關的業務指標依舊正常。為了在此類情況下我們依然可以驗證故障,我們對於每一種故障都會採集相應的驗證指標,此類指標是故障的最直觀反映的指標,基本不會受其他因素干擾,在故障實驗進行時,在頁面上同步展示指標,輔助故障觀測,快速驗證故障的有效性。

故障生效分析

向系統中注入故障後,我們採用AI算法,觀測分析故障是否生效。理論上,我們可以通過對同一個環境注入故障和不注入故障之間的系統差異來觀測故障注入的效果。但事實上,我們不能同時既注入故障,又不注入故障,所以我們無法真實的觀測到這個差異。因此,我們引入因果推斷算法,通過構造貝葉斯結構化時間序列模型,預測反事實條件下(沒有故障注入)的時間序列,並與注入故障後實際觀測到的時間序列比較,計算注入故障對系統的累計因果效應,從而判斷故障是否生效。

上圖中豎直的黑色虛線表示故障注入的時刻,紫色的陰影部分表示藍色虛線的置信區間

上圖從上到下分別展示為:

  • 上半部分 - 黑色實線:指標的真實觀測時間序列,藍色虛線:模型的擬合值
  • 中間部分 - 藍色虛線:真實值與擬合值之間的差異
  • 下半部分 - 藍色虛線:故障發生後,真實值和擬合值差異的累積和,即累積因果效應

實驗可觀測性

如上圖為注入內存故障後,內存使用的數據。在 觀測 頁面查看當前實驗場景的運行結果。目標 Pod 的 Memory 負載在故障注入的一分鐘時間內,到達了預設故障參數值 70% 。實驗結束後可以恢復到正常狀態。

8. 多監控接入

在混沌工程的實驗裏面,可觀測能力是非常重要的一環,而監控指標的獲取和接入是可觀測能力裏面比較基礎的功能。

混沌工程的系統本身不會做過多的監控能力,但為了獲取到混沌實驗觀測中所需要的指標,需要有一個適配層來接入用户的監控系統,以及獲取監控系統的監控指標。而用户所使用的監控系統是多樣的,因此適配層會適配多種主流的監控系統,並轉化成混沌平台上的指標語義。

在 ARES 產品中,用户可以在平台上提前配置好想要觀測的指標,提供指標的類型,名稱,所屬的監控系統類型(如prometheus,zabbix,skywalking等),指標 URL 等。配置完成過後,該指標可以在平台的穩態觀測,指標分析等能力中進行使用。而由於不同監控系統的指標語義有所差異,ARES也會將不同語義的指標進行轉換,統一為平台側的語義,方便進一步的處理和展示。

9. 穩態假設

“圍繞穩態行為進行假設” ,是混沌工程的重要原則之一,也是混沌工程實驗和普通的故障注入,故障演練的重要區別。

穩態觀測的功能是 ARES 裏面對混沌工程原則進行產品化落地的重要實踐,通過對實驗的穩態觀測,使用户的每一次混沌演練都有比較明確的,可以量化的實驗結果。

關於穩態假設的一些概念,我們這樣定義:

  • 穩態:可以量化觀測的對象,比如 QPS ,CPU 使用率,Http 返回碼,Http Reponse 數據;
  • 穩態探測:獲取穩態數據的過程,比如發起 http 請求獲取返回碼,獲取 response 數據;向監控系統發起請求獲取監控數據;通過調用自定義指令獲取指令結果。
  • 假設:對系統行為的“預期”或者“猜測”,更具體的就是對穩態的猜測,比如“QPS會下降”,“CPU使用率會升高”,“Http返回碼從200變成404”等等
  • 穩態算子:對穩態進行的計算操作,簡單的比如“=”算子,用來判斷 http 返回碼是否是200;複雜的比如平均值計算等等

通過穩態假設的能力,我們把傳統的故障注入和故障演練的場景進一步提升,向着混沌工程的理念更進一步,使得故障演練能得到更加直觀的實驗結果。

10. 權限管理

權限管理是 ARES 作為雲產品的基本能力之一。同一個主賬户下,不同子賬户可能是不同的業務部門,不同部門的服務可能會運行在不同集羣,也可能同集羣下相同的 namespace。為了防止各業務賬户故障注入互相影響,我們設計了一套權限管理體系,抽象出 role,permission,resource 等概念,進行權限管理。

  • resource:指資源,ARES 裏面的各種抽象的對象都可作為資源,例如主機管理中的主機,實驗模塊下的場景,實驗等等。
  • permission:權限單元,指對某資源是否有操作權利的表達,“對實驗A有操作權限”則是一個permission。
  • role:指角色,一個賬户可以擁有多個角色,一個角色可以擁有多個權限單元。

基於以上設定,我們提供了權限配置,權限繼承等能力,使得管理員可以方便地對不同賬户,不同資源進行管理。

11. 故障插件

故障插件為用户提供了更加高級,靈活的能力。顧名思義,在故障注入的前,中,後三個階段,我們提供了鈎子,用户可以在這三個階段執行自定義的腳本,使故障實驗更加豐富。

12. 工作台大盤

工作台大盤以數據可視化大盤的形式,為用户提供了高頻實驗故障,高頻實驗集羣,實驗場景執行統計等實驗執行的數據分析和統計的功能。通過大盤,用户可以直觀,快速的瞭解到工作空間內的實驗執行情況。

未來展望

混沌工程是個漫長的探索之旅,故障的模擬和注入只是其中的一部分,我們的最終目標是要通過故障注入實驗,提前發現系統的薄弱環節,降低事故影響,提升系統韌性。基於目前發現的問題和不足之處,我們從多個方面討論未來的期望:

  • 演練可觀測:當前平台已經具備了演練的能力,然而在演練的過程中,難以及時地對故障和演練進行觀察,包括故障的生命週期,相關的服務狀態,主機狀態,爆炸半徑等。未來平台將進一步優化演練的可觀測能力,融入AI能力,能實現對服務拓撲的感知,讓用户在演練的時候實時的看到整個服務集羣的調用拓撲,以及故障注入前後的拓撲變化。

  • 韌性智能分析當前平台主要半自動對故障結果和效果進行分析。未來通過不同維度和不同程度的實驗,對實驗的結果進行數據分析,結合AI智能判斷,評估出系統的韌性度等級和脆弱點,智能生成演練場景,並梳理出系統優化方案,推薦用户進行下次演練,形成演練閉環,增強用户抵禦線上真實突發故障的信心。

  • 更好的安全性和故障能力:如 eBPF 內核技術等新的技術能力,給故障實現帶來更多的可能性,能給我們帶來更加精細化,更加安全,性能更好的故障注入能力。

未來我們將探索更多的故障能力,探索內核,硬件級別的故障。當前業界混沌工程還處在不斷持續探索階段,混沌工程的核心理念尚未體現,因此不斷探索、完善混沌工程,任重而道遠,歡迎大家和我們交流,一起努力共建。

image.png