天天看點

故障注入與服務網格:測試和驗證的利器

作者:opendotnet

背景

故障注入

故障注入技術最初是在航空航天領域中開發的,用于模拟和測試飛機、飛彈等複雜系統的可靠性。後來,這項技術逐漸被應用到其他領域,包括計算機軟體、汽車、醫療裝置等。

随着網際網路和軟體系統的快速發展,複雜度和規模不斷擴大。是以,系統中的故障和異常在所難免。為了確定系統在遇到故障時能夠保持穩定運作并盡快恢複,開發人員和運維團隊需要提前預測和處理潛在的故障。故障注入慢慢地在計算機軟體中得到應用。

故障注入的重要性在于它可以幫助開發人員更好地了解系統的行為,并确定哪些部分可能存在缺陷。通過模拟各種可能的故障情況,開發人員可以評估系統在不同條件下的響應能力,并将這些資訊用于改進軟體設計和實作。

故障注入與服務網格:測試和驗證的利器

故障注入的功能

  • • 使開發和測試人員友善地進行可靠性測試,發現潛在的問題并優化系統設計,進而提升系統的健壯性。
  • • 幫助驗證系統的異常和故障處理機制是否有效,確定系統在遇到故障時能夠正确地執行故障處理政策。
  • • 服務降級是在系統發生故障時,暫時關閉部分功能以確定整體的可用性。故障注入可用于評估服務降級政策,通過模拟故障場景檢驗服務降級的實際表現。

服務網格

服務網格是一種架構模式,用于處理分布式系統中的服務間通信和服務治理問題。服務網格通常由一組網絡代理和服務間通信協定組成,用于管理和控制服務之間的通信。服務網格可以提供諸如服務發現、負載均衡、安全認證、流量控制、故障恢複等功能,以幫助開發人員和運維人員管理分布式系統的複雜性和可靠性。

Flomesh 服務網格

Flomesh 服務網格使用可程式設計代理 Pipy[1] 為核心提供東西、南北向的流量管理和豐富的服務治理能力。通過基于 L7 的流量管理能力,突破計算環境間的網絡隔離,建立一個虛拟的平面網絡,使不同計算環境中應用可以互相通信,實作覆寫多叢集的“大網格”。

故障注入與服務網格

服務網格中的代理對服務的流量進行攔截,可以實作流量的控制。攔截到服務流量時,可以通過注入故障或者異常來測試服務的容錯性和健壯性。比如可以通過服務網格來模拟服務的延遲、錯誤響應等等。

當我們使用傳統的故障注入時,通常需要在應用程式中嵌入特定的代碼或者 SDK 來實作對應用程式行為的修改和控制,比如 Chaos Monkey[2]。而由于服務網格的網絡代理與應用本身的天然解耦合,可以實作無侵入的故障注入。這種無侵入的故障注入不僅可以減少對應用程式的影響,還可以提高故障注入的靈活性和可靠性。

今天就為大家來介紹如何使用 Flomesh 服務網格的故障注入功能。

Flomesh 服務網格的故障注入

Flomesh 服務網格秉持着簡單、易用的設計原則,提供滿足使用者的最小功能集。故障注入功能并未包含在其中,但通過靈活的 插件擴充功能[3] 可以輕松地為服務網格擴充新的功能,這個在之前的文章 使用插件擴充服務網格 中也有過詳細介紹。

這下面的示範中,我們将使用 故障注入插件[4] 實作對目标服務的故障注入。首先我們看一下可注入的故障類型:

  • • 延遲響應:在服務調用時,為一定比例的響應人為地加入的延遲,模拟目标服務的不穩定來測試服務的容錯能力、優化負載均衡政策等。
  • • 終止響應:模拟服務響應異常終止的情況,進而測試系統的容錯性和健壯性。比如驗證重試機制、降級能力等等。

功能配置

  • config

    故障類型及配置
    • httpStatus

      :終止響應時的響應狀态碼,比如

      400

      501

      503

    • percentage.value

      :終止的百分比,

      0.5

      表示對

      50%

      的響應會被終止
    • fixedDelay

      :設定延遲的時長,

      1s

      表示為響應假如 1 秒鐘的延遲
    • percentage.value

      :延遲的百分比,

      0.5

      表示對

      50%

      的響應注入延遲
    • delay

      延遲
    • abort

      終止
  • plugin:

    表示這個配置是插件

    http-fault-injection

    的配置
  • destinationRefs

    : 表示配置生效的負載。比如命名空間

    pipy

    下的 Service

    pipy-ok

