導論:擁抱混亂,提升雲原生應用的彈性

在動態多變的雲原生環境中,應用程式隨時可能面臨各種不可預測的挑戰。網路中斷、節點故障、資源耗盡等問題都可能導致服務中斷,影響使用者經驗。混沌工程提供了一種主動應對這些挑戰的方法,透過模擬真實世界的故障場景,幫助我們及早發現系統的弱點,並採取相應的措施提高系統的彈性和可靠性。

本文將探討如何在 Kubernetes 環境中實施混沌工程,利用 Chaos Toolkit 和 Istio 等工具,引導您設計和執行混沌實驗,增強應用程式的彈性。

混沌工程原則:在可控的混亂中探索系統極限

混沌工程並非隨機製造混亂,而是根據一套嚴謹的原則和方法論。以下列出幾個核心原則:

  • 定義穩態假設: 在進行混沌實驗之前,必須先定義系統在正常狀態下的行為,例如服務的可用性、延遲、錯誤率等指標。這些指標將作為評估實驗影響的基準。
  • 多樣化實驗設計: 設計多樣化的實驗場景,模擬各種可能的故障情況,例如網路延遲、節點故障、磁碟空間不足等。
  • 漸進式實驗方法: 從小規模、低風險的實驗開始,逐步增加實驗的強度和範圍,避免對生產環境造成重大影響。
  • 持續監控和分析: 在實驗過程中,持續監控系統的各項指標,分析實驗結果,找出系統的弱點和改進方向。
  • 自動化實驗執行: 將混沌實驗的執行過程自動化,提高效率和可重複性。

混沌工程工具箱:Chaos Toolkit 與 Istio 的完美結合

Chaos Toolkit 是一款開源的混沌工程工具,提供了一套框架和 API,方便我們定義和執行混沌實驗。Istio 則是一個服務網格平台,提供了豐富的流量管理和安全功能,可以幫助我們更精細地控制混沌實驗的影響範圍。

結合 Chaos Toolkit 和 Istio,我們可以設計更具針對性的混沌實驗,例如模擬服務間的網路延遲、故障注入等。

實踐案例:模擬 Pod 故障

以下是一個使用 Chaos Toolkit 和 Kubernetes 外掛模擬 Pod 故障的簡單示例:

apiVersion: chaostoolkit.org/v1alpha1
kind: Experiment
metadata:
  name: pod-kill
spec:
  steady-state-hypothesis:
    probes:
      - name: "應用程式正常執行"
        type: "http"
        url: "http://myapp.example.com"
        expected_status_code: 200
  method:
    - name: "Kill Pod"
      provider:
        type: "python"
        module: "chaosk8s.pod.actions"
        func: "terminate_pods"
        arguments:
          label_selectors: "app=myapp"
          ns: "default"
          rand: true
          qty: 1

內容解密:

這段 YAML 程式碼定義了一個名為 pod-kill 的混沌實驗。實驗的穩態假設是應用程式可以正常存取,透過 HTTP 請求驗證。實驗方法是使用 chaosk8s 外掛隨機終止一個帶有 app=myapp 標籤的 Pod。ns: "default" 指定了 Pod 所在的名稱空間,rand: true 表示隨機選擇 Pod,qty: 1 表示終止一個 Pod。

混沌工程是一種強大的工具,可以幫助我們構建更具彈性的雲原生應用。透過模擬真實世界的故障場景,我們可以及早發現系統的弱點,並採取相應的措施提高系統的可靠性。本文介紹了混沌工程的核心原則和方法論,並結合 Chaos Toolkit 和 Istio 等工具,展示瞭如何在 Kubernetes 環境中實施混沌工程。希望本文能幫助您更好地理解和應用混沌工程,開發更具彈性的雲原生應用。

混沌工程:擁抱破壞,提升系統韌性

你是否曾因棘手的問題而感到沮喪?是否經歷過影響眾多使用者的線上事故,並承受巨大壓力?我曾無數次想砸爛伺服器,但破壞很少能解決問題,通常只會帶來負面後果。然而,混沌工程卻反其道而行之,透過在受控環境下模擬故障,找出系統的極限,並提升其韌性。

我們是誰?關於混沌工程團隊

這個團隊由我和 Darin 組成。我是玄貓(BlackCat),一位雲端技術專家,熱衷於容器、雲端原生、Kubernetes 等技術。我撰寫過許多技術書籍和線上課程,也經常在技術研討會中分享經驗。我的部落格和 Podcast 都是我分享技術心得的平台。

