天天看點

OpenShift 4 之Istio-Tutorial (6) 服務恢複能力(重試、逾時、斷路器)準備環境重試(Fail Try)逾時(Timeout)斷路器(Circuit Breaker)

《OpenShift 4.x HOL教程彙總》

說明:本文已經在OpenShift 4.6環境中驗證

文章目錄

  • 準備環境
  • 重試(Fail Try)
  • 逾時(Timeout)
  • 斷路器(Circuit Breaker)

準備環境

在開始操作前,我們先把以前針對Recommendation定義的DestinationRule和VirtualService删除掉,然後把運作recommendation-v2微服務的Pod設為1個。

$ oc delete -f istiofiles/destination-rule-recommendation_lb_policy_app.yml -n tutorial
$ oc get istio-io -n tutorial
NAME                                                  GATEWAYS               HOSTS   AGE
virtualservice.networking.istio.io/customer-gateway   ["customer-gateway"]   ["*"]   146m
 
NAME                                           AGE
gateway.networking.istio.io/customer-gateway   146m
 
$ oc scale deployment recommendation-v2 --replicas=1 -n tutorial
$ oc get pod -n tutorial
customer-77dc47d7f8-szhd5            2/2     Running   4          6h
preference-v1-55476494cf-xm4dq       2/2     Running   0          3h
recommendation-v1-67976848-4l4s7     2/2     Running   0          3h
recommendation-v2-599867df6c-5ccdx   2/2     Running   0          19m
           

重試(Fail Try)

當通過Service通路一個微服務的Pod出現錯誤(例如503)後,Istio可以自動(預設配置,可以修改)嘗試通路其它運作微服務的Pod。

  1. 在一個視窗中運作以下指令,可以看到此時recommendation v1和recommendation v2是交替被調用的。
$ export INGRESS_GATEWAY=$(oc get route istio-ingressgateway -n istio-system -o 'jsonpath={.spec.host}')
$ ./scripts/run.sh $INGRESS_GATEWAY/customer
customer => preference => recommendation v2 from '3cbba7a9cde5': 50
customer => preference => recommendation v1 from '67976848-4l4s7': 1451
customer => preference => recommendation v2 from '3cbba7a9cde5': 51
customer => preference => recommendation v1 from '67976848-4l4s7': 1452
           

此時在Kiali中可以看到recommendation v1和recommendation v2各有50%的調用機會。

OpenShift 4 之Istio-Tutorial (6) 服務恢複能力(重試、逾時、斷路器)準備環境重試(Fail Try)逾時(Timeout)斷路器(Circuit Breaker)

2. 在另一個視窗執行以下指令進入運作recommendation v2微服務的容器,以便能模拟recommendation v2微服務運作不正常。

$ oc exec -it $(oc get pods | grep recommendation-v2 | awk '{ print $1 }') -c recommendation -- /bin/bash
           
  1. 在運作recommendation v2微服務的容器内部執行以下指令,調用微服務接口模拟運作異常(傳回503),然後退出容器。
bash-4.4$ curl localhost:8080/misbehave
Following requests to / will return a 503
bash-4.4$ exit
exit
           
  1. 在第一個視窗确認隻調用recommendation-v1微服務了。
$ export INGRESS_GATEWAY=$(oc get route istio-ingressgateway -n istio-system -o 'jsonpath={.spec.host}')
$ ./scripts/run.sh $INGRESS_GATEWAY/customer
customer => preference => recommendation v1 from '67976848-4l4s7': 1444
customer => preference => recommendation v1 from '67976848-4l4s7': 1445
customer => preference => recommendation v1 from '67976848-4l4s7': 1446
           

此時在Kiali中可以看到recommendation v1有100%的調用機會。選中recommandation的方框,然後将滑鼠放在右側紅色App:recommendation上,此時可以看到提示:雖然2個recommandation的Pod狀态都正常,但是有一部分Inbound請求出錯。

OpenShift 4 之Istio-Tutorial (6) 服務恢複能力(重試、逾時、斷路器)準備環境重試(Fail Try)逾時(Timeout)斷路器(Circuit Breaker)

選中recommandation v2的小方框,然後将滑鼠放在右側紅色App:recommendation上,此時可以看到提示:100%的Inbound請求出錯。

OpenShift 4 之Istio-Tutorial (6) 服務恢複能力(重試、逾時、斷路器)準備環境重試(Fail Try)逾時(Timeout)斷路器(Circuit Breaker)

