如何應對 DoS 攻擊

要應對 DoS 攻擊,可以使用 Istio 的斷路器功能來限制應用程式接收的併發請求數量。這可以防止應用程式因過載而當機。讀者可以自行研究如何使用 Istio 的斷路器,並設計 chaos 實驗來驗證其有效性。

銷毀應用程式和名稱空間

實驗完成後,我們需要銷毀應用程式和名稱空間:

kubectl delete namespace go-demo-8

節點級別的混沌工程

接下來,我們將探討節點級別的混沌工程。這部分將研究節點故障或損壞對應用程式的影響。由於 Minikube 和 Docker Desktop 是單節點叢集,不適合進行這類別實驗,因此需要使用多節點的 Kubernetes 叢集。

斷路器工作原理

  graph LR
    client -->|請求| loadbalancer
    loadbalancer -->|請求| serviceA
    serviceA --超過閾值--> circuitbreaker
    circuitbreaker -->|拒絕請求| client
    circuitbreaker --低於閾值--> serviceA

    subgraph " "
        direction LR
        serviceA -->|成功| client
    end

圖表說明: 此流程圖展示了斷路器的工作原理。當請求數量超過設定的閾值時,斷路器會直接拒絕後續請求,保護後端服務。當請求數量還原到正常水平後,斷路器會允許請求透過。

在這一部分中,我們探討瞭如何使用 process provider 執行任意命令,以及如何模擬和應對 DoS 攻擊。同時,我們也為下一部分的節點級別混沌工程做了鋪墊。讀者可以參考提供的 Gist 進行實踐,並深入研究 Istio 的斷路器功能。

節點的移除與刪除:探討 Kubernetes 的彈性

在 Kubernetes 的世界中,節點的維護和升級是不可避免的。如何確保應用程式在這些操作中保持穩定執行,是我們必須面對的挑戰。本文將探討如何安全地移除節點,並驗證應用程式在節點移除前後的健康狀態。

重要警告: 請勿在正式生產環境中進行以下操作。以下實驗具有破壞性,請務必在測試或開發環境中進行。

佈署應用程式

首先,我們需要佈署一個示範應用程式。這個過程與之前的章節類別似,我們將使用相同的 go-demo-8 應用程式和 MongoDB 資料函式庫。

  1. 進入 go-demo-8 目錄:

    cd go-demo-8
    
  2. 更新程式碼:

    git pull
    
  3. 建立名稱空間並啟用 Istio 自動注入:

    kubectl create namespace go-demo-8
    kubectl label namespace go-demo-8 istio-injection=enabled
    
  4. 佈署應用程式和資料函式庫:

    kubectl --namespace go-demo-8 apply --filename k8s/app-db
    kubectl --namespace go-demo-8 rollout status deployment go-demo-8
    
  5. 驗證應用程式是否可存取:

    curl -H "Host: go-demo-8.acme.com" "http://$INGRESS_HOST"
    

請注意,這次我們沒有佈署 repeater,因為在這個實驗中並不需要它。

移除 Worker 節點

現在,我們將嘗試移除一個隨機 worker 節點上的所有資源。移除節點的常見原因之一是進行 Kubernetes 叢集升級。升級過程通常包括移除節點、關閉節點,然後使用升級版本替換它。

為了確保升級過程不會對應用程式造成影響,我們設計了一個實驗來模擬這個關鍵步驟。實驗將移除一個隨機節點,並驗證應用程式在移除前後是否健康。

以下是實驗的定義:

version: 1.0.0
title: "節點移除對應用程式的影響"
description: 驗證應用程式在節點移除後是否能自動遷移到其他健康節點
tags:
- k8s
- deployment
- node
configuration:
  node_label:
    type: env
    key: NODE_LABEL
steady-state-hypothesis:
  title: 應用程式在節點移除後保持健康
  probes:
  - name: all-apps-are-healthy
    type: probe
    tolerance: true
    provider:
      type: python
      func: all_microservices_healthy
      module: chaosk8s.probes
      arguments:
        ns: go-demo-8
method:
- type: action
  name: drain-node
  provider:
    type: python
    func: drain_nodes
    module: chaosk8s.node.actions
    arguments:
      label_selector: ${node_label}
      count: 1
      pod_namespace: go-demo-8
      delete_pods_with_local_storage: true
pauses:
  after: 1

內容解密:

這個實驗定義了一個名為 drain-node 的動作,它使用 chaosk8s.node.actions 模組中的 drain_nodes 函式來移除節點。label_selector 引數指定了要移除的節點的標籤,count 引數設定為 1,表示只移除一個節點。pod_namespace 引數指定了要檢查的名稱空間,確保移除的節點上執行著該名稱空間中的 Pod。delete_pods_with_local_storage 引數設定為 true,表示刪除具有本地儲存的 Pod。pauses 設定在動作執行後暫停 1 秒,以便驗證應用程式的健康狀態。