Darin 是我的夥伴,也是一位雲端技術顧問。我們共同主持 DevOps Paradox 這個 Podcast,並持續學習 Kubernetes 的最新發展,分享我們的知識和經驗。

混沌工程原則:為不可預期的故障做好準備

混沌工程是一種透過實驗來增強系統抵禦生產環境中各種突發狀況能力的學科。簡單來說,就是為不可避免的故障做好準備。它是一種主動的預防措施,透過模擬線上環境可能發生的各種 adverse effects,讓我們瞭解系統的反應,並強化其韌性。

你準備好迎接混沌了嗎?

在開始之前,我必須先提出警告:你可能還沒準備好迎接混沌工程。它需要團隊具備相當的成熟度和先進的技術能力。此外,混沌工程實驗必須在生產環境中進行,才能觀察真實系統的反應。

進行混沌工程需要足夠的預算、完善的可觀察性工具,以及成熟的監控和警示流程。你需要投入時間學習工具和實踐,也需要承擔實驗可能造成的損失。如果你缺乏這些條件,我不建議你現在開始實踐混沌工程。

混沌工程例項:模擬故障,提升韌性

你可能會問:「混沌工程究竟是什麼意思?」讓我舉幾個例子。以下列出幾種混沌工程的應用場景,並以 Mermaid 圖表輔助說明:

  graph LR
A[模擬服務中斷] --> B(觀察系統反應)
B --> C{系統是否自動還原?}
C -- Yes --> D[記錄成功案例]
C -- No --> E[找出問題根源]
E --> F[改進系統設計]

內容解密:
這個流程圖展示了混沌工程實驗的基本步驟。我們首先模擬一個服務中斷,然後觀察系統的反應。如果系統能夠自動還原,我們就記錄這個成功案例。如果系統無法還原,我們就需要找出問題的根源,並改進系統設計。

  sequenceDiagram
    participant 使用者
    participant 服務 A
    participant 服務 B
    使用者->>服務 A: 請求
    服務 A->>服務 B: 請求
    activate 服務 B
    服務 B-->>服務 A: 延遲回應
    deactivate 服務 B
    服務 A-->>使用者: 錯誤訊息

內容解密: 這個時序圖展示了服務 B 延遲回應導致服務 A 出錯的場景。透過混沌工程,我們可以模擬這種延遲,並觀察系統的反應,找出潛在的效能瓶頸。

這些只是混沌工程的幾個例子。在後續的文章中,我將會更深入地探討混沌工程的各種應用場景和實踐方法。

模擬混亂:建構堅韌的Kubernetes系統

在建構分散式系統,特別是Kubernetes環境中,我們常常會遇到各種不可預期的狀況。服務中斷、網路延遲、節點故障等等,這些問題都可能對系統的穩定性造成巨大衝擊。因此,如何預先識別並解決這些潛在問題,是確保系統穩定執行的關鍵。在本篇文章中,我將透過一系列的實踐演練,帶領大家探索如何在Kubernetes環境中進行混亂工程,提升系統的容錯能力。

混亂工程的目標與原則

我們將探討一些常見的混亂情境,例如:當服務不可用時,錯誤的後備設定會導致什麼後果?應用程式無限制重試連線到不可達的服務,會造成什麼影響?當應用程式或下游依賴服務流量過載或不可用時,會導致什麼樣的錯誤級聯?單點故障是否會導致整個應用程式當機?網路問題或節點故障會對系統造成什麼影響?

由於篇幅限制,我們無法涵蓋所有可能的混亂實驗。我的目標是教你如何思考、如何使用工具,以及如何根據你的組織、團隊和系統的實際情況,找出最有效的混亂工程策略。

接下來,我們先來談談混亂工程的原則。

混亂工程的五大核心原則

  • 圍繞穩態構建假設: 我們需要定義系統或其部分的穩態行為,然後執行一些可能具有破壞性的操作,驗證系統在這些操作後是否仍然保持穩態。
  • 模擬真實世界的事件: 關注那些在真實環境中可能發生的事件,例如應用程式故障、網路中斷、節點不可用等。
  • 在生產環境中執行實驗: 雖然可以在非生產環境中進行練習,但最終目標是在生產環境中執行實驗,因為這是真實使用者互動的環境。
  • 自動化實驗並持續執行: 實驗應該定期執行,或者作為持續交付流程的一部分執行。
  • 最小化爆炸半徑: 從小規模實驗開始,逐步擴大實驗範圍,最終覆寫整個系統。

