終止 Pod 後的混沌工程實驗:深度解析與實踐

在 Kubernetes 環境中,確保應用程式的高用性和彈性至關重要。混沌工程提供了一種有效的方法來驗證系統在面對意外情況時的行為。本文將探討如何使用 Chaos Toolkit 和 Kubernetes plugin 進行混沌工程實驗,特別關注 Pod 終止後的系統反應。

實驗設計:模擬 Pod 終止

首先,我們需要一個基本的 Pod 佈署。以下 YAML 檔案定義了一個簡單的 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: nginx:latest

我們的實驗目標是模擬 Pod 被終止的場景,並驗證系統是否能夠正常還原。

初始實驗:驗證 Pod 狀態

最初的實驗設計只檢查 Pod 的存在與否,而沒有考慮 Pod 的執行狀態。這導致實驗結果與預期不符。

apiVersion: chaos-toolkit/v1alpha1
kind: Experiment
metadata:
  name: pod-termination-experiment
spec:
  steady-state-hypothesis:
    probes:
    - name: pod-exists
      type: probe
      tolerance: true
      provider:
        type: python
        module: chaosk8s.pod.probes
        arguments:
          label_selector: app=go-demo-8
          ns: go-demo-8
  method:
    - name: terminate-pod
      type: action
      provider:
        type: python
        module: chaosk8s.pod.actions
        arguments:
          label_selector: app=go-demo-8
          ns: go-demo-8
  steady-state-hypothesis:
    probes:
    - name: pod-exists
      type: probe
      tolerance: false # 預期 Pod 不存在
      provider:
        type: python
        module: chaosk8s.pod.probes
        arguments:
          label_selector: app=go-demo-8
          ns: go-demo-8

實驗結果顯示,即使 Pod 被終止,探針仍然認為 Pod 存在。這是因為 Kubernetes 需要時間來完全移除 Pod,而探針執行的速度太快,導致檢測到 Pod 處於terminating狀態。

加入延遲:更真實的模擬

為了更準確地模擬真實場景,我們需要在終止 Pod 的動作後加入延遲,以便 Kubernetes 有足夠的時間完成 Pod 的移除。

apiVersion: chaos-toolkit/v1alpha1
kind: Experiment
# ... (其他部分與之前的 YAML 相同)
  pauses:
    after: 10 # 加入 10 秒延遲

加入延遲後,實驗結果符合預期,探針檢測到 Pod 不存在,實驗判定為失敗。這表明系統在 Pod 被終止後未能立即還原。

深入探測:Pod 的 Phase 和 Condition

僅僅檢查 Pod 的存在與否是不夠的。我們需要更深入地探測 Pod 的狀態,例如 Pod 的 Phase 和 Condition。

apiVersion: chaos-toolkit/v1alpha1
kind: Experiment
# ... (其他部分與之前的 YAML 相同)
  steady-state-hypothesis:
    probes:
    - name: pod-in-phase
      type: probe
      tolerance: true
      provider:
        type: python
        module: chaosk8s.pod.probes
        arguments:
          label_selector: app=go-demo-8
          ns: go-demo-8
          phase: Running
    - name: pod-in-conditions
      type: probe
      tolerance: true
      provider:
        type: python
        module: chaosk8s.pod.probes
        arguments:
          label_selector: app=go-demo-8
          ns: go-demo-8
          conditions:
          - type: Ready
            status: "True"

我們新增了兩個探針:pod-in-phasepod-in-conditionspod-in-phase 檢查 Pod 是否處於 Running 狀態,而 pod-in-conditions 檢查 Pod 的 Ready 條件是否為 True

透過這些探針,我們可以更精確地驗證 Pod 的健康狀態,並確保應用程式在 Pod 終止後能夠正常還原。

流程圖:視覺化實驗流程

  graph LR
    A[啟動實驗] --> B{檢查 Pod 存在};
    B -- 存在 --> C[終止 Pod];
    C --> D[延遲 10 秒];
    D --> E{檢查 Pod 存在};
    E -- 不存在 --> F[實驗失敗];
    E -- 存在 --> G[實驗成功];

內容解密: 此流程圖清晰地展示了混沌工程實驗的步驟,包括初始狀態檢查、執行混沌實驗 (終止 Pod)、等待系統反應以及最終狀態驗證。

