10個 Istio 流量管理 最常用的例子,你知道幾個?

2023-06-08 09:00:59

10 個 Istio 流量管理 最常用的例子,強烈建議收藏起來,以備不時之需。

為了方便理解,以Istio官方提供的Bookinfo應用範例為例,引出 Istio 流量管理的常用例子。

Bookinfo應用的架構圖如下:

其中,包含四個單獨的微服務:

  • productpage:呼叫 detailsreviews 兩個服務,用來生成頁面。
  • details:包含了書籍的資訊。
  • reviews:包含了書籍相關的評論。它還會呼叫 ratings 微服務。
  • rating:包含了由書籍評價組成的評級資訊。

其中,reviews 服務有 3 個版本:

  • v1 版本不會呼叫 ratings 服務。
  • v2 版本會呼叫 ratings 服務,並使用 1 到 5 個黑色星形圖示來顯示評分資訊。
  • v3 版本會呼叫 ratings 服務,並使用 1 到 5 個紅色星形圖示來顯示評分資訊。

流量轉移

目標1:把reviews 服務的所有流量都路由到v1版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
    - labels:
        version: v3
      name: v3

目標2:把reviews 服務的50%流量轉移到v3版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 50
    - destination:
        host: reviews
        subset: v3
      weight: 50
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
    - labels:
        version: v3
      name: v3

目標3:把reviews 服務的所有流量都路由到v3版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
    - labels:
        version: v3
      name: v3

文章持續更新,微信搜尋「萬貓學社」第一時間閱讀,關注後回覆「電子書」,免費獲取12本Java必讀技術書籍。

基於使用者身份的路由

目標:來自名為 OneMore 的使用者的所有流量都路由到v2版本,其他流量都路由到v1版本。

Istio 對使用者身份沒有任何特殊的內建機制。在應用範例中,productpage服務在所有到 reviews 服務的 HTTP 請求中都增加了一個自定義的 end-user 請求頭,其值為使用者名稱。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: OneMore
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
    - labels:
        version: v3
      name: v3

文章持續更新,微信搜尋「萬貓學社」第一時間閱讀,關注後回覆「電子書」,免費獲取12本Java必讀技術書籍。

注入 HTTP 延遲故障

目標:使用者 OneMore 存取時, ratings 服務注入一個 2 秒的延遲,productpage頁面在大約 2 秒鐘載入完成並且沒有錯誤。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers:
        end-user:
          exact: OneMore
    fault:
      delay:
        percentage:
          value: 100.0
        fixedDelay: 2s
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: ratings
spec:
  host: ratings
  subsets:
    - labels:
        version: v1
      name: v1

文章持續更新,微信搜尋「萬貓學社」第一時間閱讀,關注後回覆「電子書」,免費獲取12本Java必讀技術書籍。

注入 HTTP 中止故障

目標:使用者 OneMore 存取時, ratings 服務注入一個503的中止故障,productpage 頁面能夠立即被載入,同時顯示 「Ratings service is currently unavailable」 這樣的訊息。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
    - ratings
  http:
    - fault:
        abort:
          httpStatus: 503
          percentage:
            value: 100
      match:
        - headers:
            end-user:
              exact: OneMore
      route:
        - destination:
            host: ratings
            subset: v1
    - route:
        - destination:
            host: ratings
            subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: ratings
spec:
  host: ratings
  subsets:
    - labels:
        version: v1
      name: v1

文章持續更新,微信搜尋「萬貓學社」第一時間閱讀,關注後回覆「電子書」,免費獲取12本Java必讀技術書籍。

設定請求超時

首先,使用者 OneMore 存取時, ratings 服務注入一個 2 秒的延遲,productpage頁面在大約 2 秒鐘載入完成並且沒有錯誤。

按照上文注入 HTTP 延遲故障進行操作,不再贅述。

目標:使用者 OneMore 存取時, reviews 服務的請求超時設定為 1 秒,同時顯示 「Sorry, product reviews are currently unavailable for this book.」 這樣的訊息。

kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
    - match:
        - headers:
            end-user:
              exact: OneMore
      route:
        - destination:
            host: reviews
            subset: v2
      timeout: 1s
    - route:
        - destination:
            host: reviews
            subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
    - labels:
        version: v3
      name: v3

在Jaeger可以看到具體的呼叫鏈如下:

文章持續更新,微信搜尋「萬貓學社」第一時間閱讀,關注後回覆「電子書」,免費獲取12本Java必讀技術書籍。

設定請求重試

首先,使用者 OneMore 存取時, ratings 服務注入一個 2 秒的延遲,productpage頁面在大約 2 秒鐘載入完成並且沒有錯誤。

按照上文注入 HTTP 延遲故障進行操作,不再贅述。

