地理位置故障轉移

請依照本指南設定您的網格以進行地區故障轉移。

在繼續操作之前,請務必完成開始之前下的步驟。

在此任務中,您將使用 region1.zone1 中的 curl pod 作為對 HelloWorld 服務發出請求的來源。然後,您將觸發故障,導致以下列順序在地區之間進行故障轉移

Locality failover sequence
地區故障轉移順序

在內部,Envoy 優先級用於控制故障轉移。對於來自 curl pod(在 region1 zone1 中)的流量,這些優先級將按如下方式分配

優先級地區詳細資訊
0region1.zone1地區、區域和子區域都匹配。
1由於此任務未使用子區域,因此沒有針對不同子區域的匹配項。
2region1.zone2同一地區內的不同區域。
3region2.zone3不匹配,但已定義 region1->region2 的故障轉移。
4region3.zone4不匹配,且沒有為 region1->region3 定義故障轉移。

設定地理位置故障轉移

套用 DestinationRule 來設定以下內容

  • 針對 HelloWorld 服務的離群值偵測。為了使故障轉移正常運作,這是必要的。特別是,它設定 sidecar 代理,以了解服務的端點何時不健康,最終觸發故障轉移到下一個地區。

  • 地區之間的故障轉移原則。這可確保超出地區邊界的故障轉移將以可預測的方式運作。

  • 強制每個 HTTP 請求都使用新連線的連線池原則。此任務利用 Envoy 的 drain 函數來強制故障轉移到下一個地區。一旦 drain,Envoy 將拒絕新的連線請求。由於每個請求都使用一個新連線,這將導致在 drain 後立即進行故障轉移。此設定僅用於示範目的。

$ kubectl --context="${CTX_PRIMARY}" apply -n sample -f - <<EOF
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: helloworld
spec:
  host: helloworld.sample.svc.cluster.local
  trafficPolicy:
    connectionPool:
      http:
        maxRequestsPerConnection: 1
    loadBalancer:
      simple: ROUND_ROBIN
      localityLbSetting:
        enabled: true
        failover:
          - from: region1
            to: region2
    outlierDetection:
      consecutive5xxErrors: 1
      interval: 1s
      baseEjectionTime: 1m
EOF

驗證流量是否停留在 region1.zone1

curl pod 呼叫 HelloWorld 服務

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region1.zone1, instance: helloworld-region1.zone1-86f77cd7b-cpxhv

驗證回應中的 version 是否為 region1.zone1

重複執行幾次,並驗證回應是否始終相同。

故障轉移至 region1.zone2

接下來,觸發到 region1.zone2 的故障轉移。為此,您需要排空 Envoy sidecar 代理,適用於 region1.zone1 中的 HelloWorld

$ kubectl --context="${CTX_R1_Z1}" exec \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l app=helloworld \
  -l version=region1.zone1 -o jsonpath='{.items[0].metadata.name}')" \
  -n sample -c istio-proxy -- curl -sSL -X POST 127.0.0.1:15000/drain_listeners

curl pod 呼叫 HelloWorld 服務

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region1.zone2, instance: helloworld-region1.zone2-86f77cd7b-cpxhv

第一次呼叫將失敗,這會觸發故障轉移。重複執行命令幾次,並驗證回應中的 version 是否始終為 region1.zone2

故障轉移至 region2.zone3

現在,觸發到 region2.zone3 的故障轉移。如同您之前所做的那樣,將 region1.zone2 中的 HelloWorld 設定為在呼叫時失敗

$ kubectl --context="${CTX_R1_Z2}" exec \
  "$(kubectl get pod --context="${CTX_R1_Z2}" -n sample -l app=helloworld \
  -l version=region1.zone2 -o jsonpath='{.items[0].metadata.name}')" \
  -n sample -c istio-proxy -- curl -sSL -X POST 127.0.0.1:15000/drain_listeners

curl pod 呼叫 HelloWorld 服務

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region2.zone3, instance: helloworld-region2.zone3-86f77cd7b-cpxhv

第一次呼叫將失敗,這會觸發故障轉移。重複執行命令幾次,並驗證回應中的 version 是否始終為 region2.zone3

故障轉移至 region3.zone4

現在,觸發到 region3.zone4 的故障轉移。如同您之前所做的那樣,將 region2.zone3 中的 HelloWorld 設定為在呼叫時失敗

$ kubectl --context="${CTX_R2_Z3}" exec \
  "$(kubectl get pod --context="${CTX_R2_Z3}" -n sample -l app=helloworld \
  -l version=region2.zone3 -o jsonpath='{.items[0].metadata.name}')" \
  -n sample -c istio-proxy -- curl -sSL -X POST 127.0.0.1:15000/drain_listeners

curl pod 呼叫 HelloWorld 服務

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region3.zone4, instance: helloworld-region3.zone4-86f77cd7b-cpxhv

第一次呼叫將失敗,這會觸發故障轉移。重複執行命令幾次,並驗證回應中的 version 是否始終為 region3.zone4

恭喜!您已成功設定地區故障轉移!

下一步

清除此任務中的資源和檔案。

此資訊是否對您有幫助?
您是否有任何改進建議?

感謝您的回饋!