架構圖:系統元件關係

  graph LR
    subgraph Kubernetes Cluster
        A[Pod: go-demo-8]
    end
    B[Chaos Toolkit] --> C[Kubernetes API];
    C --> A;

內容解密: 此架構圖展示了 Chaos Toolkit、Kubernetes API 和目標 Pod 之間的關係。Chaos Toolkit 透過 Kubernetes API 與 Pod 互動,執行混沌實驗。

透過以上實驗和分析,我們可以更深入地理解 Kubernetes 環境中 Pod 終止的影響,並利用混沌工程方法提高系統的彈性和可靠性。

總結:混沌工程實驗設計的關鍵在於真實模擬和精確驗證。透過加入延遲和更細緻的探針,我們可以更有效地發現系統的弱點,並提升系統的健壯性。Mermaid 圖表的使用則有助於更清晰地呈現實驗流程和系統架構,方便理解和溝通。

應用程式例項銷毀的深入解析:從錯誤中學習

在建構和佈署應用程式的過程中,我們常常會遇到各種意想不到的問題。Pod 狀態錯誤就是其中之一。它可能以各種形式出現,例如 Pod 無法啟動、執行狀態異常,或未能滿足預期條件。這些問題可能源於多種因素,例如缺少必要的依賴項、組態錯誤,或網路連線問題。

在本篇文章中,我將分享一個真實案例,說明如何透過混沌工程實驗來識別和解決 Pod 狀態錯誤。這個案例涉及一個 Go 語言應用程式,它依賴於 MongoDB 資料函式庫。

初始實驗的失敗與 Pod 狀態的誤判

在初始實驗中,我設計了一個混沌工程實驗來模擬 Pod 終止的情況。實驗包含三個探針:pod-exists 檢查 Pod 是否存在,pod-in-phase 檢查 Pod 是否處於執行狀態,pod-in-conditions 檢查 Pod 是否滿足特定條件,例如 Ready 狀態為 True

然而,實驗失敗了。pod-in-conditions 探針回報錯誤,指出 Pod 的 Ready 狀態並非 True。這意味著 Pod 雖然正在執行,但未能達到預期狀態。

檢查 Pod 的日誌後,我發現應用程式嘗試連線到 MongoDB 資料函式庫時發生錯誤。原來,我並沒有佈署 MongoDB 資料函式庫,導致應用程式啟動失敗。

這個錯誤提醒我,在設計混沌工程實驗時,必須仔細檢查 Pod 的初始狀態。僅僅確認 Pod 存在並處於執行狀態是不夠的。我們還需要驗證 Pod 是否滿足所有必要條件,例如所有依賴項都可用,並且組態正確。

佈署 MongoDB 與實驗的再次執行

在佈署 MongoDB 資料函式庫後,我重新執行了混沌工程實驗。這次,所有三個探針在執行動作之前都透過了驗證,表明 Pod 處於正確的狀態。

然而,在終止 Pod 之後,探針再次失敗。這證實了應用程式仍然不具備容錯能力。單個 Pod 的佈署並不能保證高用性和容錯性。

提升應用程式容錯能力的必要性

這個實驗的結果突顯了提升應用程式容錯能力的重要性。在 Kubernetes 中,我們應該使用更高階別的抽象,例如 Deployment,來管理 Pod。Deployment 可以確保 Pod 的多個副本始終執行,並在 Pod 失敗時自動重新啟動。

視覺化 Pod 狀態轉換

以下 Mermaid 狀態圖展示了 Pod 的狀態轉換過程:

  stateDiagram
    [*] --> Pending
    Pending --> Running
    Running --> Succeeded
    Running --> Failed
    Running --> Unknown
    Failed --> Pending

內容解密:

此狀態圖描述了 Pod 的生命週期。Pod 從 Pending 狀態開始,然後轉換到 Running 狀態。如果 Pod 成功完成,則進入 Succeeded 狀態。如果 Pod 失敗,則進入 Failed 狀態。如果 Pod 的狀態未知,則進入 Unknown 狀態。在 Failed 狀態下,Pod 可以重新回到 Pending 狀態,重新啟動。

透過這個案例,我學習到在設計混沌工程實驗時,必須仔細驗證 Pod 的初始狀態,並確保應用程式具備容錯能力。混沌工程實驗可以幫助我們發現系統中的弱點,並促使我們改進系統設計,提升系統的可靠性和彈性。

應用程式的高用性測試