混亂工程的流程

混亂工程的流程是一個迭代的過程,包含以下步驟:

  1. 定義穩態假設: 明確系統在正常情況下的行為模式。
  2. 確認穩態: 驗證系統當前處於穩態。
  3. 模擬真實世界事件: 執行預先設計的混亂實驗。
  4. 再次確認穩態: 驗證系統在混亂實驗後是否仍然保持穩態。
  5. 使用指標、儀錶板和警示: 監控系統的行為,並在出現異常時及時通知相關人員。

混亂實驗清單

以下列出一些我們可能會進行的混亂實驗:

  • 終止應用程式例項
  • 部分終止網路連線
  • 增加網路延遲
  • 模擬拒絕服務攻擊
  • 釋放節點資源
  • 刪除節點
  • 建立報告
  • 傳送通知
  • 在Kubernetes叢集中執行實驗

我們不會做的事情

  • 修改應用程式內部:我們不會修改應用程式的架構或程式碼。
  • 永久更改任何定義:我們會盡可能在實驗後還原系統的狀態。

本文組織架構

接下來,我們將探討如何在Kubernetes環境中進行混亂工程的實踐。

  graph LR
A[定義穩態假設] --> B(確認穩態);
B --> C{模擬真實事件};
C -- 確認穩態 --> D[收集指標與監控];
D --> E(分析結果);
E --> A;

內容解密: 上圖展示了混亂工程的流程,它是一個迴圈迭代的過程,從定義穩態假設開始,到分析結果結束,然後再次回到定義穩態假設,不斷迴圈,持續改進系統的穩定性。

  graph LR
subgraph 混亂實驗目標
    A[終止應用程式例項] --> B(觀察系統反應);
    C[部分終止網路] --> D(驗證容錯機制);
    E[增加網路延遲] --> F(測試系統彈性);
end

內容解密: 上圖列出了部分混亂實驗目標,例如終止應用程式例項、部分終止網路以及增加網路延遲,這些實驗旨在測試系統在不同壓力下的反應,驗證其容錯能力和彈性。

在接下來的文章中,我將會詳細介紹如何在 Kubernetes 環境中實施這些混亂實驗,並分享一些我在實際操作中積累的經驗和技巧。敬請期待!

混沌工程工具選擇

在開始設計和執行混沌實驗之前,我們需要選擇合適的工具。市面上有哪些工具可用?又該如何選擇?

混沌工程領域尚未成熟,但仍有一些工具可供選擇。受限於篇幅,我無法一一介紹所有工具,因此必須有所取捨。

在選擇工具之前,讓我們先探討幾個我認為重要的需求:

  • **開源優先:**我堅信開源的價值。這並不意味著我們使用的所有工具都必須是開源的,在某些情況下,商業軟體或服務可能更合適。但在本章中,我希望能選擇免費與開源的工具,讓讀者更容易上手。

  • **跨平台支援:**儘管本章著重於 Kubernetes,但如果我們選擇的工具也能在 Kubernetes 之外運作,那就更好了。您可能需要直接對節點進行混沌實驗,或者調整叢集或基礎架構的其他方面。

您可能會問:既然我們希望工具能在 Kubernetes 內外都能運作,為什麼還要專注於 Kubernetes?因為如果我用 AWS 做範例,您可能需要 Azure 的範例,或者您可能更喜歡 Google,又或者您使用的是根據 VMware 的本地叢集。要提供所有平台的範例幾乎是不可能的,那需要好幾本章的篇幅。因此,我不想專注於特定的託管平台(例如僅 AWS 或僅 Azure),因為這樣不夠包容。我希望範圍盡可能廣泛,因此本的重點是 Kubernetes,它幾乎可以在任何地方執行。您學到的所有內容都應該或多或少適用於任何 Kubernetes 發行版和任何託管供應商。

Kubernetes 發行版與環境選擇

本章中的範例在 Minikube、Docker Desktop、Google Kubernetes Engine (GKE)、AWS Elastic Kubernetes Service (EKS) 和 Azure Kubernetes Service (AKS) 中測試過。這並不意味著您必須使用這些 Kubernetes 發行版。您可以在任何地方、任何型別的發行版、任何供應商上執行實驗。然而,我只在前面提到的這些平台上測試過所有範例,如果您使用的是不同的 Kubernetes 版本,則可能需要修改某些定義或指令。

