天天看點

ChaosBlade:從零開始的混沌工程(三

ChaosBlade:從零開始的混沌工程(三

前言

在上篇文章中,我們介紹了如何安裝 ChaosBlade Operator,并進行了簡單的使用。從本章開始,所有的實踐章節,都會有配套的

katacode

互動式教程,讀者可用通過 katacode,在浏覽器上操作真實的 Kubernetes 和 ChaosBlade。

KataCoda 教程:《ChaosBlade Pod 實驗場景》

位址:

https://katacoda.com/guoxudong/courses/chaosblade/pod-experiment

實驗對象:Pod

Pod 是 Kubernetes 應用程式的基本執行單元,即它是 Kubernetes 對象模型中建立或部署的最小和最簡單的單元。Pod 表示在 叢集 上運作的程序。

Pod 封裝了應用程式容器(或者在某些情況下封裝多個容器)、存儲資源、唯一網絡 IP 以及控制容器應該如何運作的選項。 Pod 表示部署單元:Kubernetes 中應用程式的單個執行個體,它可能由單個 容器 或少量緊密耦合并共享資源的容器組成。

Pod 實驗場景

Pod 作為 Kubernetes 最基本的執行單元,對于 Kubernetes 叢集來說十分重要。那麼對于混沌工程,從 Pod 入手實踐就再合适不過了。

本篇預設已安裝 guestbook 應用和 ChaosBlade Operator。

删除 Pod 場景

實驗目标:删除

chaosblade

命名空間下标簽是

role=master

的 pod。

執行觀測

開始觀察需要删除的 pod:

$ kubectl get pod -l "role=master" -n chaosblade -w           

開始實驗

delete_pod_by_labels.yaml

内容:

apiVersion: chaosblade.io/v1alpha1
kind: ChaosBlade
metadata:
  name: delete-two-pod-by-labels
spec:
  experiments:
  - scope: pod
    target: pod
    action: delete
    desc: "delete pod by labels"
    matchers:
    - name: labels
      value:
      - "role=master"
    - name: namespace
      value:
      - "chaosblade"
    - name: evict-count
      value:
      - "2"           

建立終端,并開始實驗:

$ kubectl apply -f delete_pod_by_labels.yaml           

檢視實驗狀态

執行指令:

kubectl get blade delete-two-pod-by-labels -o json

,檢視實驗狀态。

檢視實驗結果

通過上面的觀測指令,可以看到 pod 被删除并重新開機,結果符合預期。

ChaosBlade:從零開始的混沌工程(三

停止實驗

kubectl delete -f delete_pod_by_labels.yaml

或者直接删除 blade 資源:

kubectl delete blade delete-two-pod-by-labels

Pod 網絡延遲場景

實驗目标:在 chaosblade 命名空間中,對

redis-master-68857cd57c-dzbs9

Pod 的本地 6379 端口添加 3000 毫秒通路延遲,延遲時間上下浮動 1000 毫秒。

delay_pod_network_by_names.yaml

apiVersion: chaosblade.io/v1alpha1
kind: ChaosBlade
metadata:
  name: delay-pod-network-by-names
spec:
  experiments:
  - scope: pod
    target: network
    action: delay
    desc: "delay pod network by names"
    matchers:
    - name: names
      value:
      - "redis-master-68857cd57c-dzbs9"
    - name: namespace
      value:
      - "chaosblade"
    - name: local-port
      value: ["6379"]
    - name: interface
      value: ["eth0"]
    - name: time
      value: ["3000"]
    - name: offset
      value: ["1000"]           

擷取 Pod 名稱:

$ kubectl get pod -l app=redis,role=master -o jsonpath={.items..metadata.name}           

修改

delay_pod_network_by_names.yaml

中的

name

字段的值。

執行指令,開始實驗:

$ kubectl apply -f delay_pod_network_by_names.yaml           

執行

kubectl get blade delay-pod-network-by-names -o json

指令,檢視實驗狀态。

觀測結果

# 擷取實驗 pod ip
$ kubectl get pod -l app=redis,role=master -o jsonpath={.items..status.podIP}
10.42.69.44
# 進入觀測 pod
$ kubectl exec -it redis-slave-6dd975d4c8-2zrkb bash
# 在 pod 中安裝 telnet
$ apt-get update && apt-get install -y telnet
# 測試時間
$ time echo "" | telnet 10.42.69.44 6379
Trying 10.42.69.44...
Connected to 10.42.69.44.
Escape character is '^]'.
Connection closed by foreign host.

real    0m3.790s
user    0m0.007s
sys     0m0.001s           

可以看到通路實驗 pod 6379 端口的延遲為 3s 左右,結果符合預期。

ChaosBlade:從零開始的混沌工程(三

kubectl delete -f delay_pod_network_by_names.yaml

kubectl delete blade delay-pod-network-by-names

Pod 網絡丢包場景

redis-master-68857cd57c-dzbs9

Pod 注入丢包率 100% 的故障,隻針對 IP 為 10.42.69.42 的 pod 生效,也就是除 10.42.69.42 以外的 pod 都能正常通路

redis-master-68857cd57c-dzbs9

擷取 pod 名稱内容同上。

loss_pod_network_by_names.yaml

apiVersion: chaosblade.io/v1alpha1
kind: ChaosBlade
metadata:
  name: loss-pod-network-by-names
spec:
  experiments:
  - scope: pod
    target: network
    action: loss
    desc: "loss pod network by names"
    matchers:
    - name: names
      value:
      - "redis-master-68857cd57c-dzbs9"
    - name: namespace
      value:
      - "chaosblade"
    - name: interface
      value: ["eth0"]
    - name: percent
      value: ["100"]
    - name: timeout
      value: ["60"]
    - name: destination-ip
      value: ["10.42.69.42"]           
$ kubectl apply -f loss_pod_network_by_names.yaml           

kubectl get blade loss-pod-network-by-names -o json

# 擷取實驗 pod ip
$ kubectl get pod -l app=redis,role=master -o jsonpath={.items..status.podIP}
10.42.69.44
# 進入觀測 pod,IP為:10.42.69.42(被設定丢包率 100%)
$ kubectl exec -it redis-slave-6dd975d4c8-lm8jz bash
# Ping 實驗Pod ip
$ ping 10.42.69.44
PING 10.42.69.44 (10.42.69.44) 56(84) bytes of data.
# 無響應

# 進入觀測 pod,該 pod 未被指定丢包
$ kubectl exec -it redis-slave-6dd975d4c8-2zrkb bash
# Ping 實驗Pod ip
$ ping 10.42.69.44
PING 10.42.69.44 (10.42.69.44) 56(84) bytes of data.
64 bytes from 10.42.69.44: icmp_seq=1 ttl=63 time=0.128 ms
64 bytes from 10.42.69.44: icmp_seq=2 ttl=63 time=0.128 ms
64 bytes from 10.42.69.44: icmp_seq=3 ttl=63 time=0.092 ms
...
# 響應正常           

可以看到觀測 pod 通路實驗 pod 丢包率 100%(無法通路),而其他 pod 不受影響,結果符合預期。

ChaosBlade:從零開始的混沌工程(三

這裡在配置中将

timeout

設定為 60 秒,60 秒後 100% 丢包的情況将會消失,這個配置是為了防止因丢包率設定太高,造成機器無法連接配接的情況。與其有相似功能的還有

exclude-port

,該配置指定一些端口不會丢包,以免該 pod 失聯。

kubectl delete -f loss_pod_network_by_names.yaml

kubectl delete blade loss-pod-network-by-names

)

Pod 域名通路異常場景

實驗目标:Pod 内通路指定域名異常。

dns_pod_network_by_names.yaml

apiVersion: chaosblade.io/v1alpha1
kind: ChaosBlade
metadata:
  name: dns-pod-network-by-names
spec:
  experiments:
  - scope: pod
    target: network
    action: dns
    desc: "dns pod network by names"
    matchers:
    - name: names
      value:
      - "redis-slave-6dd975d4c8-lm8jz"
    - name: namespace
      value:
      - "chaosblade"
    - name: domain
      value: ["www.baidu.com"]
    - name: ip
      value: ["10.0.0.1"]           
$ kubectl apply -f dns_pod_network_by_names.yaml           

kubectl get blade dns-pod-network-by-names -o json

# 進入實驗 pod
$ kubectl exec -it redis-slave-6dd975d4c8-lm8jz bash
# Ping www.baidu.com
$ ping www.baidu.com
# 無響應           

可以看到通路指定域名

www.baidu.com

異常,結果符合預期。

ChaosBlade:從零開始的混沌工程(三

kubectl delete -f dns_pod_network_by_names.yaml

kubectl delete blade dns-pod-network-by-names

Pod 檔案系統 I/O 故障場景

實驗目标:給 kubernetes 的 pod 注入檔案系統I/O故障。

注意:此場景需要激活

--webhook-enable

參數,如需使用此功能,請在 chaosblade-operator 參數中添加

--webhook-enable

,或者在安裝時指定:例如 helm 安裝時添加

--set webhook.enable=true

指定。

前提條件

  • 叢集中部署了

    chaosblade-admission-webhook

  • 需要注入故障的

    volume

    設定

    mountPropagation

    HostToContainer

  • pod上面添加了如下annotations:
chaosblade/inject-volume: "data" //需要注入故障的volume name
chaosblade/inject-volume-subpath: "conf" //volume挂載的子目錄           

部署測試 pod

chaosblade webhook 會根據 pod 的 annotation,注入 fuse 的 sidecar 容器:

  1. chaosblade/inject-volume

    指明需要注入故障的 volume name,比如例子中的

    data

  2. chaosblade/inject-volume-subpath

    指明 volume 挂載路徑的子目錄。上面的例子中,volume 的挂載路徑是

    /data

    ,子目錄是

    conf

    ,則在 pod 内,注入I/O異常的目錄是

    /data/conf

  3. 指定需要注入故障的 volume 需要指定

    mountPropagation:HostToContainer

    ,這個字段的含義可以參考官方文檔 Volumes
# 部署測試 pod
$ kubectl apply -f io-test-pod.yaml
# 檢視 sidecar 是否注入成功
$ kubectl get pod test-7c9fc6fd88-7lx6b -n chaosblade
NAME                    READY   STATUS    RESTARTS   AGE
test-7c9fc6fd88-7lx6b   2/2     Running   0          4m8s           

pod_io.yaml

apiVersion: chaosblade.io/v1alpha1
kind: ChaosBlade
metadata:
  name: inject-pod-by-labels
spec:
  experiments:
  - scope: pod
    target: pod
    action: IO
    desc: "Pod IO Exception by labels"
    matchers:
    - name: labels
      value:
      - "app=test"
    - name: namespace
      value:
      - "chaosblade"
    - name: method
      value:
      - "read"
    - name: delay
      value:
      - "1000"
    - name: path
      value:
      - ""
    - name: percent
      value:
      - "60"
    - name: errno
      value:
      - "28"           
$ kubectl apply -f pod_io.yaml           

kubectl get blade inject-pod-by-labels -o json

# 進入實驗 pod
$ kubectl exec -it test-7c9fc6fd88-7lx6b bash
# 在 pod 内讀取指定目錄中的檔案,如果沒有可以建立一個
$ time cat /data/conf/test.yaml
cat: read error: No space left on device

real    0m3.007s
user    0m0.002s
sys     0m0.002s
# 因為有重試,顯示有 3s 的延遲
# 因為設定了 60% 的異常,所有還是有成功的情況
$ time cat /data/conf/test.yaml
123

real    0m0.004s
user    0m0.002s
sys     0m0.000s           

檔案讀取異常,結果符合預期。

ChaosBlade:從零開始的混沌工程(三

在本例中,我們對 read 操作注入兩種異常,異常率為百分之60:

  • read

    操作增加 1s 的延遲。
  • read

    操作傳回錯誤

    28

這裡隻是做了一種類型的實驗,更多的實驗類型詳見

官方文檔

kubectl delete -f pod_io.yaml

kubectl delete blade inject-pod-by-labels

删除測試 pod:

kubectl delete -f io-test-pod.yaml

結語

本篇我們使用 ChaosBlade Operator 對 Kubernetes Pod 資源進行混沌工程實驗,可以看到 ChaosBlade 的操作簡單易懂且功能強大,通過模拟不同的故障,可以檢驗我們系統監控報警的時效性,也可以檢驗我們系統在遇到故障時的情況,根據這些情況對系統進行調整,進而完善系統架構,增加可用性。

這裡隻是對于每種場景進行了簡單的實驗,而每個場景不止有一種實驗方式,使用者可以通過調整參數進行不同的實驗。