在執行實驗之前,我們需要確定節點的標籤。可以使用以下命令檢視節點的標籤:

kubectl describe nodes

找到一個合適的標籤後,將其設定為環境變數 NODE_LABEL

export NODE_LABEL="beta.kubernetes.io/os=linux"  # 將此替換為你的節點標籤

Mermaid 圖表 - 實驗流程:

  graph LR
    B[B]
    D[D]
A[佈署應用程式] --> B{設定 NODE_LABEL};
B --> C[執行 drain-node 動作];
C --> D{驗證應用程式健康狀態};

內容解密: 圖表展示了實驗的執行流程,首先佈署應用程式,然後設定 NODE_LABEL 環境變數,接著執行 drain-node 動作,最後驗證應用程式的健康狀態。

本文探討瞭如何在 Kubernetes 中安全地移除節點,並驗證應用程式在節點移除前後的健康狀態。我們使用了一個實驗來模擬節點移除的過程,並使用 Mermaid 圖表展示了實驗流程。記住,在正式環境中進行此類別操作前,請務必做好充分的測試和準備。

單節點叢集的挑戰:節點移除與 Istio 佈署

在進行混沌工程實驗之前,我們必須先思考預期結果。尤其在單節點叢集上進行節點移除實驗時,結果可能與直覺相悖。讓我們先回顧一下叢集的建立過程,特別是 Istio 的佈署細節。

現在,重新思考一下,當我們移除單節點叢集的唯一節點時會發生什麼?節點真的能被移除嗎?為了更容易理解,仔細檢查一下叢集內執行的應用程式,尤其是 Istio 相關元件。

實驗:移除節點

執行以下指令:

chaos run chaos/node-drain.yaml

簡化後的輸出如下:

[... INFO] 驗證實驗語法
[... INFO] 實驗語法有效
[... INFO] 執行實驗:移除節點的影響
[... INFO] 穩定狀態假設:節點堅不可摧
[... INFO] 探測:所有應用程式健康
[... INFO] 穩定狀態假設成立!
[... INFO] 動作:移除節點
[... ERROR] => 失敗: 無法移除 Pod istio-ingressgateway,違反 Pod 的中斷預算
[... INFO] 動作後暫停 1 秒...
[... INFO] 穩定狀態假設:節點堅不可摧
[... INFO] 探測:所有應用程式健康
[... ERROR] => 失敗: 系統不健康
[... WARNING] 探測意外終止
[... CRITICAL] 穩定狀態探測失敗
[... INFO] 執行回復...
[... INFO] 無已宣告回復,繼續執行
[... INFO] 實驗結束,狀態:偏離
[... INFO] 穩定狀態已偏離,可能已發現弱點

輸出顯示初始探測透過,go-demo-8 名稱空間中的所有應用程式都正常運作。然而,移除節點的動作卻失敗了,原因是違反了 istio-ingressgateway 的中斷預算。

Istio Gateway 的中斷預算

Gateway 的中斷預算設定為 1,表示任何時刻都必須至少有一個 Pod 正在執行。我們在佈署 Istio 時犯了一個錯誤:沒有仔細調整 Gateway 的副本數量,導致只有一個副本在執行。雖然 Gateway 的設計考量是正確的,確保 Gateway 始終執行,但單節點叢集加上單副本 Gateway 的組態,使得節點移除操作必然失敗。

單節點叢集的限制

在單節點叢集上,即使將 Istio 元件擴充套件到多個副本,所有副本仍然會在同一個節點上執行,這將導致與之前相同的錯誤。系統無法移除節點,因為這意味著所有 Istio 元件的副本都需要關閉,而它們的中斷預算被設定為 1。

解除 Worker 節點的封鎖

執行以下指令檢視節點狀態:

kubectl get nodes

輸出顯示節點狀態為 Ready,SchedulingDisabled。實驗的第一步是停用節點上的排程,防止新 Pod 佈署,第二步是移除節點上的所有資源。實驗完成了第一步,但在第二步失敗了,導致叢集無法排程任何新的 Pod。

我們應該在實驗定義中加入回復機制,無論實驗成功或失敗,都會解除節點的封鎖。

加入回復機制

檢視新的實驗定義:

cat chaos/node-uncordon.yaml

與之前的定義比較:

diff chaos/node-drain.yaml chaos/node-uncordon.yaml