如果您遇到任何問題,請與我聯絡,我會盡力協助您。我甚至可能會擴充這篇文章,提供其他 Kubernetes 發行版的說明。您只需要告訴我您喜歡哪個發行版即可。

關於 Kubernetes 發行版,Minikube 和 Docker Desktop 大部分時間都能正常工作,但並非總是如此。特別是,我們將無法在 Minikube 和 Docker Desktop 中的節點上進行實驗,因為它們是單節點叢集,控制平面和工作節點混合在一起。損壞單節點叢集不會產生預期的結果,反而會導致永久性損壞。

總而言之,所有內容都在 GKE、EKS 和 AKS 中經過測試,而 Minikube 和 Docker Desktop 大部分時間都能正常工作。在少數情況下,如果某些內容在其中一個本地單節點叢集中無法正常工作,您應該能夠從我提供的輸出中觀察結果。即使範例在 Minikube 或 Docker Desktop 中不起作用,您也應該能夠看到正在發生的事情並學習。

學習方法與挑戰

我會給您一些作業,您可以選擇是否完成。與其他不同的是,這些作業並不容易,它們會比我展示的範例更難。如果您選擇做作業,請做好迎接挑戰的準備。這不會是一些簡單的事情,因為我希望您花時間沉浸在混沌工程的世界中,透過做困難的事情來學習,而不是簡單的事情。

我不會詳盡介紹我們將使用的所有工具的功能。我會假設您可以閱讀檔案並瞭解所有額外的模組、外掛和功能。我們只會介紹最常用的場景。

最後,我對本還有一個重要的假設。我會假設您已經精通 Kubernetes。您不會透過本學習如何執行一些基本的 Kubernetes 操作。我也會假設您至少對 Istio 有基本的瞭解。您不需要是 Istio 專家,但一些基本知識是必要的。此外,您還會看到我會討論監控、警示和儀錶板。我不會詳細介紹這些內容。

總之,本的主題不是教您 Kubernetes、服務網格或監控和警示。它專注於 Kubernetes 中的混沌工程。但是,如果您想深入研究一些與本主題不直接相關的主題,我會提供相關資料的參考。

混沌工程之旅

我們即將開始混沌工程之旅。現在,請假設任何事情都可能失敗。這是您應該記住的最重要的事情。它應該銘刻在您的腦海中。任何可能失敗的事情都可能會失敗。

我們將從小處著手,逐步擴充套件。最初的練習可能看起來太基礎,這是故意的。我希望您從小處著手,逐步成長。

溝通與協作

我希望您與您的同事溝通。這可能是混沌工程中最重要的事情。至關重要的是,您學到的經驗教訓以及您將在自己的系統中應用的經驗教訓,都應與您公司的其他人、您的團隊成員和您的同事進行溝通。您必須共同合作解決您將發現的問題。

本文闡述了選擇混沌工程工具的關鍵考量,以及在 Kubernetes 環境中進行混沌實驗的注意事項。記住,混沌工程的目標並非製造混亂,而是透過主動注入故障來提升系統的韌性。持續學習、不斷實驗,才能在面對不可預期的挑戰時,保持系統的穩定執行。

選擇混沌工程工具的關鍵考量

我們已經確定了選擇工具的標準:必須是開源的,並且能夠在 Kubernetes 內外都能正常運作。那麼有哪些選項呢?

首先,我們可以手動執行。例如,自行修改 Kubernetes 資源、調整服務網格等等。但手動執行實驗並非我們想要的。我之前提到過,我認為混沌實驗的執行應該自動化,可以定期執行,或者透過持續交付Pipeline觸發。因此,手動混沌並不可取。

當然,我們也可以編寫自己的指令碼來實作自動化。但為什麼要這麼做呢?市面上已經有一些工具可以幫助我們快速上手。這並不排除編寫自定義指令碼的可能性,你幾乎肯定遲早會需要建立自己的指令碼。但是,選擇一個已經具備我們所需部分功能的工具,可以讓我們更快地達到一定的水平。

既然我們不打算手動執行混沌工程,也不打算從頭開始編寫所有指令碼,那麼讓我們看看有哪些工具可供選擇。