在前一章中,我們探討瞭如何設計混沌實驗來終止應用程式執行個體,以驗證其容錯能力。容錯能力固然重要,但對大多數應用程式來說,僅僅依靠容錯機制並不足夠。我們通常不希望應用程式在發生故障後重新啟動,因為這可能意味著數秒甚至數分鐘的停機時間。雖然 Deployment 和 StatefulSet 等高階 Kubernetes 物件可以確保故障 Pod 的重建,但在銷毀和重新可用之間的停機時間仍可能存在,這並不是我們樂見的。

在本章中,我們將嘗試設計混沌實驗,以驗證範例應用程式是否具備高用性。根據實驗結果,我們可能需要調整應用程式的定義並進行改進。

佈署應用程式

在前一章的結尾,我們刪除了整個 go-demo-8 名稱空間。現在,我們需要重新佈署應用程式。它與我們之前佈署的最後一個版本完全相同。因此,我們可以快速完成佈署過程。

cd go-demo-8
git pull
kubectl create namespace go-demo-8

應用程式定義與前一章相同,包含資料函式庫和以 Deployment 形式定義的 go-demo-8 API。

混沌實驗:終止 Pod

我們先前的實驗證明,如果我們銷毀以 Pod 形式執行的應用程式執行個體,Kubernetes 並不會自動重建新的執行個體。為了提升應用程式的容錯能力,我們將使用 Deployment 來管理 Pod。

以下是 Deployment 的定義:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-demo-8
  labels:
    app: go-demo-8
spec:
  selector:
    matchLabels:
      app: go-demo-8
  template:
    metadata:
      labels:
        app: go-demo-8
    spec:
      containers:
      - name: go-demo-8
        image: vfarcic/go-demo-8:0.0.1
        env:
        - name: DB
          value: go-demo-8-db
        - name: VERSION
          value: "0.0.1"
        ports:
        - containerPort: 8080
        livenessProbe:
          httpGet:
            path: /
            port: 8080
        readinessProbe:
          httpGet:
            path: /
            port: 8080
        resources:
          limits:
            cpu: 100m
            memory: 50Mi
          requests:
            cpu: 50m
            memory: 20Mi

內容解密:

這個 Deployment 定義了一個名為 go-demo-8 的佈署,它使用 vfarcic/go-demo-8:0.0.1 映像建立 Pod。livenessProbereadinessProbe 用於檢查應用程式的健康狀態。資源限制和請求定義了 Pod 的資源使用量。

應用 Deployment:

kubectl --namespace go-demo-8 apply --filename k8s/terminate-pods/deployment.yaml
kubectl --namespace go-demo-8 rollout status deployment go-demo-8

現在,我們再次執行混沌實驗來終止 Pod:

chaos run chaos/terminate-pod-phase.yaml

這次,實驗結果顯示所有探針都透過了。這表明,當 Pod 被終止時,Deployment 會自動建立新的 Pod,確保應用程式持續執行。

從實驗結果分析

透過這個實驗,我們確認了即使應用程式執行個體被銷毀,應用程式仍然可以持續執行,因為 Deployment 和 ReplicaSet 確保了指定數量的 Pod 始終在執行。

需要注意的是,容錯並不等同於高用性。雖然我們確認了應用程式可以承受執行個體故障,但我們還需要進一步驗證其高用性。

  graph LR
    A[Deployment] --> B(ReplicaSet)
    B --> C{Pod 1}
    B --> D{Pod 2}
    B --> E{Pod 3}
    subgraph "Pod Lifecycle"
        C --> F[Terminated]
        B --> G{New Pod}
    end

內容解密:

此圖表展示了 Deployment、ReplicaSet 和 Pod 之間的關係。當 Pod 被終止時,ReplicaSet 會建立新的 Pod 以維持所需的副本數量,確保應用程式的高用性。

透過混沌工程驗證了使用 Deployment 佈署應用程式能有效提升其容錯能力,確保在 Pod 故障時自動重建新的 Pod,維持應用程式的持續執行。接下來,我們將進一步探討如何提升應用程式的高用性。

應用程式可用性實驗:Pod 終止與健康狀態驗證

在 Kubernetes 環境中,應用程式的高用性至關重要。本篇文章將探討如何模擬 Pod 終止的混亂場景,並驗證應用程式在面對此類別突發狀況時的還原能力。我們將使用 chaosk8s 工具來執行這些實驗,並深入分析結果。