主要的差異是新增了 rollbacks 區段,其中包含一個使用 uncordon_node 函式的動作。這個回復動作會重新啟用節點上的排程。rollbacks 區段中的 label_selector 引數與 cordoning 動作中使用的標籤比對,它將解除所有具有該標籤的節點的封鎖。

再次執行實驗

chaos run chaos/node-uncordon.yaml

實驗仍然會失敗,因為我們尚未解決節點數量不足和 Istio 元件副本數量不足的問題。然而,這次實驗失敗後會執行回復動作,將節點還原到正確的狀態。

內容解密:

這部分的程式碼主要演示了在 Kubernetes 叢集中進行混沌工程實驗的過程,以及如何處理實驗失敗的情況。node-drain.yaml 定義了一個實驗,嘗試移除一個節點,但由於 Istio ingressgateway 的中斷預算限制而失敗。node-uncordon.yaml 在前者的基礎上增加了回復機制,即使實驗失敗也能將節點還原到 SchedulingEnabled 狀態。這個例子突出了在設計混沌工程實驗時考慮回復機制的重要性,以避免對系統造成永久性損壞。同時,也展現了在單節點叢集中進行節點移除實驗的挑戰,以及 Istio 中斷預算的組態對實驗結果的影響。

(Mermaid 圖表)

  graph LR
    B[B]
    D[D]
    No[No]
    Yes[Yes]
A[實驗開始] --> B{探測: 所有應用程式健康?};
B -- Yes --> C[動作: 移除節點];
C --> D{移除節點成功?};
D -- No --> E[回復: 啟用節點排程];
D -- Yes --> F[實驗結束 - 成功];
E --> G[實驗結束 - 失敗];
B -- No --> G;

(Mermaid 圖表說明)

此流程圖展示了節點移除實驗的執行流程,包括初始探測、移除節點動作、成功與失敗分支,以及回復機制。

解決 Kubernetes 節點無法排空的問題

在分散式系統的維護過程中,我經常遇到需要排空節點進行升級或其他操作的情況。然而,有時會發現節點無法順利排空,這通常表示系統中存在單點故障或資源組態不合理的問題。本文將分享我如何診斷並解決 Kubernetes 節點無法排空問題的經驗,並提供一些實用的技巧。

  graph LR
    B[B]
    No[No]
    Yes[Yes]
    A[kubectl get nodes] --> B{Node Status: Ready?};
    B -- Yes --> C[繼續實驗];
    B -- No --> D[修復問題];

檢查 Istio 佈署

首先,我會檢查 Istio 的佈署情況,特別是 istio-ingressgatewayistiod 這兩個關鍵元件。

kubectl --namespace istio-system get deployments

輸出結果顯示了這些元件的狀態,包括 READY 列,指示每個元件的副本數量是否達到預期。

確保 Istio 元件的高用性

為了避免單點故障,Istio 的關鍵元件應該至少有兩個副本。HorizontalPodAutoscaler (HPA) 可以根據 CPU 和記憶體使用情況自動調整副本數量。為了確保高用性,我將 HPA 的最小副本數設定為 2。

  graph LR
    B[B]
    No[No]
    Yes[Yes]
    A[檢查 HPA 設定] --> B{minReplicas >= 2?};
    B -- Yes --> C[繼續];
    B -- No --> D[設定 minReplicas 為 2];

調整叢集規模

在調整 Istio 元件之前,需要確保叢集本身有足夠的節點來支援多個副本。如果叢集中只有一個節點,即使增加了 Istio 副本數量,也無法解決節點無法排空的問題。

# 設定叢集名稱變數
export CLUSTER_NAME=your_cluster_name

# GKE
gcloud container clusters resize $CLUSTER_NAME --zone your_zone --num-nodes=3

# EKS
eksctl scale nodegroup --cluster=$CLUSTER_NAME --nodes 3 your_node_group

# AKS
az aks scale --resource-group your_resource_group --name $CLUSTER_NAME --node-count 3 --nodepool-name your_node_group

內容解密: 以上程式碼片段展示瞭如何在不同 Kubernetes 發行版中調整叢集規模。根據你的環境選擇對應的命令,並將佔位符替換為你的實際值。

更新 Istio HPA

調整叢集規模後,需要更新 Istio HPA 的設定,將最小副本數設定為 2。

kubectl --namespace istio-system patch hpa istio-ingressgateway --patch '{"spec": {"minReplicas": 2}}'

內容解密: 這段程式碼使用 kubectl patch 命令更新了 istio-ingressgateway 的 HPA 設定,將 minReplicas 設定為 2。

驗證設定

完成以上步驟後,需要驗證設定是否生效。

kubectl --namespace istio-system get hpa
kubectl --namespace istio-system get pods -o wide