Netflix 的 Chaos Monkey、Simian Army 和其他一些混沌工程工具都是不錯的選擇。Netflix 在混沌工程領域的貢獻是卓越的,他們是先驅者,至少在公開工具方面是如此。然而,Chaos Monkey 在 Kubernetes 中的效果並不好,而與它需要 Spinnaker 和 MySQL。我不認為每個人都應該為了混沌工程而採用 Spinnaker。在 Kubernetes 中表現不佳是一個很大的缺點,Spinnaker 的要求是另一個缺點。我並不是說 Spinnaker 是一個糟糕的工具,恰恰相反,它在某些方面非常有用。然而,問題在於,你是否應該僅僅因為想要做混沌工程而採用它?很可能不應該。如果你已經在使用 Spinnaker,那麼 Chaos Monkey 可能是一個正確的選擇,但我不能做這樣的假設。

接下來是 Gremlin,它可能是市面上最好的工具之一。雖然我鼓勵你嘗試一下,看看它是否符合你的需求,但它是一個服務(你不能自己執行它),而與它不是開源的。由於開源是我們的要求之一,因此 Gremlin 也被排除在外。

此外,還有 PowerfulSeal,它不夠成熟,檔案也很差。除此之外,它只在 Kubernetes 中工作,這不符合我們的要求之一。還有 kube-monkey,它受到了 Chaos Monkey 的啟發,但專為 Kubernetes 設計。與 PowerfulSeal 一樣,它不夠成熟,檔案也很差,我不推薦它。然後是 Litmus,它也存在類別似問題。它的檔案比我提到的其他工具要好,但仍然不夠完善。它還很新,而與只適用於 Kubernetes。還有 Gloo Shot。我喜歡 solo.io 的工具,我喜歡 Gloo 和他們的服務網格。但是,至少在撰寫本文時(2020 年 3 月),Gloo Shot 還比較新,而與它只在服務網格層面上工作。所以,它也不是一個好的選擇。

最後,我們選擇 Chaos Toolkit。它的檔案非常完善,你應該可以找到所有你需要的訊息。它有很多模組可以顯著擴充套件其功能。我們可以在 Kubernetes 內外使用它,可以針對 GCP、AWS、Azure、服務網格(尤其是 Istio)等執行實驗。它有一個非常活躍的社群。如果你加入他們的 Slack 工作區,你會發現有很多人都樂於幫助你。儘管這個專案還不夠完善,但我認為它是我們今天(2020 年 3 月)最好的選擇,至少在我提到的這些工具中是這樣。

我們選擇 Chaos Toolkit,因為它是唯一一個開源的,並且可以在 Kubernetes 內外都能工作的工具。它有完善的檔案,而與它的社群總是樂於提供幫助。這並不意味著其他工具不好,它們並不差。但我們必須做出選擇,而這個選擇就是 Chaos Toolkit。

記住,本章的目標,以及我所做的一切的目標,是教你如何思考以及事物背後的原理,而不是如何使用特定的工具。工具是達到目地的手段。目標很少應該是精通一個工具,而是理解它背後的流程和原理。

希望到本章結束時,你將成為混沌工程高手,並且知道如何使用 Chaos Toolkit。如果你選擇使用其他工具,你將能夠轉化這些知識,因為無論你選擇哪種工具,混沌工程背後的原理都是相同的。你應該能夠輕鬆地適應任何工具。不過,我懷疑你會喜歡 Chaos Toolkit,並且會發現它非常有用。

課程要求

在我們開始實際操作和製造混亂之前,你需要了解一些要求。

你需要 Git。我相信你已經安裝了它,每個人都有。如果你沒有,那麼換個職業吧。

如果你是 Windows 使用者,我強烈建議你從 Git Bash 終端執行所有命令。它可以透過 Git 安裝程式獲得。如果你還沒有安裝它,我建議你重新執行 Git 安裝程式。你會看到一個核取方塊,選中它就會安裝 Git Bash。如果你對它有什麼意見,任何其他 Bash 都可以。理論上,你可以在 PowerShell 或 Windows 終端中執行命令,但與本章中的命令相比會有一些差異。因此,如果你是 Windows 使用者,為了與 Mac 和 Linux 使用者保持一致,我強烈建議你從 Git Bash 或任何其他 Bash 終端執行命令。

由於我們將使用 Kubernetes,因此你需要 kubectl 以及 Kubernetes 叢集。它可以是 Docker Desktop、Minikube、GKE、EKS、AKS。我將提供如何建立它們的說明。它也可以是任何其他發行版。但是,請記住,我只測試了這五個,即使所有內容都應該在任何其他 Kubernetes 版本中工作,你也應該知道,你可能需要不時修改一些命令。