佈署應用程式與 Ingress 設定

首先,我們將佈署一個簡單的 Go 應用程式到 Kubernetes 叢集中,並設定 Ingress 控制器,使其可從外部存取。

# k8s/terminate-pods/app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-demo-8
  namespace: go-demo-8
spec:
  replicas: 3
  selector:
    matchLabels:
      app: go-demo-8
  template:
    metadata:
      labels:
        app: go-demo-8
    spec:
      containers:
      - name: go-demo-8
        image: <your-go-app-image>
        ports:
        - containerPort: 8080

內容解密: 以上 YAML 定義了一個名為 go-demo-8 的佈署,它將啟動 3 個 Pod 副本。每個 Pod 都包含一個執行 Go 應用程式的容器,該容器監聽 8080 埠。

接下來,我們需要安裝 Ingress 控制器,例如 nginx Ingress,並建立 Ingress 資源,將外部流量導向我們的應用程式。

kubectl apply --filename https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.27.0/deploy/static/mandatory.yaml
# 選擇適合你的 Kubernetes 平台的 Ingress 設定
# ...
kubectl --namespace go-demo-8 apply --filename k8s/health/ingress.yaml

內容解密: 這些指令安裝了 nginx Ingress 並設定了 Ingress 資源,將 go-demo-8.acme.com 的流量導向我們的應用程式服務。

驗證應用程式可用性

設定完成後,我們可以使用 curl 命令驗證應用程式是否可從外部存取。

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

內容解密: 這個指令模擬從 go-demo-8.acme.com 網域名稱傳送請求,驗證 Ingress 設定是否正確。

混亂實驗:終止 Pod

現在,我們可以使用 chaosk8s 定義一個混亂實驗,模擬 Pod 終止的場景。

# chaos/health.yaml
version: 1.0.0
title: "Pod 終止測試"
description: 驗證應用程式在 Pod 終止後的還原能力
tags:
- k8s
- pod
- deployment
steady-state-hypothesis:
  title: 應用程式健康狀態
  probes:
  - name: 所有 Pod 健康
    type: probe
    tolerance: true
    provider:
      type: python
      func: all_microservices_healthy
      module: chaosk8s.probes
      arguments:
        ns: go-demo-8
method:
  - type: action
    name: 終止 Pod
    provider:
      type: python
      module: chaosk8s.pod.actions
      func: terminate_pods
      arguments:
        label_selector: app=go-demo-8
        rand: true
        ns: go-demo-8

內容解密: 這個 YAML 定義了一個 chaosk8s 實驗,它將隨機終止一個帶有 app=go-demo-8 標籤的 Pod,並驗證應用程式是否仍然健康。

執行實驗與觀察結果

執行 chaosk8s run chaos/health.yaml 命令即可開始實驗。觀察 Pod 的狀態變化以及應用程式的反應。Kubernetes 的自我修復機制應該會自動啟動新的 Pod 來取代被終止的 Pod,確保應用程式持續執行。

透過模擬 Pod 終止的混亂實驗,我們可以驗證 Kubernetes 應用程式的高用性和自我修復能力。chaosk8s 提供了一個簡便的工具來執行這類別實驗,幫助我們更好地理解和提升應用程式的穩定性。

  graph LR
    A[Ingress Controller] --> B(Service go-demo-8)
    B --> C{Pod 1}
    B --> D{Pod 2}
    B --> E{Pod 3}
    subgraph Kubernetes Cluster
        C
        D
        E
    end

圖表說明: 此圖展示了 Ingress 控制器、服務和 Pod 之間的關係。Ingress 控制器將外部流量導向服務,服務再將流量分發到各個 Pod。

  sequenceDiagram
    participant User
    participant Ingress
    participant Service
    participant Pod

    User->>Ingress: HTTP Request (go-demo-8.acme.com)
    Ingress->>Service: Forward Request
    Service->>Pod: Forward Request
    Pod->>Service: HTTP Response
    Service->>Ingress: Forward Response
    Ingress->>User: HTTP Response

圖表說明: 此時序圖展示了使用者請求如何透過 Ingress、服務和 Pod,最終傳回回應的流程。

應用程式終止後的自動還原機制:探討健康狀態與延遲