內容解密: 這些命令分別用於檢查 HPA 設定和 Pod 狀態。-o wide 引數可以顯示 Pod 執行的節點資訊,確保 Istio 的副本分佈在不同的節點上。

透過以上步驟,我成功解決了 Kubernetes 節點無法排空的問題。關鍵在於確保 Istio 的關鍵元件具有高用性,並且分佈在不同的節點上。這個過程也讓我更深入地理解了 Kubernetes 和 Istio 的運作機制。

節點刪除的影響:探討 Kubernetes 叢集的容錯能力

在 Kubernetes 叢集中,節點的穩定性至關重要。前一篇文章中,我們探討瞭如何安全地排出節點,以進行升級或維護。然而,真實世界中,節點故障往往突如其來,並非總能按計劃進行。本文將深入研究當節點被刪除時,叢集如何應對,以及如何設計應用程式以應對這類別突發狀況。

模擬節點刪除實驗

為驗證叢集在節點刪除時的行為,我們設計了一個實驗,模擬節點故障的場景。以下列出實驗的 YAML 檔案:

version: 1.0.0
title: "節點刪除對應用程式的影響"
description: 驗證應用程式在節點刪除後的健康狀態
tags:
- k8s
- deployment
- node
configuration:
  node_label:
    type: env
    key: NODE_LABEL
steady-state-hypothesis:
  title: 應用程式在節點刪除後保持健康
  probes:
  - name: all-apps-are-healthy
    type: probe
    tolerance: true
    provider:
      type: python
      func: all_microservices_healthy
      module: chaosk8s.probes
      arguments:
        ns: go-demo-8
method:
- type: action
  name: delete-node
  provider:
    type: python
    func: delete_nodes
    module: chaosk8s.node.actions
    arguments:
      label_selector: ${node_label}
      count: 1
      pod_namespace: go-demo-8
pauses:
  after: 10

與之前的排出節點實驗相比,主要差異在於使用了 delete-node 方法,並移除 rollbacks 區段。這是因為節點刪除是不可逆的操作,叢集本身應具備自我修復能力,無需額外回復操作。

實驗結果分析

執行實驗後,我的輸出顯示初始穩態假設成立,delete-node 操作成功執行。等待 10 秒後,目標節點被刪除。後續的穩態假設檢查也成功透過,表明在 go-demo-8 名稱空間中執行的應用程式仍然保持健康狀態。

kubectl get nodes

執行上述指令後,節點數量減少了一個,確認節點已從 Kubernetes 叢集中移除。雖然叢集尚未自動還原節點數量(因為未設定自動擴充套件),但應用程式仍然正常執行。

需要注意的是,實驗中並非真正銷毀了節點,而是將其從 Kubernetes 叢集中移除。實際的虛擬機器可能仍在執行,需要手動刪除。

關於資料函式庫的注意事項

實驗過程中,如果被刪除的節點恰好是託管 go-demo-8 資料函式庫的節點,實驗可能會失敗。這凸顯了資料函式庫高用性設計的重要性,我們將在後續文章中探討。

透過模擬節點刪除實驗,我們驗證了 Kubernetes 叢集的容錯能力。儘管節點被移除,應用程式仍然能夠保持執行,這得益於 Kubernetes 的自我修復機制。然而,資料函式庫的高用性設計仍然需要額外考量,以確保應用程式在任何情況下都能正常運作。

  graph LR
    C[C]
    D[D]
    E[E]
A[應用程式] --> B(Kubernetes 叢集)
B --> C{節點1}
B --> D{節點2}
B --> E{節點3}
E --> F[資料函式庫]
style E stroke-dasharray: 5 5,stroke:red,fill:#f9f,stroke-width:2px

內容解密: 上圖展示了應用程式、Kubernetes 叢集和節點之間的關係。紅色虛線框標示的節點3是本次實驗中被刪除的節點,它同時也託管著資料函式庫。這突顯了單點故障的風險,以及資料函式庫高用性設計的重要性。 探究 Kubernetes 節點刪除的影響與叢集災難應變策略

在 Kubernetes 環境中,刪除節點是一個常見的操作,但其影響卻不容忽視。本文將探討節點刪除對應用程式和叢集的影響,並提供一些災難應變策略。

節點刪除模擬實驗

我們可以模擬節點刪除來觀察其影響。當一個節點從 Kubernetes 中移除(無論是物理移除還是邏輯移除),Kubernetes 會將其視為消失,並將在該節點上執行的 Pod 重新分配到其他健康節點。

kubectl --namespace go-demo-8 get pods