kind: PluginConfig
apiVersion: plugin.flomesh.io/v1alpha1
metadata:
 name: http-fault-injection-config
 namespace: pipy
spec:
 config:
 delay:
 percentage:
 value: 0.5
 fixedDelay: 1s
 abort:
 percentage:
 value: 0.5
 httpStatus: 400
 plugin: http-fault-injection
 destinationRefs:
 - kind: Service
 name: pipy-ok
 namespace: pipy           

示範

建立叢集

export INSTALL_K3S_VERSION=v1.23.8+k3s2
curl -sfL https://get.k3s.io | sh -s - --disable traefik --disable servicelb --write-kubeconfig-mode 644 --write-kubeconfig ~/.kube/config           

安裝服務網格

下載下傳 CLI。

system=$(uname -s | tr [:upper:] [:lower:]) 
arch=$(dpkg --print-architecture) 
release=v1.3.3 
curl -L https://github.com/flomesh-io/osm-edge/releases/download/${release}/osm-edge-${release}-${system}-${arch}.tar.gz | tar -vxzf - 
./${system}-${arch}/osm version 
cp ./${system}-${arch}/osm /usr/local/bin/           

安裝服務網格。

osm install           

部署示例應用

kubectl create namespace curl
osm namespace add curl
kubectl apply -n curl -f https://raw.githubusercontent.com/flomesh-io/osm-edge-docs/release-v1.3/manifests/samples/plugins/curl.yaml

kubectl create namespace pipy
osm namespace add pipy
kubectl apply -n pipy -f https://raw.githubusercontent.com/flomesh-io/osm-edge-docs/release-v1.3/manifests/samples/plugins/pipy-ok.pipy.yaml

# Wait for pods to be up and ready

sleep 2
kubectl wait --for=condition=ready pod -n curl -l app=curl --timeout=180s
kubectl wait --for=condition=ready pod -n pipy -l app=pipy-ok -l version=v1 --timeout=180s
kubectl wait --for=condition=ready pod -n pipy -l app=pipy-ok -l version=v2 --timeout=180s           

驗證服務通路。

curl_client="$(kubectl get pod -n curl -l app=curl -o jsonpath='{.items[0].metadata.name}')"

kubectl exec ${curl_client} -n curl -c curl -- curl -ksi http://pipy-ok.pipy:8080 ; echo "";            

你将會看到如下的響應,多次請求可以發現 v1 和 v2 版本的服務輪流響應。

HTTP/1.1 200 OK
content-length: 20
connection: keep-alive

Hi, I am PIPY-OK v1!           

啟用插件特性

預設情況下,服務網格是沒有開啟插件特性的。可以通過下面的指令開啟:

kubectl patch meshconfig osm-mesh-config -n osm-system -p '{"spec":{"featureFlags":{"enablePluginPolicy":true}}}' --type=merge           

故障注入插件

插件的應用包含了兩個部分:

  • • 聲明插件:也就是建立插件的過程。插件聲明後,才可以被其他資源引用。
  • • 配置插件鍊:服務治理的功能分布于流量處理的各個階段,比如 4 層的處理、7 層的路由、負載均衡等等。插件鍊則是對插件進行編排,指定其工作的階段以及作用的資源。

聲明插件

執行下面的聲明插件。插件是使用 PipyJS[5] 開發的,對故障注入插件感興趣的同學可以通路 Github 浏覽 源碼[6]。

kubectl apply -f https://raw.githubusercontent.com/flomesh-io/osm-edge-docs/release-v1.3/manifests/samples/plugins/fault-injection.yaml           

配置插件鍊

插件鍊