選中preference的方框,然後将滑鼠放在右側紅色App:preference上,此時可以看到提示:有一部分Outbound請求出錯。

OpenShift 4 之Istio-Tutorial (6) 服務恢複能力(重試、逾時、斷路器)準備環境重試(Fail Try)逾時(Timeout)斷路器(Circuit Breaker)

5. 再恢複recommendation v2微服務正常運作,此時第一個視窗又可以通路到recommendation v2微服務了。

$ oc exec -it $(oc get pods | grep recommendation-v2 | awk '{ print $1 }') -c recommendation -- /bin/bash
bash-4.4$ curl localhost:8080/behave
Following requests to / will return a 503
bash-4.4$ exit
exit
           
  1. 檔案istiofiles/virtual-service-recommendation-v2_retry.yml修改了對recommendation的Servic通路的預設重試配置。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: recommendation
spec:
  hosts:
  - recommendation
  http:
  - route:
    - destination:
        host: recommendation
    retries:
      attempts: 3
      perTryTimeout: 2s
           

執行指令修改重試的配置。

$ oc apply -f istiofiles/virtual-service-recommendation-v2_retry.yml
           

逾時(Timeout)

為通路微服務設定逾時時間,當超過Timeout時間後自動結束通路。

  1. 首先我們根據本文開始說明,重新準備環境,確定recommendation v1和recommendation v2都可以正常通路。
  2. 執行以下指令,删掉正常的recommendation v2的Deployment,然後部署一個逾時版的recommendation v2。
$ oc delete -f recommendation/kubernetes/Deployment-v2.yml
$ oc apply -f recommendation/kubernetes/Deployment-v2-timeout.yml
           
  1. 執行腳本連續通路customer,可以發現recommendation v2傳回結果比較慢。
$ export INGRESS_GATEWAY=$(oc get route istio-ingressgateway -n istio-system -o 'jsonpath={.spec.host}')
$ ./scripts/run.sh $INGRESS_GATEWAY/customer
customer => preference => recommendation v1 from '67976848-4l4s7': 3078
customer => preference => recommendation v2 from '379afb614fb1': 1
customer => preference => recommendation v1 from '67976848-4l4s7': 3079
customer => preference => recommendation v2 from '379afb614fb1': 2
CTL+C
           
  1. 為recommendation服務建立一個VirtualService。檔案istiofiles/virtual-service-recommendation-timeout.yml内容如下,其中為通路recommendation定義了timeout為1s。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: recommendation
spec:
  hosts:
  - recommendation
  http:
  - route:
    - destination:
        host: recommendation
    timeout: 1.000s
           

執行指令,建立VirtualService

$ oc apply -f istiofiles/virtual-service-recommendation-timeout.yml -n tutorial
           
  1. 執行腳本持續通路customer,可以看到由于recommendation v2逾時,是以傳回的隻有recommendation v1。
$ export INGRESS_GATEWAY=$(oc get route istio-ingressgateway -n istio-system -o 'jsonpath={.spec.host}')
$ ./scripts/run.sh $INGRESS_GATEWAY/customer
customer => preference => recommendation v1 from '67976848-4l4s7': 3084
customer => preference => recommendation v1 from '67976848-4l4s7': 3085
customer => preference => recommendation v1 from '67976848-4l4s7': 3086
           
  1. 在Kiali控制台中,選中recommendation的紅色方框,滑鼠點到右上方App:recommendation後,可以看到50%的Inbound出現錯誤。由于此步驟沒有配置“retry”
    OpenShift 4 之Istio-Tutorial (6) 服務恢複能力(重試、逾時、斷路器)準備環境重試(Fail Try)逾時(Timeout)斷路器(Circuit Breaker)
  2. 最後恢複環境,删除逾時的recommendation v2部署和recommendation的VirtualService,并重新部署正常的recommendation v2。
$ oc delete -f istiofiles/virtual-service-recommendation-timeout.yml -n tutorial
$ oc delete -f recommendation/kubernetes/Deployment-v2-timeout.yml
$ oc apply -f recommendation/kubernetes/Deployment-v2.yml
           

斷路器(Circuit Breaker)