透過觀察 Pod 的狀態,我們可以確認應用程式是否正常執行。如果 Pod 狀態顯示 Running,則表示應用程式在節點刪除後成功遷移到其他節點。

然而,如果被移除的節點仍在物理執行,其上的應用程式副本可能仍在執行,但 Kubernetes 無法感知。這就需要進一步調查,確認這些副本是否會對應用程式造成影響,例如資料不一致等問題。

此外,更進階的實驗是模擬節點的物理銷毀,例如關閉節點電源。這需要根據不同的雲端供應商或本地環境使用不同的方法。可以使用 Chaos Toolkit 等工具來執行這類別實驗,透過模擬真實的故障場景來驗證系統的容錯能力。

叢集規模與容錯性

在單區域叢集中,刪除過多節點可能導致叢集容量不足,應用程式無法正常執行。因此,叢集的規模和容錯性至關重要。

以下是一些提升叢集容錯性的策略:

  • 叢集自動擴充套件器 (Cluster Autoscaler): Cluster Autoscaler 可以根據負載自動調整叢集規模,確保叢集容量始終滿足應用程式的需求。當節點故障時,Cluster Autoscaler 也能自動建立新的節點,彌補損失的容量。
  • 多區域叢集: 將叢集佈署到多個區域可以提高容錯性。當一個區域發生故障時,應用程式可以繼續在其他區域執行,避免單點故障。

以下 Gist 提供了在不同雲端平台上建立多區域、可擴充套件叢集的範例:

清理環境

實驗結束後,應清理建立的資源,避免資源浪費。

cd ..
kubectl delete namespace go-demo-8

由於我們在非自動擴充套件的叢集中移除了節點,強烈建議銷毀整個叢集,並重新建立一個多區域、可擴充套件的叢集,以確保系統的穩定性和容錯性。

生成混沌實驗報告

混沌工程實驗的目的是發現系統的弱點,並提供改進建議。因此,生成清晰易懂的實驗報告至關重要。報告應包含以下內容:

  • 實驗目標: 明確說明實驗的目的和預期結果。
  • 實驗步驟: 詳細描述實驗的步驟和操作。
  • 實驗結果: 呈現實驗的資料和觀察結果。
  • 結論與建議: 總結實驗發現的問題,並提供改進建議。

透過有效的報告,可以將混沌工程的價值傳達給團隊成員和其他相關方,促進系統的持續改進。

本文探討了 Kubernetes 節點刪除的影響,並介紹了叢集規模和容錯性的重要性。同時,也強調了生成混沌實驗報告的重要性。透過這些策略,可以提高 Kubernetes 環境的穩定性和可靠性。

  graph LR
A[節點刪除] --> B{應用程式影響?};
B -- 正常執行 --> C[實驗成功];
B -- 故障 --> D[調查原因];
D --> E[調整叢集組態];
E --> F[重新實驗];

內容解密: 上面的 Mermaid 流程圖展示了節點刪除實驗的流程。首先模擬節點刪除,然後觀察應用程式是否受到影響。如果應用程式正常執行,則實驗成功。如果應用程式出現故障,則需要調查原因,並調整叢集組態,例如增加節點或啟用自動擴充套件。最後,重新進行實驗,驗證調整後的組態是否有效。

從實驗資料到視覺化報告:Chaos Toolkit 的進階應用

在先前的探索中,我們運用 Chaos Toolkit 對系統進行了一系列混沌實驗,藉此揭示潛在的弱點。然而,實驗結果本身的資料通常以 JSON 格式呈現,對於人類閱讀和理解來說並不直觀。因此,本文將探討如何將這些實驗資料轉化為更易於理解的視覺化報告,例如 PDF 格式,以便更好地與團隊成員和管理階層溝通實驗結果。

建立 Kubernetes 叢集與佈署應用程式

在開始之前,我們需要準備好 Kubernetes 叢集和待測試的應用程式。以下列出幾種建立和銷毀 Kubernetes 叢集的指令碼,您可以根據自己的環境選擇使用:

  • Docker Desktop with Istio: docker-istio.sh
  • Minikube with Istio: minikube-istio.sh
  • Regional and scalable GKE with Istio: gke-istio-full.sh
  • Regional and scalable EKS with Istio: eks-istio-full.sh
  • Regional and scalable AKS with Istio: aks-istio-full.sh

佈署應用程式的步驟簡述如下:

  1. 進入 go-demo-8 目錄並更新程式碼:

    cd go-demo-8
    git pull
    
  2. 建立名稱空間並設定 Istio 自動注入 sidecar:

    kubectl create namespace go-demo-8
    kubectl label namespace go-demo-8 istio-injection=enabled
    
  3. 佈署應用程式:

    kubectl --namespace go-demo-8 apply --filename k8s/app-full
    kubectl --namespace go-demo-8 rollout status deployment go-demo-8
    
  4. 測試應用程式:

    curl -H "Host: repeater.acme.com" "http://$INGRESS_HOST?addr=http://go-demo-8"
    