當我們討論 Kubernetes 發行版時,如果你確實更喜歡 Minikube 或 Docker Desktop,請注意,很少有處理節點的示例能夠正常工作。在這些情況下,你需要觀察書中的輸出以瞭解發生了什麼。原因在於 Minikube 和 Docker Desktop 是單節點叢集,工作節點和控制平面混合在一起。你可能已經猜到了,銷毀唯一的節點是我們無法還原的。總而言之,除了處理節點的部分之外,大多數內容都可以在本地 Kubernetes 發行版(Minikube 或 Docker Desktop)中工作。

如果你使用的是 EKS,則需要 Helm v3.x。我們將設定 Cluster Autoscaler,使用 Helm 佈署它可能是最簡單的方法。

很快,我們將安裝 Chaos Toolkit,它需要 Python v3.x 和 pip。後者通常在 Python 安裝過程中安裝。

除了這些要求之外,我可能會要求你在整本章中安裝其他東西。但就目前而言,這些要求就是你所需要的。如果你已經在使用 Kubernetes(我希望你正在使用),那麼你的筆記型電腦上應該已經有了所有這些可執行檔案。唯一的例外可能是 Python。

  graph LR
A[選擇工具] --> B{手動?};
B -- No --> C[自動化工具];
B -- Yes --> D[手動調整];
C --> E{開源?};
E -- Yes --> F[Chaos Toolkit];
E -- No --> G{Gremlin, 商業工具};

在 Kubernetes 的世界中,應用程式終止是一個不可避免的課題。無論是為了更新版本、縮放資源或是處理故障,我們都需要一套可靠的機制來安全地終止應用程式執行個體。本文將探討如何在 Kubernetes 環境中進行 chaos engineering,特別是如何安全地終止應用程式執行個體,並藉此強化應用程式的容錯能力和高用性。

我將帶您逐步操作,從建立 Kubernetes 叢集、佈署應用程式到執行 chaos 實驗,並分享我在實務中獲得的經驗和獨到見解。

準備 Kubernetes 叢集

首先,您需要一個 Kubernetes 叢集。您可以使用 Minikube、Docker Desktop、GKE、EKS、AKS 或任何其他 Kubernetes 叢集。我建議使用單一區域、單一節點的叢集,這樣就足以進行我們的實驗。

以下是一些建立叢集的參考指令,您可以根據自己的環境選擇:

請確保您的叢集已準備就緒,然後我們就可以開始佈署應用程式。

佈署示範應用程式

我準備了一個簡單的示範應用程式,您可以使用它來進行 chaos 實驗。

首先,複製應用程式儲存函式庫:

git clone https://github.com/example/go-demo-8.git
cd go-demo-8
git pull

為了避免影響叢集中的其他應用程式,我們將在一個獨立的名稱空間中佈署示範應用程式:

kubectl create namespace go-demo-8

應用程式的定義檔位於 k8s/terminate-pods/pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: go-demo-8
  labels:
    app: go-demo-8
spec:
  containers:
  - name: go-demo-8
    image: example/go-demo-8:0.0.1
    env:
    - name: DB
      value: go-demo-8-db
    ports:
    - containerPort: 8080
    livenessProbe:
      httpGet:
        path: /
        port: 8080
    readinessProbe:
      httpGet:
        path: /
        port: 8080
    resources:
      limits:
        cpu: 100m
        memory: 50Mi
      requests:
        cpu: 50m
        memory: 20Mi

這個應用程式定義非常簡單,只包含一個容器,並設定了資源限制、健康檢查等基本組態。

內容解密:

這個 YAML 檔案定義了一個 Kubernetes Pod,其中包含一個名為 go-demo-8 的容器。該容器使用 example/go-demo-8:0.0.1 映像檔,並設定了一個環境變數 DB。此外,它還定義了容器的連線埠、liveness 和 readiness 探針,以及資源限制。liveness 和 readiness 探針確保應用程式正常執行,資源限制則限制了容器可使用的 CPU 和記憶體資源。

Chaos Toolkit 與 Kubernetes 外掛

在開始 chaos 實驗之前,我們需要安裝 Chaos Toolkit 和 Kubernetes 外掛:

pip install -U chaostoolkit
pip install chaostoolkit-kubernetes

驗證安裝:

chaos --help

如果輸出包含用法、選項和命令,則表示安裝成功。

