混沌網格(Chaos Mesh)的設計和工作原理

原文發表於kubernetes中文社區,爲作者原創翻譯 ,原文地址

更多kubernetes文章,請多關注kubernetes中文社區

目錄

爲什麼選擇混沌網格(Chaos Mesh)?

混沌網格(Chaos Mesh)可以做什麼?

混沌網格(Chaos Mesh)設計

專爲Kubernetes設計

CustomResourceDefinitions設計

混沌網格(Chaos Mesh)如何工作?

Controller-manager

Chaos-daemon(混沌守護進程)

Sidecar

運行混亂

準備環境

使用YAML文件運行混亂

部署一個名爲“ chaos-demo-1”的TiDB集羣。你可以使用TiDB Operator來部署TiDB

創建名爲“ kill-tikv.yaml”的YAML文件:

保存文件。

開始混亂,kubectl apply -f kill-tikv.yaml

使用Kubernetes API運行混亂

Chaos Mesh未來何去何從?


爲什麼選擇混沌網格(Chaos Mesh)?

在分佈式計算的世界中,故障可能隨時隨地發生在你的集羣上。傳統上,我們使用單元測試和集成測試來確保系統可以投入生產。但是,隨着集羣規模的擴大,複雜性的增加以及數據量以PB級增長,這些測試無法涵蓋所有內容。

爲了更好地識別系統漏洞並提高彈性,Netflix發明了Chaos Monkey,該技術將各種類型的故障注入基礎架構和業務系統。這就是混沌工程的開始。

PingCAP上,我們的產品TiDB(開源的分佈式NewSQL數據庫)遇到了同樣的問題。容錯性和彈性是頭等大事,因爲對於任何數據庫用戶來說,最重要的資產—數據本身—都處於危險之中。

我們已經在測試框架中內部 實踐了Chaos Engineering已有一段時間了。但是,隨着TiDB的增長,測試要求也隨之提高。

我們意識到,我們不僅需要TiDB,而且還需要其他分佈式系統的通用混沌測試平臺。考慮到這一點,我們開發了Chaos Mesh,這是一個雲原生的Chaos Engineering平臺,可在Kubernetes環境中協調混沌實驗。這是一個開源項目:https://github.com/pingcap/chaos-mesh

在以下各節中,我將與你分享什麼是Chaos Mesh以及我們如何設計和實現它。

混沌網格(Chaos Mesh)可以做什麼?

Chaos Mesh包括針對Kubernetes上複雜系統的故障注入方法,並涵蓋了Pod,網絡,文件系統甚至內核中的故障。

這是我們如何使用Chaos Mesh定位TiDB系統錯誤的示例。

我們使用分佈式存儲引擎(TiKV)模擬了Pod的停機時間,並觀察了每秒查詢量(QPS)的變化。通常,如果一個TiKV節點發生故障,則QPS在恢復正常前可能會經歷短暫的抖動。這就是我們保證高可用性的方式。

從儀表板可以看到:

  • 在前兩個停機時間中,QPS在大約一分鐘後恢復正常。
  • 但是,在第三次停機後,QPS需要更長的時間才能恢復-大約9分鐘。如此長的停機時間是無法預料的,並且肯定會影響在線服務。

經過診斷後,我們發現在處理TiKV停機時間時,TiDB集羣版本(V3.0.1)存在一些棘手的問題。我們在更高版本中解決了這些問題。

除了模擬停機時間之外,Chaos Mesh還包括以下故障注入方法:

  1. pod-kill: 模擬Kubernetes Pod被殺死
  2. pod-failure: 模擬Kubernetes Pod長時間不可用
  3. 網絡延遲: 模擬網絡延遲
  4. 網絡丟失: 模擬網絡數據包丟失
  5. 網絡複製: 模擬網絡數據包複製
  6. 網絡損壞: 模擬網絡數據包損壞
  7. 網絡分區: 模擬網絡分區
  8. I/O延遲: 模擬文件系統I/O延遲
  9. I/O 錯誤: 模擬文件系統I/O錯誤

混沌網格(Chaos Mesh)設計

Chaos Mesh專爲Kubernetes設計。混沌網格:

  • 不需要特殊的依賴關係,因此可以將其直接部署在Kubernetes集羣(包括Minikube)上。
  • 無需修改被測系統(SUT-- the system under test )的部署邏輯,因此可以在生產環境中執行混亂的實驗。
  • 利用現有的實現,以便可以輕鬆擴展故障注入方法。
  • 與其他測試框架集成。

專爲Kubernetes設計

在容器世界中,Kubernetes是絕對的領導者。本質上,Kubernetes是用於雲的操作系統。