產生實驗日誌

Chaos Toolkit 提供了 --journal-path 引數,可以將實驗過程中產生的資料儲存到指定的 JSON 檔案中。以下是一個執行實驗並產生日誌的範例:

chaos run chaos/health-http.yaml --journal-path journal-health-http.json

這個指令碼執行了一個名為 health-http.yaml 的混沌實驗,並將實驗日誌儲存到 journal-health-http.json 檔案中。

將實驗日誌轉換為報告

雖然 JSON 格式的日誌易於機器解析,但對於人類閱讀並不友好。因此,我們需要將其轉換為更易讀的格式,例如 PDF。

由於安裝和組態必要的依賴項可能比較複雜,我們建議使用 Docker 容器來簡化這個過程。以下是一個使用 Docker 容器產生 PDF 報告的指令碼:

docker container run \
  --user $(id -u) \
  --volume $PWD:/tmp/result \
  -it \
  chaostoolkit/reporting \
  -- report \
  --export-format=pdf \
  journal-health-http.json \
  report.pdf

內容解密:

這個指令碼使用了 chaostoolkit/reporting 映像檔建立一個 Docker 容器,並將當前目錄掛載到容器內的 /tmp/result 目錄,以便將產生的報告檔案儲存到本地。--user $(id -u) 引數確保報告檔案的擁有者與當前使用者相同。-it 引數則允許我們以互動模式執行容器,並在終端機中檢視輸出。最後,--report --export-format=pdf journal-health-http.json report.pdf 引數指定了要執行的指令,以及輸入的日誌檔案和輸出的報告檔案路徑。

執行完畢後,您可以在當前目錄找到生成的 report.pdf 檔案。使用 PDF 閱讀器開啟即可檢視詳細的實驗報告。

視覺化實驗流程

為了更清晰地展示實驗流程,我們可以使用 Mermaid 流程圖。以下是一個示例:

  graph LR
    C[C]
A[準備 Kubernetes 叢集] --> B(佈署應用程式);
B --> C{執行混沌實驗};
C --成功--> D[產生實驗日誌];
C --失敗--> E[排查錯誤];
D --> F[生成 PDF 報告];

內容解密:

這個流程圖展示了從準備 Kubernetes 叢集到生成 PDF 報告的完整流程。首先,我們需要準備 Kubernetes 叢集,然後佈署應用程式。接著,執行混沌實驗,如果實驗成功,則產生實驗日誌,否則需要排查錯誤。最後,將實驗日誌轉換為 PDF 報告。

透過視覺化的圖表,我們可以更直觀地理解實驗流程,並更容易地發現潛在問題。

總結:本文介紹瞭如何使用 Chaos Toolkit 產生實驗日誌,並將其轉換為易於理解的 PDF 報告。同時,我們也示範瞭如何使用 Mermaid 圖表來視覺化實驗流程,進一步提升溝通效率。希望這些技巧能幫助您更好地運用 Chaos Toolkit 進行混沌工程實踐。

從單次實驗報告到多實驗整合報告:我的混沌工程實踐經驗

在混沌工程實踐中,報告的生成是驗證實驗結果和分享洞察的關鍵步驟。我之前分享過如何從單次 Chaos Toolkit 執行中生成報告,現在我們將進一步探討如何整合多個實驗的結果,生成更全面的多實驗報告。

執行第二個混沌實驗

為了生成多實驗報告,我們首先需要執行另一個實驗,產生新的 journal 檔案。這裡我選擇複用之前用過的網路延遲實驗,它模擬了服務回應中止和延遲的場景。實驗定義檔案 chaos/network-delay.yaml 如下所示:

version: 1.0.0
title: "模擬服務回應中止和延遲"
description: 驗證依賴應用程式在回應中止和延遲情況下的重試和逾時機制
# ... (其他設定)

這個實驗的重點在於驗證應用程式在網路故障下的彈性。執行實驗的指令如下:

chaos run chaos/network-delay.yaml --journal-path journal-network-delay.json

實驗成功執行後,結果會儲存在 journal-network-delay.json 檔案中。

生成多實驗報告

現在我們有了兩個 journal 檔案:journal-health-http.jsonjournal-network-delay.json。接下來,我們將使用 Chaos Toolkit 的報告生成工具,將這兩個檔案的資訊整合到一份報告中。