目標:使用者 OneMore 存取時, reviews 服務的請求重試次數為2次,重試超時時間為 0.5 秒,同時顯示 「Sorry, product reviews are currently unavailable for this book.」 這樣的錯誤訊息。

kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
    - match:
        - headers:
            end-user:
              exact: OneMore
      route:
        - destination:
            host: reviews
            subset: v2
      retries:
        attempts: 2
        perTryTimeout: 0.5s
    - route:
        - destination:
            host: reviews
            subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
    - labels:
        version: v3
      name: v3

文章持續更新,微信搜尋「萬貓學社」第一時間閱讀,關注後回覆「電子書」,免費獲取12本Java必讀技術書籍。

拒絕目標IP的請求

目標:除了IP為10.201.240.131的使用者端可以存取/api/v1/products/1,其他使用者端拒絕請求。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-by-ip
spec:
  selector:
    matchLabels:
      app: productpage
  action: DENY
  rules:
  - to:
    - operation:
        paths: ["/api/v1/products/1"]
    when:
    - key: remote.ip
      notValues: ["10.201.240.131"]

文章持續更新,微信搜尋「萬貓學社」第一時間閱讀,關注後回覆「電子書」,免費獲取12本Java必讀技術書籍。

熔斷

目標:設定details服務的並行上限為1。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: details
spec:
  host: details
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 1
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1

可以使用 Fortio 進行負載測試,傳送並行數為 2 的連線(-c 2),請求 20 次(-n 20):

kubectl exec fortio-deploy-684b6b47f8-tzsg8 -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 20 -loglevel Warning http://details:9080/details/0

其中,fortio-deploy-684b6b47f8-tzsg8是Fortio的Pod名稱,效果如下:

文章持續更新,微信搜尋「萬貓學社」第一時間閱讀,關注後回覆「電子書」,免費獲取12本Java必讀技術書籍。

流量映象

目標:把流量全部路由到reviews服務的 v2 版本,再把流量全部映象到 v3 版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v2
    mirror:
      host: reviews
      subset: v3
    mirrorPercentage:
      value: 100.0
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
    - labels:
        version: v3
      name: v3

執行如下命令檢視reviews服務 v3 版本的 Envoy 存取紀錄檔:

kubectl logs -l app=reviews,version=v3 -c istio-proxy

可以看到reviews服務 v3 版本被呼叫的紀錄檔:

{
     "authority": "reviews-shadow:9080",
     "bytes_received": 0,
     "bytes_sent": 375,
     "connection_termination_details": null,
     "downstream_local_address": "10.1.1.64:9080",
     "downstream_remote_address": "10.1.1.59:0",
     "duration": 1914,
     "method": "GET",
     "path": "/reviews/0",
     "protocol": "HTTP/1.1",
     "request_id": "b79cefe6-1277-9c39-b398-f94a704840cc",
     "requested_server_name": "outbound_.9080_.v3_.reviews.default.svc.cluster.local",
     "response_code": 200,
     "response_code_details": "via_upstream",
     "response_flags": "-",
     "route_name": "default",
     "start_time": "2022-06-27T07:34:19.129Z",
     "upstream_cluster": "inbound|9080||",
     "upstream_host": "10.1.1.64:9080",
     "upstream_local_address": "127.0.0.6:59837",
     "upstream_service_time": "1913",
     "upstream_transport_failure_reason": null,
     "user_agent": "curl/7.79.1",
     "x_forwarded_for": "10.1.1.59"
}

文章持續更新,微信搜尋「萬貓學社」第一時間閱讀,關注後回覆「電子書」,免費獲取12本Java必讀技術書籍。

Ingress的路由

目標:請求頭app-iddetails的所有流量都路由到details服務中。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
    - '*'
  gateways:
    - bookinfo-gateway
  http:
    - match:
        - uri:
            exact: /productpage
        - uri:
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
      route:
        - destination:
            host: productpage
            port:
              number: 9080
    - match:
        - headers:
            app-id:
              exact: details
      route:
        - destination:
            host: details
            port:
              number: 9080

使用curl命令驗證一下:

curl -H "app-id: details" -v http://127.0.0.1/details/2

返回結果如下:

* Trying 127.0.0.1:80...
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /details/2 HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.79.1
> Accept: */*
> app-id: details
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: application/json
< server: istio-envoy
< date: Tue, 28 Jun 2022 07:14:40 GMT
< content-length: 178
< x-envoy-upstream-service-time: 4
<

{"id":2,"author":"William Shakespeare","year":1595,"type":"paperback","pages":200,"publisher":"PublisherA","language":"English","ISBN-10":"1234567890","ISBN-13":"123-1234567890"}

* Connection #0 to host 127.0.0.1 left intact

返回結果可以看出,存取的是details服務。

最後,感謝你這麼帥,還給我點贊

微信公眾號:萬貓學社

微信掃描二維條碼

關注後回覆「電子書」

獲取12本Java必讀技術書籍