TiDB是雲原生的分佈式數據庫。我們的內部自動化測試平臺從一開始就是在Kubernetes上構建的。我們每天在Kubernetes上運行數百個TiDB集羣,以進行各種實驗,包括廣泛的混沌測試,以模擬生產環境中的各種故障或問題。爲了支持這些混沌實驗,將混沌和Kubernetes結合起來成爲我們實現的自然選擇和原則。

CustomResourceDefinitions設計

混沌網格(Chaos Mesh)使用CustomResourceDefinitions(CRD)定義混沌對象。

在Kubernetes領域,CRD是用於實現自定義資源的成熟解決方案,具有豐富的實現案例和工具集。使用CRD可使Chaos Mesh與Kubernetes生態系統自然融合。

代替使用統一的CRD對象中定義所有類型的故障注入,我們允許針對不同類型的故障注入使用靈活且獨立的CRD對象。如果添加符合現有CRD對象的故障注入方法,則可以直接基於此對象進行縮放;如果這是一種全新的方法,我們將爲其創建一個新的CRD對象。

通過這種設計,可以從頂層提取混亂的對象定義和邏輯實現,從而使代碼結構更清晰。這種方法還降低了耦合程度和出錯的可能性。此外,Kubernetes的控制器運行時是實現控制器的絕佳包裝。這節省了很多時間,因爲我們不必爲每個CRD項目重複實現同一組控制器。

Chaos Mesh實現PodChaos,NetworkChaos和IOChaos對象。這些名稱清楚地標識了相應的故障注入類型。

例如,在Kubernetes環境中,Pod崩潰是一個非常普遍的問題。許多本機資源對象會通過典型操作(例如創建新的Pod)自動處理此類錯誤。我們的應用程序真的可以處理此類錯誤嗎?如果Pod無法啓動怎麼辦?

通過定義明確的動作(例如“ pod-kill ”),PodChaos可以幫助我們有效地查明此類問題的原因。PodChaos對象使用以下代碼:

spec: 
 action: pod-kill 
 mode: one 
 selector:   
   namespaces:     
     - tidb-cluster-demo
   labelSelectors:
     "app.kubernetes.io/component": "tikv"
  scheduler:
   cron: "@every 2m"

此代碼執行以下操作:

  • “action “屬性:定義要注入的特定錯誤類型。在這種情況下,“ pod-kill”會隨機殺死Pod。
  • “selector ”屬性:限制了混沌實驗的範圍。在這種情況下,範圍是TiDB集羣下名稱空間爲“ tidb-cluster-demo”的TiKV Pods。
  • “ scheduler ”屬性:定義每個混亂故障操作的間隔。

有關CRD對象(如NetworkChaos和IOChaos)的更多詳細信息,請參見Chaos-mesh文檔

混沌網格(Chaos Mesh)如何工作?

解決了CRD設計問題後,讓我們看一下Chaos Mesh的工作原理。涉及以下主要組件:

Controller-manager

充當平臺的“大腦”。它管理CRD對象的生命週期並安排混亂實驗。它具有用於調度CRD對象實例的對象控制器,而admission-webhooks控制器可將邊車容器動態注入Pod

Chaos-daemon(混沌守護進程)

作爲特權daemonset 運行,可以在節點和Cgroup上操作網絡設備。

Sidecar

作爲一種特殊類型的容器運行,該容器由admission-webhooks動態注入到目標Pod中。例如,“ chaosfs”邊車容器運行一個fuse-daemon來劫持應用程序容器的I/O操作。

混沌網格工作流程

 

以下是這些組件簡化混亂實驗的方式:

  1. 用戶使用YAML文件或Kubernetes客戶端,創建或更新混亂對象到Kubernetes API服務器。
  2. Chaos Mesh使用API服務器來監視混沌對象,並通過創建,更新或刪除事件來管理混沌實驗的生命週期。控制器管理器,chaos-daemon和sidecar容器一起工作以注入錯誤。
  3. 當admission-webhooks收到Pod創建請求時,將動態更新要創建的Pod對象。例如,將其注入邊車容器和Pod中。

運行混亂

現在讓我們開始展示如何使用Chaos Mesh。請注意,混亂的測試時間可能會有所不同,具體取決於要測試的應用程序的複雜性以及CRD中定義的測試計劃規則。

準備環境

Chaos Mesh在Kubernetes v1.12或更高版本上運行。Helm是Kubernetes的軟件包管理工具,用於部署和管理Chaos Mesh。在運行Chaos Mesh之前,請確保在Kubernetes集羣中正確安裝了Helm。要設置環境,請執行以下操作:

1. 確保你具有Kubernetes集羣。如果已經有,請跳至步驟2;否則,請使用Chaos Mesh提供的腳本在本地啓動一個:

// install kind 
curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.6.1/kind-$(uname)-amd64 
chmod +x ./kind 
mv ./kind /some-dir-in-your-PATH/kind 
// get script 
git clone https://github.com/pingcap/chaos-mesh 
cd chaos-mesh 
// start cluster 
hack/kind-cluster-build.sh

注意:本地啓動Kubernetes集羣會影響與網絡相關的故障注入。

2. 如果Kubernetes集羣已準備就緒,請使用HelmKubectl部署Chaos Mesh:

git clone https://github.com/pingcap/chaos-mesh.git 
cd chaos-mesh 
// create CRD resource 
kubectl apply -f manifests/ 
// install chaos-mesh helm install 
helm/chaos-mesh --name=chaos-mesh --namespace=chaos-testing

等待所有組件安裝完畢,然後檢查安裝狀態:

// check chaos-mesh status 
kubectl get pods --namespace chaos-testing -l app.kubernetes.io/instance=chaos-mesh

如果安裝成功,則可以看到所有Pod已啓動並正在運行。現在,該玩了。

你可以使用YAML定義或Kubernetes API運行Chaos Mesh。

使用YAML文件運行混亂

你可以通過YAML文件方法定義自己的混亂實驗,該方法提供了一種在部署應用程序後進行混亂實驗的快速便捷的方法。

要使用YAML文件運行混亂,請執行以下步驟。

注意:出於說明目的,我們將TiDB用作我們的測試系統。你可以使用自己選擇的目標系統,並相應地修改YAML文件。

  1. 部署一個名爲“ chaos-demo-1”的TiDB集羣。你可以使用TiDB Operator來部署TiDB。

  2. 創建名爲“ kill-tikv.yaml”的YAML文件,並添加以下內容:

    apiVersion: pingcap.com/v1alpha1
    kind: PodChaos 
    metadata:
      name: pod-kill-chaos-demo
      namespace: chaos-testing
    spec:
      action: pod-kill
      mode: one
      selector:
        namespaces:
          - chaos-demo-1
        labelSelectors:
          "app.kubernetes.io/component": "tikv"
      scheduler:
        cron: "@every 1m"
  3. 保存文件。

  4. 開始混亂,kubectl apply -f kill-tikv.yaml。

以下混亂實驗模擬了在“ chaos-demo-1”集羣中經常被殺死的TiKV Pod:

混沌實驗運行

 

我們使用sysbench程序來監視TiDB集羣中的實時QPS變化。當我們向集羣中注入錯誤時,QPS會顯示劇烈的抖動,這意味着已刪除特定的TiKV Pod,然後Kubernetes重新創建了一個新的TiKV Pod。

你可以在此處找到更多YAML文件示例。

使用Kubernetes API運行混亂

Chaos Mesh使用CRD定義混沌對象,因此你可以直接通過Kubernetes API操作CRD對象。這樣,通過自定義的測試場景和自動混沌實驗,將Chaos Mesh應用於你自己的應用程序非常方便。

在這個測試基礎項目中,我們模擬了Kubernetes上ETCD集羣中的潛在錯誤,包括節點重啓,網絡故障和文件系統故障。

以下是使用Kubernetes API的Chaos Mesh示例腳本:

import (
    "context"
  "github.com/pingcap/chaos-mesh/api/v1alpha1"
    "sigs.k8s.io/controller-runtime/pkg/client"
 )
 func main() {  
   ...
   delay := &chaosv1alpha1.NetworkChaos{
   Spec: chaosv1alpha1.NetworkChaosSpec{...},
       }
​
   k8sClient := client.New(conf, client.Options{ Scheme: scheme.Scheme })
   k8sClient.Create(context.TODO(), delay)
   k8sClient.Delete(context.TODO(), delay)
 }

Chaos Mesh未來何去何從?

本文向你介紹了Chaos Mesh,這是一個開源的雲原生Chaos Engineering平臺。仍有許多工作正在進行中,還有更多有關設計,用例和開發的詳細信息。敬請關注。

開源僅僅是一個起點。除了我們前面討論的基礎架構級別的混亂實驗之外,我們還在以更精細的粒度支持更廣泛的故障類型,例如:

  • 在eBPF和其他工具的幫助下,在系統調用和內核級別注入錯誤。
  • 通過集成failpoint將特定的錯誤類型注入應用程序功能和語句級別,這將覆蓋傳統注入方法無法實現的方案。

展望未來,我們將不斷改進Chaos Mesh儀表板,以便用戶可以輕鬆查看故障注入是否以及如何影響其在線業務。此外,我們的路線圖還包括一個易於使用的故障協調界面。我們正在計劃其他很棒的功能,例如Chaos Mesh Verifier和Chaos Mesh Cloud。

GitHub:https : //github.com/pingcap/chaos-mesh

譯文鏈接: https://dzone.com/articles/chaos-mesh-a-chaos-engineering-solution-for-system

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章