docker container run \
--user $(id -u) \
--volume $PWD:/tmp/result \
-it \
chaostoolkit/reporting \
-- report \
--export-format=pdf \
journal-health-http.json \
journal-network-delay.json \
report.pdf

這個指令與生成單實驗報告的指令類別似,只是新增了第二個 journal 檔案的路徑。Chaos Toolkit 會自動整合所有指定的 journal 檔案,生成一份包含所有實驗結果的報告。

開啟 report.pdf,我們可以看到這次的報告包含了兩個實驗的結果。透過這種方式,我們可以將任意多個實驗的結果整合到一份報告中,方便團隊成員分享和分析。

清理實驗環境

實驗完成後,我們需要清理建立的資源:

cd ..
kubectl delete namespace go-demo-8

如果不再需要 Docker,也可以停止 Docker daemon。

將混沌實驗移至 Kubernetes 叢集內執行

目前為止,我們的混沌實驗都是在本地機器上執行,目標是遠端 Kubernetes 叢集。接下來,我將分享如何將實驗的執行也移至 Kubernetes 叢集中,讓實驗在叢集內部執行,並以叢集內部的元件為目標。這將更貼近真實的生產環境,並能更有效地驗證應用程式的彈性。

(Mermaid 圖表)

  graph LR
    C[C]
    A[本地機器] --> B(Kubernetes 叢集)
    B --> C{應用程式}
    D[混沌實驗(本地執行)] --> C
    subgraph Kubernetes 叢集內部
        E[混沌實驗(叢集內執行)] --> C
    end

上圖展示了混沌實驗在本地執行和在叢集內執行的區別。在叢集內執行實驗,可以更精確地模擬真實的故障場景,並減少網路延遲等外部因素的幹擾。

總結:本文介紹瞭如何生成多實驗混沌工程報告,並展望了在 Kubernetes 叢集內執行實驗的優勢。希望這些實踐經驗能幫助你更好地應用混沌工程,提升系統的彈性。 在 Kubernetes 叢集中執行混沌實驗

本章所有指令都可以在 08-k8s.sh Gist 中找到。

建立叢集

我們需要一個叢集來執行 demo 應用程式和實驗。您是否擁有它取決於您是否在上一章結束時銷毀了您的叢集。如果您沒有銷毀它,請直接跳到下一節。如果您確實銷毀了叢集,請隨意使用以下 Gist 之一建立一個新的叢集。或者,您可以推出自己的叢集。由你決定。

  • Docker Desktop with Istio: docker-istio.sh
  • Minikube with Istio: minikube-istio.sh
  • Regional and scalable GKE with Istio: gke-istio-full.sh
  • Regional and scalable EKS with Istio: eks-istio-full.sh
  • Regional and scalable AKS with Istio: aks-istio-full.sh

佈署應用程式

在前面的章節中,我們佈署了 demo 應用程式,這是我們實驗的目標。這一章也不例外。我們將佈署與之前使用的相同的 demo 應用程式。鑑於您已經熟悉它,我們將快速瀏覽這些指令,不做太多解釋。

我們將進入 go-demo-8 目錄並提取儲存函式庫的最新版本。

cd go-demo-8
git pull

接下來,我們將建立一個名為 go-demo-8 的名稱空間,並新增標籤,以便 Istio 知道它應該自動注入代理 sidecar。

kubectl create namespace go-demo-8
kubectl label namespace go-demo-8 istio-injection=enabled

我們將應用 k8s/app-full 目錄中的定義,一旦建立了所有資源,我們將等待 API 的佈署推出。

kubectl --namespace go-demo-8 apply --filename k8s/app-full
kubectl --namespace go-demo-8 rollout status deployment go-demo-8

最後,為了確保它正常工作,我們將向新佈署的 demo 應用程式傳送一個請求。

curl -H "Host: repeater.acme.com" "http://$INGRESS_HOST?addr=http://go-demo-8"

現在我們可以將注意力轉向設定在 Kubernetes 叢集中執行實驗所需的資源。

在 Kubernetes 中設定 Chaos Toolkit

在我們開始在 Kubernetes 叢集中執行混沌實驗之前,我們需要至少設定兩件事。

我們需要將實驗定義儲存在叢集中的某個位置。在 Kubernetes 中定義組態最常見與最合乎邏輯的方法是使用 ConfigMap。除了可以輕鬆獲得實驗定義外,我們還需要建立一個 ServiceAccount,它將為執行實驗的流程提供必要的許可權。

讓我們從 ConfigMap 開始。

cat k8s/chaos/experiments.yaml

輸出(僅限於第一個實驗)如下所示。

apiVersion: v1
kind: ConfigMap
metadata:
  name: chaostoolkit-experiments