穩態假設

在 chaos engineering 中,穩態假設是指系統在正常情況下的預期行為。我們需要定義穩態假設,以便在實驗過程中判斷系統是否受到影響。

執行 Chaos 實驗

現在,我們可以使用 Chaos Toolkit 和 Kubernetes 外掛來終止應用程式執行個體。

後續步驟

在本文中,我們學習瞭如何在 Kubernetes 環境中使用 Chaos Toolkit 終止應用程式執行個體。這只是 chaos engineering 的第一步,後續我們還可以探索更多 chaos 實驗,例如網路延遲、資源耗盡等,以進一步提升應用程式的容錯能力和高用性。

摧毀 Pod:Kubernetes 混沌工程實踐

在 Kubernetes 環境中,應用程式通常以 Pod 的形式執行。瞭解 Pod 的生命週期以及如何應對突發狀況,例如 Pod 被意外終止,對於維護系統穩定性至關重要。本文將探討如何使用 Chaos Toolkit 的 Kubernetes 外掛來模擬 Pod 終止,並觀察系統的反應。

應用程式 Pod 定義

首先,我們來看一個簡單的 Pod 定義:

apiVersion: v1
kind: Pod
metadata:
  name: go-demo-8
  namespace: go-demo-8
  labels:
    app: go-demo-8
spec:
  containers:
  - name: go-demo-8
    image: vfarcic/go-demo-8:latest
    ports:
    - containerPort: 8080
    env:
    - name: MESSAGE
      value: "Hello from Kubernetes!"
    livenessProbe:
      httpGet:
        path: /
        port: 8080
    readinessProbe:
      httpGet:
        path: /
        port: 8080
    resources:
      requests:
        cpu: 100m
        memory: 128Mi
      limits:
        cpu: 200m
        memory: 256Mi

這個 Pod 定義包含了應用程式名稱、名稱空間、容器映像、連線埠、環境變數、livenessProbe、readinessProbe 以及資源限制等資訊。如果您熟悉 Kubernetes,這是一個非常基礎的 Pod 定義。如果您不熟悉 Kubernetes,建議您先學習 Kubernetes 的基礎知識,例如參考我的其他文章或線上資源。

佈署應用程式

接下來,我們將這個 Pod 定義應用到 Kubernetes 叢集中:

kubectl --namespace go-demo-8 apply --filename k8s/terminate-pods/pod.yaml

現在,我們的應用程式已經以 Pod 的形式執行。

引入 Chaos Toolkit Kubernetes 外掛

Chaos Toolkit 本身並不直接支援 Kubernetes,需要安裝 Kubernetes 外掛:

pip install -U chaostoolkit-kubernetes

-U 引數確保安裝最新版本的外掛。

探索外掛功能

安裝外掛後,可以使用 discover 命令探索其功能:

chaos discover chaostoolkit-kubernetes

執行結果會儲存在 discovery.json 檔案中,其中包含了外掛提供的 actions、probes 等資訊。建議您仔細閱讀這個檔案,瞭解外掛的完整功能。

終止 Pod 實驗

現在,我們可以開始進行混沌實驗。以下是一個用於終止 Pod 的實驗定義:

version: 1.0.0
title: "模擬 Pod 終止"
description: 驗證 Pod 終止後是否會自動重建
tags:
- k8s
- pod
method:
- type: action
  name: terminate-pod
  provider:
    type: python
    module: chaosk8s.pod.actions
    func: terminate_pods
  arguments:
    label_selector: app=go-demo-8
    rand: true
    ns: go-demo-8

內容解密:

這個實驗定義包含了版本、標題、描述和標籤等資訊。method 部分定義了要執行的動作,這裡使用 terminate_pods 函式來終止 Pod。arguments 部分指定了目標 Pod 的標籤選擇器、名稱空間以及是否隨機選擇 Pod。

執行實驗:

chaos run chaos/terminate-pod.yaml

內容解密:

執行 chaos run 命令後,Chaos Toolkit 會驗證實驗定義的語法,然後執行實驗。實驗過程中,會終止符合條件的 Pod。由於我們沒有定義 steady state hypothesis 和 rollback,實驗會直接結束。

觀察結果

實驗執行後,您可以觀察 Kubernetes 叢集的狀態,確認 Pod 是否被成功終止以及是否自動重建。這個簡單的實驗展示瞭如何使用 Chaos Toolkit 的 Kubernetes 外掛來模擬 Pod 終止,並觀察系統的反應。