當一個被調用服務出現錯誤後,下一次Istio還會将請求發給出錯的服務。回顧本文的“重試(Fail Try)”中的第二章截圖,通路recommendation v2的失敗率是33%。這是由于Istio會輪訓将請求發給recommendation v2和recommendation v2,當發現recommendation v2出現錯誤後再嘗試發給recommendation v1。我們可以在DestinationRule上設定斷路器(Circuit Breaker),以便在通路某個服務失敗後暫時斷開對這個服務執行個體的通路。Istio會在指定的時間後嘗試将請求再次發給recommendation v2,如果此時失效的recommendation v2已經恢複正常,Istio會停止作用于recommendation v2的斷路器。

  1. 根據本文“準備環境”的說明,删除所有recommendation微服務相關的VirtualService、DestinationRule。此時請求可以被輪訓發到recommendation v1和recommendation v2上。
  2. 進入運作recommendation v2的容器裡,執行指令把狀态設為disbehave狀态,然後退出。
$ oc exec -it $(oc get pods -n tutorial | grep recommendation-v2 | awk '{ print $1 }') -c recommendation -- /bin/bash
bash-4.4$ curl localhost:8080/misbehave
Following requests to / will return a 503
bash-4.4$ exit
exit
           
  1. 執行指令,連續通路customer。此時從調用用戶端看到的是recommendation v1響應處理的請求。
$ export INGRESS_GATEWAY=$(oc get route istio-ingressgateway -n istio-system -o 'jsonpath={.spec.host}')
$ ./scripts/run.sh $INGRESS_GATEWAY/customer
customer => preference => recommendation v1 from '67976848-4l4s7': 3492
customer => preference => recommendation v1 from '67976848-4l4s7': 3493
customer => preference => recommendation v1 from '67976848-4l4s7': 3494
customer => preference => recommendation v1 from '67976848-4l4s7': 3495
...
           
  1. 在另一個視窗執行以下指令,檢視運作recommendation v2的容器日志。我們可以發現recommendation v2微服務還繼續不斷有日志輸出,說明有請求還是不斷發給它。因為此時我們還沒有為recommendation v2設定斷路器。
$ oc logs -f $(oc get pods | grep recommendation-v2 | awk '{ print $1 }') -c recommendation
recommendation request from 3cbba7a9cde5: 11
recommendation request from 3cbba7a9cde5: 12
recommendation request from 3cbba7a9cde5: 13
...
           
  1. 在第三個視窗執行指令,為recommendation服務建立帶有斷路器的DestinationRule。檔案istiofiles/destination-rule-recommendation_cb_policy_version_v2.yml定義了DestinationRule:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: recommendation
spec:
  host: recommendation
  subsets:
  - labels:
      version: v1
    name: version-v1
  - labels:
      version: v2
    name: version-v2
  trafficPolicy:
    connectionPool:
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
      tcp:
        maxConnections: 1
    outlierDetection:
      baseEjectionTime: 3m
      consecutiveErrors: 1
      interval: 1s
      maxEjectionPercent: 100
           

執行指令為recommendation服務建立DestinationRule。

$ oc apply -f istiofiles/destination-rule-recommendation_cb_policy_version_v2.yml -n tutorial
           
  1. 此時可從從視窗1看到還不斷發送對customer的請求,但是視窗2已經不再有日志輸出,說明請求沒有被發到recommendation v2微服務上,這是由于斷路器暫時不再将請求發給出問題的recommendation v2微服務。
  2. 再次進入運作recommendation v2的容器裡,執行指令把狀态設為behave狀态,然後退出。這樣recommendation v2微服務又恢複了正常通路。
$ oc exec -it -n tutorial $(oc get pods -n tutorial | grep recommendation-v2 | awk '{ print $1 }') -c recommendation -- /bin/bash
bash-4.4$ curl localhost:8080/behave
Following requests to / will return a 503
bash-4.4$ exit
exit
           
  1. 繼續觀察視窗1和視窗2的輸出,需要等3分鐘左右。從以下視窗1的日志可以看到請求再次被轉發到recommendation v2,而視窗2也會有新的日志輸出,說明recommendation v2已經恢複接收到轉發的請求。
customer => preference => recommendation v1 from '67976848-4l4s7': 4522
customer => preference => recommendation v2 from '3cbba7a9cde5': 20
customer => preference => recommendation v1 from '67976848-4l4s7': 4523
customer => preference => recommendation v2 from '3cbba7a9cde5': 21
customer => preference => recommendation v1 from '67976848-4l4s7': 4524
customer => preference => recommendation v2 from '3cbba7a9cde5': 22
customer => preference => recommendation v1 from '67976848-4l4s7': 4525
customer => preference => recommendation v2 from '3cbba7a9cde5': 23
           

繼續閱讀