data:
  health-http.yaml: |
    version: 1.0.0
    title: 如果我們終止應用程式的一個例項會發生什麼?
    description: 如果應用程式的一個例項被終止,則應用程式整體應仍然可以執行。
    tags:
    - k8s
    - pod
    steady-state-hypothesis:
      title: 應用程式正常
      probes:
      - name: app-responds-to-requests
        type: probe
        tolerance: 200
        provider:
          type: http
          timeout: 3
          verify_tls: false
          url: http://go-demo-8.go-demo-8/demo/person
          headers:
            Host: go-demo-8.acme.com
    method:
    - type: action
      name: terminate-app-pod
      provider:
        type: python
        module: chaosk8s.pod.actions
        func: terminate_pods
        arguments:
          label_selector: app=go-demo-8
          rand: true
          ns: go-demo-8
      pauses:
        after: 2
...

我們可以看到,它是一個“標準”的 Kubernetes ConfigMap,其中包含一些實驗。我沒有列出我們目前探討的所有實驗,因為我們在本章中並不需要所有實驗。然而,您應該能夠新增其他實驗,只要您不超過 1MB 的限制。這是 etcd 的限制,etcd 是 Kubernetes 儲存其物件的登入檔。如果您確實需要更多,則可以使用多個 ConfigMap。

該定義的重要部分是 data 部分。

我們可以看到 health-http.yaml 鍵,正如您希望知道的那樣,當我們掛載該 ConfigMap 時,它將被轉換為具有相同名稱的檔案。該值是一個實驗的定義。steady-state-hypothesis 正在檢查應用程式是否正常。它透過向應用程式傳送請求的探針來做到這一點。該方法的作用是終止 go-demo-8 應用程式的一個 Pod。

再往下看,我們可以看到還有一些其他的實驗。我們不會一一介紹它們,因為在該 ConfigMap 中定義的所有實驗都與我們之前使用的實驗相同。在本章中,我們不是要找出新的方法來製造混亂,而是要如何在 Kubernetes 叢集中執行實驗。

總而言之,我們的實驗將被定義為 ConfigMap,並且它們將對叢集內的流程可用。

讓我們應用該定義並繼續前進。

kubectl --namespace go-demo-8 apply --filename k8s/chaos/experiments.yaml

接下來,為了安全起見,我們將描述 ConfigMap 並確認它確實已建立並在我們的叢集中可用。

kubectl --namespace go-demo-8 describe configmap chaostoolkit-experiments

我們可以看到輸出或多或少與我們在用於建立該 ConfigMap 的 YAML 檔案中看到的內容相同。

下一個是 ServiceAccount。我們需要它為我們將在 go-demo-8 名稱空間中執行的混沌流程提供足夠的許可權。

讓我們看一下 sa.yaml 檔案。

cat k8s/chaos/sa.yaml

輸出如下:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: chaostoolkit


apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: chaostoolkit
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: chaostoolkit
subjects:
- kind: ServiceAccount
  name: chaostoolkit

我們可以看到那裡定義了一些東西。首先,我們有名為 chaostoolkit 的 ServiceAccount。正如您希望已經知道的那樣,ServiceAccount 本身只是對某些東西的參照,如果不將它們繫結到定義許可權的角色,它們就沒有多大用處。因此,該 YAML 定義包含一個角色,其中的規則決定了可以在特定型別的 apiGroupsresources 上執行哪些操作(動詞)。此外,我們還有一個 RoleBinding,它將角色繫結到 ServiceAccount。

對該定義的簡短解釋是,它將允許我們執行幾乎任何我們可能需要做的事情,但僅限於特定名稱空間。

在現實世界中,您可能希望比這更具限制性。這些許可權將有效地允許該名稱空間中的流程在其中執行任何操作。另一方面,很難限制我們需要賦予混沌實驗的許可權。從理論上講,我們可能希望透過實驗影響名稱空間內甚至整個叢集中的任何內容。因此,無論我們多麼希望限制一般許可權,我們都可能需要對混沌實驗慷慨解囊。為了讓它們正常工作,我們很可能需要允許廣泛的許可權。至少,我們必須允許它們執行我們決定要執行的操作。

內容解密:

這段文字解釋瞭如何在 Kubernetes 叢集中設定和執行混沌實驗,包括建立叢集、佈署應用程式、設定 Chaos Toolkit、定義實驗以及設定必要的許可權。它還強調了在設定許可權時需要在安全性和實驗靈活性之間取得平衡。程式碼範例展示瞭如何使用 ConfigMap 定義實驗以及如何使用 ServiceAccount 和 RoleBinding 設定許可權。