在後續的文章中,我們將探討 steady state hypothesis 和 rollback 的概念,以及如何使用它們來構建更複雜和更有效的混沌實驗。

  graph LR
A[定義 Pod] --> B(佈署 Pod);
B --> C{Pod 執行中};
C --> D[執行混沌實驗];
D --> E(終止 Pod);
E --> F{觀察結果};

內容解密: 此流程圖展示了從定義 Pod 到執行混沌實驗並觀察結果的完整流程。

透過這個實驗,我們可以驗證 Kubernetes 的自我修復能力,並進一步提升系統的穩定性和可靠性。

在混沌工程的實踐中,Pod 終止實驗是驗證 Kubernetes 叢集彈性的一個常見方法。然而,實驗結果的解讀往往並非表面那麼簡單。本文將深入剖析一個 Pod 終止實驗,揭示實驗結果背後的真相,並探討如何正確驗證系統的穩態假說。

首先,我們回顧一下先前的操作:佈署一個 Pod,執行一個實驗來終止它,然後確認 Pod 不存在。這個實驗本身的價值有限,因為我們既沒有驗證執行前的狀態是否正確,也沒有檢查執行後的狀態是否符合預期。我們只是執行了一個終止 Pod 的動作,並觀察到 Pod 消失了。

真正的混沌工程實驗並非為了破壞而破壞,而是為了識別系統中的弱點。一個典型的混沌工程實驗始於定義並驗證穩態假說。我們定義系統的預期狀態,如果系統的實際狀態與預期一致,我們就引入一些混亂,然後再次檢查系統狀態是否仍然與預期一致。如果系統在混亂引入前後都保持穩態,我們就可以得出結論:系統具有容錯性和彈性。

在 Chaos Toolkit 中,我們透過定義 steady-state-hypothesis 來實作這一點。以下是一個示例:

steady-state-hypothesis:
  title: Pod exists
  probes:
  - name: pod-exists
    type: probe
    tolerance: 1
    provider:
      type: python
      func: count_pods
      module: chaosk8s.pod.probes
      arguments:
        label_selector: app=go-demo-8
        ns: go-demo-8

steady-state-hypothesis 部分包含一個標題和一些探針。在這個例子中,只有一個探針 pod-existstolerance 設定為 1,表示實驗預期找到一個符合條件的 Pod。provider 部分定義了探針的實作方式,這裡使用 Python 函式 count_pods 來計數符合標籤選擇器 app=go-demo-8 和名稱空間 go-demo-8 的 Pod 數量。

如果我們在之前的實驗中終止了 Pod,再次執行這個實驗,它會在初始狀態驗證階段失敗,因為找不到符合條件的 Pod。

[...] CRITICAL] Steady state probe 'pod-exists' is not in the given tolerance so failing this experiment

重新建立 Pod 後再次執行實驗,這次實驗成功完成了。

[...] INFO] Steady state hypothesis is met!
[...] INFO] Action: terminate-pod
[...] INFO] Steady state hypothesis is met!

實驗結果顯示,Pod 在終止動作執行前後都存在。這似乎與預期不符,因為我們明明終止了 Pod。

內容解密: 這裡的關鍵在於探針的執行時機。探針是在動作執行前後檢查 Pod 的狀態,而不是在動作執行過程中或執行完成的瞬間。由於 Kubernetes 的 Pod 控制器機制,被終止的 Pod 會被自動重新建立。因此,在探針再次檢查時,新的 Pod 已經被建立出來,導致實驗結果顯示 Pod 仍然存在。

為了更精確地驗證 Pod 的終止狀態,我們需要修改探針,使其在 Pod 終止後立即檢查狀態,或者使用更細粒度的驗證方法,例如檢查 Pod 的狀態變化。

  graph LR
A[佈署 Pod] --> B{Pod 存在?};
B -- Yes --> C[執行終止動作];
C --> D{Pod 消失?};
D -- Yes --> E[實驗成功];
D -- No --> F[實驗失敗];
B -- No --> F;

上圖展示了實驗的流程。如果 Pod 不存在,實驗會立即失敗。如果 Pod 存在,執行終止動作後,如果 Pod 消失,則實驗成功;否則實驗失敗。

這個實驗結果提醒我們,在設計混沌工程實驗時,必須仔細考慮穩態假說的定義和驗證方法,才能準確評估系統的彈性。