在探討應用程式容錯能力時,僅確認 Pod 的執行狀態並不足夠。Pod 啟動並不等同於應用程式可正常存取。本篇文章將探討如何驗證應用程式在例項終止後的自動還原能力,並著重分析健康狀態檢查和延遲機制的重要性。

初步實驗:忽略延遲的健康狀態檢查

首先,我們設計一個實驗,模擬應用程式例項終止後的場景。實驗目標是驗證名稱空間內所有應用程式例項的健康狀態。我們使用 all_microservices_healthy 函式來檢查名稱空間 go-demo-8 的健康狀態。實驗步驟如下:

  1. 初始狀態檢查: 確認所有應用程式例項健康。
  2. 終止操作: 隨機終止一個帶有特定標籤 app=go-demo-8 的 Pod。
  3. 再次檢查: 再次檢查所有應用程式例項的健康狀態。

Mermaid 流程圖如下:

  graph LR
A[初始狀態檢查] --> B{所有例項健康?};
B -- Yes --> C[終止 Pod];
B -- No --> F[實驗失敗];
C --> D[延遲];
D --> E[再次檢查];
E -- Yes --> G[實驗成功];
E -- No --> F;

執行實驗後發現,儘管 Kubernetes 會自動重建被終止的 Pod,但實驗仍然失敗。這是因為新的 Pod 需要時間來初始化和啟動服務,而我們沒有給予系統足夠的時間來還原。

加入延遲機制:完善健康狀態檢查

為瞭解決這個問題,我們在實驗中加入了延遲機制。在終止 Pod 後,我們會暫停 10 秒,再進行健康狀態檢查。修改後的實驗定義如下:

pauses:
  after: 10

Mermaid 時序圖如下:

  sequenceDiagram
    participant Chaos Toolkit
    participant Kubernetes
    Chaos Toolkit->>Kubernetes: 終止 Pod
    activate Kubernetes
    Kubernetes-->>Chaos Toolkit: Pod 終止完成
    deactivate Kubernetes
    Chaos Toolkit->>Chaos Toolkit: 暫停 10 秒
    Chaos Toolkit->>Kubernetes: 檢查 Pod 狀態
    activate Kubernetes
    Kubernetes-->>Chaos Toolkit: Pod 執行中
    deactivate Kubernetes

加入延遲後再次執行實驗,結果顯示實驗成功。這證明瞭延遲機制的重要性。在實際應用中,我們需要根據應用程式的啟動時間和環境複雜度來調整延遲時間,確保系統有足夠的時間還原到健康狀態。

內容解密:

pauses: after: 10 這段程式碼定義了在執行終止 Pod 的動作後,Chaos Toolkit 將會暫停 10 秒。這個延遲機制允許系統有足夠的時間來重新啟動 Pod 並還原服務,從而更準確地驗證應用程式的容錯能力。在實際應用中,延遲時間的設定需要根據具體的應用程式和環境進行調整。

應用程式容錯測試不僅要關注 Pod 的執行狀態,更要關注應用程式的整體健康狀態。透過加入延遲機制,我們可以更準確地評估應用程式在例項終止後的自動還原能力,並根據測試結果調整系統組態,提升系統的穩定性和可靠性。合理的延遲時間設定至關重要,它能確保系統在遭受故障後有足夠的時間還原,從而避免誤判系統的健康狀態。

應用程式可用性實驗:單點失效的挑戰

在探索如何驗證應用程式能否持續接收 HTTP 請求,尤其是在應用程式的一個例項被銷毀後,我發現了一個問題:難以在 YAML 中定義應用程式的地址,因為大家的 IP 地址幾乎不可能相同,而與我們也沒有使用真實的網域名稱,因為設定起來太複雜。這個問題讓我想到可以利用 Chaos Toolkit 的一個特性:變數注入。

我們先來看一下新的 YAML 檔案 chaos/health-http.yaml 與之前的 chaos/health-pause.yaml 的差異:

3c3
< description: If an instance of the application is terminated, a new instance should be created
> - http
> configuration:
>   ingress_host:
>     type: env
>     key: INGRESS_HOST
11c15
< - name: all-apps-are-healthy
---
> - name: app-responds-to-requests
13c17
< tolerance: true
---
> tolerance: 200
15,19c19,24
< type: python
< func: all_microservices_healthy
< module: chaosk8s.probes
< arguments:
< ns: go-demo-8
---
> type: http
> timeout: 3
> verify_tls: false
> url: http://${ingress_host}/demo/person
> headers:
>   Host: go-demo-8.acme.com
32c37
< after: 10
---
> after: 2