http-fault-injection-chain

  • metadata.name

    :插件鍊資源名稱

    http-fault-injection-chain

  • spec.chains

    • name

      :所處的插件鍊名稱,4 個插件鍊之一,這裡是

      inbound-http

      也就是出站流量的 HTTP 協定處理階段。
    • plugins

      :要插入到插件鍊的插件清單,這裡将

      http-fault-injection

      插入到插件鍊中。
  • spec.selectors

    :插件鍊作用的目标,使用的是 Kubernetes 标簽選擇器[7] 方案。
    • podSelector

      :pod 選擇器,選擇标簽

      app=pipy-ok

      的 pod。
    • namespaceSelector

      :命名空間選擇器,選擇命名空間被網格納管的命名空間,即

      openservicemesh.io/monitored-by=osm

kubectl apply -f - <<EOF
kind: PluginChain
apiVersion: plugin.flomesh.io/v1alpha1
metadata:
 name: http-fault-injection-chain
 namespace: pipy
spec:
 chains:
 - name: inbound-http
 plugins:
 - http-fault-injection
 selectors:
 podSelector:
 matchLabels:
 app: pipy-ok
 matchExpressions:
 - key: app
 operator: In
 values: ["pipy-ok"]
 namespaceSelector:
 matchExpressions:
 - key: openservicemesh.io/monitored-by
 operator: In
 values: ["osm"]
EOF
           

此時,我們執行前面指令進行驗證,可以發現服務扔可正常通路。這是因為還缺少故障注入的配置。

配置注入故障

注入延遲

這裡我們配置為

50%

的響應加上

2s

的延遲。

kubectl apply -n pipy -f - <<EOF
kind: PluginConfig
apiVersion: plugin.flomesh.io/v1alpha1
metadata:
 name: http-fault-injection-config
 namespace: pipy
spec:
 config:
 delay:
 percentage:
 value: 0.5
 fixedDelay: 2s
 plugin: http-fault-injection
 destinationRefs:
 - kind: Service
 name: pipy-ok
 namespace: pipy
EOF           

為了友善看到效果請求前後我們列印下目前的時間。多次請求後可以發現一半的請求響應時間超過 5s。

date; kubectl exec ${curl_client} -n curl -c curl -- curl -ksi http://pipy-ok.pipy:8080 ; echo ""; date
Mon Apr 3 11:21:58 UTC 2023
HTTP/1.1 200 OK
content-length: 20
connection: keep-alive

Hi, I am PIPY-OK v1!
Mon Apr 3 11:22:00 UTC 2023           

終結響應

接下來我們修改插件配置,去掉

delay

的配置,為

abort

添加配置:50% 的情況下傳回

500

的響應。

kubectl apply -n pipy -f - <<EOF
kind: PluginConfig
apiVersion: plugin.flomesh.io/v1alpha1
metadata:
 name: http-fault-injection-config
 namespace: pipy
spec:
 config:
 abort:
 percentage:
 value: 0.5
 httpStatus: 500
 plugin: http-fault-injection
 destinationRefs:
 - kind: Service
 name: pipy-ok
 namespace: pipy
EOF           

經過驗證,50% 的響應會傳回狀态碼

500

HTTP/1.1 500 Internal Server Error
content-length: 0
connection: keep-alive           

總結

故障注入技術作為一種重要的測試方法,在軟體工程中已經得到廣泛的應用。随着雲計算和微服務架構的普及,故障注入在分布式系統和服務網格中的應用也越來越受到重視。結合服務網格技術,故障注入可以做到更加的自動化和智能化,良好相容更多的應用場景。

通過擴充故障注入功能,我們再一次體驗了可擴充服務網絡的靈活性。功能可擴充的服務網格通過更強的可定制性、更好更靈活的擴充性,可以滿足使用者多元的需求、複雜的場景。

引用連結

[1]

Pipy: https://github.com/flomesh-io/pipy

[2]

Chaos Monkey: https://github.com/Netflix/chaosmonkey

[3]

插件擴充功能: https://osm-edge-docs.flomesh.io/docs/guides/operating/plugins/

[4]

故障注入插件: https://raw.githubusercontent.com/flomesh-io/osm-edge-docs/release-v1.3/manifests/samples/plugins/fault-injection.yaml

[5]

PipyJS: https://flomesh.io/pipy/docs/en/reference/pjs

[6]

源碼: https://raw.githubusercontent.com/flomesh-io/osm-edge-docs/release-v1.3/manifests/samples/plugins/fault-injection.yaml

[7]

Kubernetes 标簽選擇器: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/