iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 22
1
DevOps

Kubernetes and Istio 三十天系列 第 22

[Day22] Istio Example BookInfo - Traffic Management II

Istio Example BookInfo Architecture

BookInfo-Architecture

前言

Istio Service Mesh可以在請求途中會加入Circuit Breaking
、Request Timeouts等等策略。

Fault injection

重新設定回原先的Bookinfo

kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml

Injecting an HTTP delay fault

Install

kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      delay:
        percentage:
          value: 100.0
        fixedDelay: 7s
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1

這邊是設定使用者json訪問網頁的時候會固定delay 7s

Testing the delay configuration

在瀏覽器中打開BookInfo的URL: http://localhost:31380/productpage

這裏登錄用戶名為 jason ,密碼隨便輸入即可
因為我們在ratings Service設定了delay 7s,所以會出現下列錯誤

Error fetching product reviews!
Sorry, product reviews are currently unavailable for this book.

Understanding what happened

發現了一個bug。在微服務中有hard-coded Timeout,導致reviews服務失敗。

在productpage和reviews服務之間Timeout設定6s,reviews和 ratings服務之間的hard-coded Timeout為10s。由於我們設定了7s delay,因此訪問/productpage會出現Timeout錯誤。

這類型的錯誤可能發生在很多情境下,其中獨立地開發不同的微服務。Istio的Fault injection可幫助您判斷此類異常錯誤,而不會影響最終結果。

這邊我們僅設定限制用戶 “jason” 會出現Timeout的錯誤狀況。如果您以任何其他用戶身份登入,則不會遇到任何Delay Timeout錯誤。


Injecting an HTTP abort fault

測試微服務的另一種方法是引入HTTP abort fault。在ratings Service中引入HTTP abort,測試用戶為jason 。

在這個案例中,我們希望網頁能夠立即加載,同時顯示Ratings service is currently unavailable這樣的消息。

#install
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
  ...
spec:
  hosts:
  - ratings
  http:
  #設定http abort,ratings Service所有流量都回500 Error
  - fault:
      abort:
        httpStatus: 500
        percent: 100
    match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1

Testing the abort configuration

在瀏覽器中打開BookInfo的URL: http://localhost:31380/productpage

這裏登錄用戶名為 jason ,密碼隨便輸入即可

能立即看到Ratings service is currently unavailable畫面。

因為我們只設定jason這個帳號,所以除了jason外的用戶都會看到網頁上看到評級星標的評論成功顯示。

Requests Timeout

kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v2
EOF

#設定ratings Service delay 2s 

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - fault:
      delay:
        percent: 100
        fixedDelay: 2s
    route:
    - destination:
        host: ratings
        subset: v1
EOF

Setting Request timeout

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v2
    timeout: 0.5s
EOF

因為前面已經設定ratings delay 2s,因此新增的設定生效reviews的畫面會不到。

Understanding what happened

在reviews Service的Request加入了0.5s的Timeout,預設的Timeout 15秒鐘被覆蓋掉了。因此網頁重新整理時,reviews Service會調用 ratings Service,ratings Service中有設定2s Timeout,這樣就讓 reviews Service要花費超過0.5s的時間來調用 ratings Service,觸發了我們加入的Timeout Rule。

這樣就會看到 Bookinfo 上沒有出現 reviews Service的內容,取而代之的是錯誤信息:Sorry, product reviews are currently unavailable for this book,出現這一錯誤的原因就是因為來自 reviews Service的Timeout。

除了像上面在VirtualService中進行Timeout Setting之外,還可以在istio-ingressgateway設置,在istio-ingressgateway中加入x-envoy-upstream-rq-timeout-ms Header。在這個 Header 中的逾時單位是毫秒而不是秒。

Circuit Breaking

Install Service Side

kubectl apply -f samples/httpbin/httpbin.yaml

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: httpbin
spec:
  host: httpbin
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 1
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
    outlierDetection:
      consecutiveErrors: 1
      interval: 1s
      baseEjectionTime: 3m
      maxEjectionPercent: 100
EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: httpbin
  ...
spec:
  host: httpbin
  trafficPolicy:
    connectionPool:
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
      tcp:
        maxConnections: 1
    outlierDetection:
      baseEjectionTime: 180.000s
      consecutiveErrors: 1
      interval: 1.000s
      maxEjectionPercent: 100

DestinationRule除了可以設定Circuit Breaking,還可以設定connectionPool以及loadBalancer在trafficPolicy之下,

現在我們已經設置了 httpbin Service,接下來需要創建一個Client,用來向httpbin Service發送請求,觀察是否會觸發Circuit Breaking。這裏要使用一個簡單的負載測試客戶端,名字叫 fortio。這個客戶端可以控制連接數量、並發數以及發送 HTTP 請求的延遲。

Install Client Side

kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml

FORTIO_POD=$(kubectl get pod | grep fortio | awk '{ print $1 }')

kubectl exec -it $FORTIO_POD  -c fortio /usr/local/bin/fortio -- load -curl  http://httpbin:8000/get

Tripping the circuit breaker

我們在上面的Circuit Breaking有設定maxConnections: 1 以及 http1MaxPendingRequests: 1這兩項規則

接下來嘗試一下,一次兩個Thread(-c 2),發送20次請求(-n 20)

kubectl exec -it $FORTIO_POD  -c fortio /usr/local/bin/fortio -- load -c 2 -qps 0 -n 20 -loglevel Warning http://httpbin:8000/get

稍微修改一下,一次三個Thread(-c 3),發送30次請求(-n 30)

kubectl exec -it $FORTIO_POD  -c fortio /usr/bin/fortio -- load -c 3 -qps 0 -n 30 -loglevel Warning http://httpbin:8000/get

查詢 istio-proxy 的狀態,獲取更多相關信息

kubectl exec $FORTIO_POD -c istio-proxy -- pilot-agent request GET stats | grep httpbin | grep pending

cluster.outbound|80||httpbin.springistio.svc.cluster.local.upstream_rq_pending_active: 0
cluster.outbound|80||httpbin.springistio.svc.cluster.local.upstream_rq_pending_failure_eject: 0
cluster.outbound|80||httpbin.springistio.svc.cluster.local.upstream_rq_pending_overflow: 12
cluster.outbound|80||httpbin.springistio.svc.cluster.local.upstream_rq_pending_total: 39

upstream_rq_pending_overflow是12,說明有12次請求被視為熔斷。

結語

今天主要講解比較進階的幾個常見應用,明天會再講一些更特別的應用情境

圖片來源

Istio BookInfo


上一篇
[Day21] Istio Example BookInfo - Traffic Management I
下一篇
[Day23] Istio Example BookInfo - Traffic Management III
系列文
Kubernetes and Istio 三十天30

尚未有邦友留言

立即登入留言