主要變更如下:

  • 新增了一個 configuration 區段,其中定義了一個名為 ingress_host 的變數。這個變數的型別是環境變數 (env),鍵值為 INGRESS_HOST。這表示如果我們設定了環境變數 INGRESS_HOST,該變數的值將會被指定給 Chaos Toolkit 變數 ingress_host
  • steady-state-hypothesis 的名稱和容錯機制也做了調整。現在的容錯設定為 200,意味著

應用程式的高用性:實戰 Kubernetes 混沌工程

確保應用程式在部分元件失效時仍能正常運作,是建構高用性系統的關鍵。本文將透過實際案例,探討如何在 Kubernetes 環境中運用混沌工程驗證應用程式的高用性。

水平 Pod 自動擴充套件器 (HPA) 設定

我們將使用 HorizontalPodAutoscaler (HPA) 來動態調整應用程式的 Pod 數量,以應對負載變化。以下 YAML 檔案定義了一個名為 go-demo-8 的 HPA:

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: go-demo-8
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: go-demo-8
  minReplicas: 2
  maxReplicas: 6
  metrics:
  - type: Resource
    resource:
      name: cpu
    targetAverageUtilization: 80
  - type: Resource
    resource:
      name: memory
    targetAverageUtilization: 80

內容解密:

這個 HPA 設定檔指定目標 Deployment 為 go-demo-8,最小 Pod 數量為 2,最大 Pod 數量為 6。HPA 將根據 CPU 和記憶體的平均使用率來動態調整 Pod 數量,目標是將兩者都維持在 80% 左右。雖然在實際應用中,僅依靠 CPU 和記憶體指標可能不足,但在這個範例中已足夠。

佈署 HPA:

kubectl apply --namespace go-demo-8 --filename k8s/health/hpa.yaml

驗證 HPA 狀態:

kubectl --namespace go-demo-8 get hpa

HPA 需要一些時間才能調整 Pod 數量。持續執行 get hpa 指令,直到 Pod 數量增加到 2 或以上。

混沌實驗:終止應用程式 Pod

為了驗證 HPA 是否有效提升應用程式的高用性,我們將執行混沌實驗,模擬應用程式 Pod 故障的情況。以下混沌實驗定義檔 chaos/health-http.yaml 驗證應用程式在一個 Pod 被終止後是否仍能正常回應請求:

# chaos/health-http.yaml 內容,請參考前文

執行實驗:

chaos run chaos/health-http.yaml

實驗結果顯示,即使一個 Pod 被終止,應用程式仍然能夠正常回應請求,證明 HPA 成功地維持了應用程式的高用性。

混沌實驗:終止資料函式庫 Pod

現在,我們將進一步驗證應用程式在資料函式庫 Pod 故障時的行為。以下混沌實驗定義檔 chaos/health-db.yamlchaos/health-http.yaml 幾乎相同,主要差異在於 label_selector,這次的目標是終止資料函式庫 Pod:

# chaos/health-db.yaml 內容,請參考前文

兩個檔案的差異:

# 顯示兩個檔案的差異,請參考前文

執行實驗:

chaos run chaos/health-db.yaml

實驗結果顯示,當資料函式庫 Pod 被終止後,應用程式無法正常回應請求。這表明應用程式對資料函式庫的依賴性很高,資料函式庫的單點故障會直接影回應用程式的可用性。

透過 HPA,我們可以確保應用程式在 Pod 故障時仍能維持一定的可用性。然而,實驗也顯示,應用程式對資料函式庫的依賴性是潛在的弱點。未來可以探討如何提升資料函式庫的高用性,例如佈署資料函式庫叢集或使用其他高用性解決方案,以進一步增強整體系統的穩健性。

  graph LR
    A[應用程式 Pod] --> B(資料函式庫 Pod)
    C[HPA] --> A
    D[使用者請求] --> A
    subgraph "混沌實驗 1:終止應用程式 Pod"
        A1[應用程式 Pod 1] -.-> X
        A2[應用程式 Pod 2] --> B
        D --> A2
    end
    subgraph "混沌實驗 2:終止資料函式庫 Pod"
        A --> B1[資料函式庫 Pod 1] -.-> X
        D --> A
    end
    style X fill:#f9f,stroke:#333,stroke-width:2px

