位元組跳動混沌工程之雲原生場景實踐

語言: 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