內容解密:

此圖表展示了應用程式、資料函式庫和 HPA 之間的關係,以及兩個混沌實驗的場景。紅色標記的節點表示被終止的 Pod。實驗 1 模擬應用程式 Pod 故障,HPA 確保其他 Pod 能繼續服務;實驗 2 模擬資料函式庫 Pod 故障,導致應用程式無法正常運作。

模擬網路故障:強化系統韌性的試煉

在先前的討論中,我們探討瞭如何模擬應用程式例項的終止,以測試系統的容錯能力。現在,我們將進一步探討如何透過網路故障模擬,將混沌工程實驗提升到一個全新的層級。藉由破壞、阻礙或偽造網路中的特定環節,我們可以更全面地檢驗系統的韌性。

Kubernetes 提供了多種網路管理方式,今天我們將聚焦於最常用的 Istio 服務網格。選擇 Istio 的主要原因是它目前最廣泛使用的服務網格解決方案。此外,Chaos Toolkit 也提供了 Istio 外掛,方便我們進行實驗。當然,您也可以將這些經驗應用到其他網路解決方案中,並利用 Chaos Toolkit 的靈活性執行自定義命令。

您可能會好奇,為什麼需要服務網格?在混沌工程的背景下,服務網格提供了強大的流量管理能力,例如:中止請求、繞過特定服務、延遲請求等,這些功能與我們的實驗目標完美契合。

實驗環境準備

在開始實驗之前,我們需要準備一個 Kubernetes 叢集,並佈署我們將要測試的應用程式。如果您在上一篇文章的實驗後保留了叢集,可以直接跳到下一節。如果您需要重新建立叢集,可以使用以下 Gist 中提供的指令碼,或自行搭建叢集。

  • Docker Desktop: docker.sh
  • Minikube: minikube.sh
  • GKE: gke.sh
  • EKS: eks.sh
  • AKS: aks.sh

安裝 Istio 服務網格

接下來,我們需要安裝 Istio 服務網格。如果您已經熟悉 Istio,可以直接跳過以下步驟,自行安裝。如果您是 Istio 新手,也不用擔心,安裝過程相當簡單。

首先,您需要安裝 istioctl 工具。如果尚未安裝,請前往 Istio Releases 頁面下載並安裝。

然後,執行以下命令即可安裝 Istio:

istioctl manifest install --skip-confirmation

安裝過程可能需要一些時間。安裝完成後,我們需要確認 Istio Ingress Gateway 服務已分配到外部 IP。執行以下命令:

kubectl --namespace istio-system get service istio-ingressgateway

在大多數情況下,尤其是在雲端環境中執行 Kubernetes 時,外部 IP 表示正在建立外部負載平衡器(LB)。如果 EXTERNAL-IP 欄位的值為 <pending>,則表示外部 LB 仍在建立中。請重複執行上述命令,直到該欄位顯示一個 IP 地址。

請注意,Docker Desktop 和 Minikube 無法建立外部負載平衡器,因此 EXTERNAL-IP 欄位將一直保持 <pending> 狀態。這沒有問題,如果您使用的是這些 Kubernetes 發行版,可以忽略等待 IP 地址的步驟。

為了簡化後續操作,我們將取得 Istio Ingress 主機,並將其儲存到變數 INGRESS_HOST 中。取得方式會根據 Kubernetes 叢集的型別而有所不同,我們將在後續文章中詳細說明。

內容解密:

這段文字描述瞭如何準備 Kubernetes 叢集和安裝 Istio 服務網格,為後續的網路故障模擬實驗做好準備。它解釋了為什麼選擇 Istio,以及 Istio 在混沌工程實驗中的作用。同時,它也提供了一些實用的指令碼和命令,方便讀者快速搭建實驗環境。特別需要注意的是,EXTERNAL-IP 的狀態在不同 Kubernetes 發行版中可能不同,讀者需要根據自己的環境進行調整。

  graph LR
    A[準備 Kubernetes 叢集] --> B{安裝 Istio}
    B --> C(確認 Ingress Gateway)
    C --> D{取得 Ingress 主機}

上圖展示了準備實驗環境的流程。首先準備 Kubernetes 叢集,然後安裝 Istio 服務網格,接著確認 Ingress Gateway 的狀態,最後取得 Ingress 主機。