5個 Istio 訪問外部服務流量控制最常用的例子,你知道幾個?

5 個 Istio 訪問外部服務的流量控制常用例子,強烈建議收藏起來,以備不時之需。

環境準備

部署 sleep 服務,作爲發送請求的測試源:

kubectl apply -f samples/sleep/sleep.yaml

在 Istio 外部,使用 Nginx 搭建 duckling 服務的v1和v2兩個版本,訪問時顯示簡單的文本:

> curl -s http://192.168.1.118/
This is the v1 version of duckling.
> curl -s http://192.168.1.119/
This is the v2 version of duckling.

訪問外部服務

執行如下命名訪問外部服務 httpbin.org :

export SLEEP_POD=$(kubectl get pods -l app=sleep -o 'jsonpath={.items[0].metadata.name}')
kubectl exec "$SLEEP_POD" -c sleep -- curl -s http://httpbin.org/headers

返回結果如下:

{
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.81.0-DEV", 
    "X-Amzn-Trace-Id": "Root=1-62bbfa10-3237e3b9662c65ae005148ab", 
    "X-B3-Sampled": "0", 
    "X-B3-Spanid": "9e650093bf7ae862", 
    "X-B3-Traceid": "1da46d7fafa5d71c9e650093bf7ae862", 
    "X-Envoy-Attempt-Count": "1", 
    "X-Envoy-Peer-Metadata": "......", 
    "X-Envoy-Peer-Metadata-Id": "sidecar~......"
  }
}

此時的方法,沒有通過Service Entry,沒有 Istio 的流量監控和控制特性。創建 Service Entry :

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: httpbin-ext
spec:
  hosts:
  - httpbin.org
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: DNS
  location: MESH_EXTERNAL
EOF

再此次訪問,返回結果如下:

{
  "headers": {
    "Accept": "*/*", 
    "Host": "httpbin.org", 
    "User-Agent": "curl/7.81.0-DEV", 
    "X-Amzn-Trace-Id": "Root=1-62bbfbd6-254b05344b3cde2c0c41b3b8", 
    "X-B3-Sampled": "0", 
    "X-B3-Spanid": "307c0b106c8b262e", 
    "X-B3-Traceid": "f684a50776c088ac307c0b106c8b262e", 
    "X-Envoy-Attempt-Count": "1", 
    "X-Envoy-Decorator-Operation": "httpbin.org:80/*", 
    "X-Envoy-Peer-Metadata": "......", 
    "X-Envoy-Peer-Metadata-Id": "sidecar~......"
  }
}

可以發現由 Istio 邊車添加的請求頭:X-Envoy-Decorator-Operation

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

設置請求超時

向外部服務 httpbin.org 的 /delay 發出請求:

export SLEEP_POD=$(kubectl get pods -l app=sleep -o 'jsonpath={.items[0].metadata.name}')
kubectl exec "$SLEEP_POD" -c sleep -- time curl -o /dev/null -sS -w "%{http_code}\n" http://httpbin.org/delay/5

返回結果如下:

200
real    0m 5.69s
user    0m 0.00s
sys     0m 0.00s

請求大約在 5 秒後返回 200 (OK)。

創建虛擬服務,訪問外部服務 httpbin.org 時, 請求超時設置爲 3 秒:

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin-ext
spec:
  hosts:
    - httpbin.org
  http:
  - timeout: 3s
    route:
      - destination:
          host: httpbin.org
        weight: 100
EOF

再此次訪問,返回結果如下:

504
real    0m 3.01s
user    0m 0.00s
sys     0m 0.00s

可以看出,在 3 秒後出現了 504 (Gateway Timeout)。 Istio 在 3 秒後切斷了響應時間爲 5 秒的 httpbin.org 服務。

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

注入 HTTP 延遲故障

向外部服務 httpbin.org 的 /get 發出請求:

export SLEEP_POD=$(kubectl get pods  -l app=sleep -o 'jsonpath={.items[0].metadata.name}')
kubectl exec "$SLEEP_POD" -c sleep -- time curl -o /dev/null -sS -w "%{http_code}\n" http://httpbin.org/get

返回結果如下:

200
real  0m 0.45s
user  0m 0.00s
sys 0m 0.00s

請求不到 1 秒就返回 200 (OK)。

創建虛擬服務,訪問外部服務 httpbin.org 時, 注入一個 3 秒的延遲:

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin-ext
spec:
  hosts:
    - httpbin.org
  http:
    - fault:
        delay:
          fixedDelay: 3s
          percentage:
            value: 100
      route:
        - destination:
            host: httpbin.org
EOF

再此次訪問 httpbin.org 的 /get ,返回結果如下:

200
real  0m 3.43s
user  0m 0.00s
sys 0m 0.00s

可以看出,在 3 秒後出現了 200 (OK)。

流量轉移

訪問duckling服務時,所有流量都路由到v1版本,具體配置如下:

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: duckling
spec:
  hosts:
  - duckling.com
  ports:
  - number: 80
    name: http
    protocol: HTTP
  location: MESH_EXTERNAL
  resolution: STATIC
  endpoints:
  - address: 172.24.29.118
    ports:
      http: 80
    labels:
      version: v1
  - address: 172.24.29.119
    ports:
      http: 80
    labels:
      version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: duckling
spec:
  hosts:
  - duckling.com
  http:
  - route:
    - destination:
        host: duckling.com
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: duckling
spec:
  host: duckling.com
  subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
EOF

執行如下命名訪問外部服務 duckling.com :

export SLEEP_POD=$(kubectl get pods -l app=sleep -o 'jsonpath={.items[0].metadata.name}')
kubectl exec "$SLEEP_POD" -c sleep -- curl -s http://duckling.com/

多次訪問後,返回結果一直是:This is the v1 version of duckling.

訪問duckling服務時,把50%流量轉移到v2版本,具體配置如下:

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

多次訪問外部服務 duckling.com ,有時返回This is the v1 version of duckling.,有時返回This is the v2 version of duckling.

訪問duckling服務時,所有流量都路由到v2版本,具體配置如下:

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

多次訪問外部服務 duckling.com ,一直返回This is the v2 version of duckling.

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

基於請求頭的路由

請求頭end-user爲OneMore的所有流量都路由到v2版本,其他流量都路由到v1版本,具體配置如下:

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: duckling
spec:
  hosts:
  - duckling.com
  ports:
  - number: 80
    name: http
    protocol: HTTP
  location: MESH_EXTERNAL
  resolution: STATIC
  endpoints:
  - address: 172.24.29.118
    ports:
      http: 80
    labels:
      version: v1
  - address: 172.24.29.119
    ports:
      http: 80
    labels:
      version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: duckling
spec:
  hosts:
  - duckling.com
  http:
  - match:
    - headers:
        end-user:
          exact: OneMore
    route:
    - destination:
        host: duckling.com
        subset: v2
  - route:
    - destination:
        host: duckling.com
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: duckling
spec:
  host: duckling.com
  subsets:
    - labels:
        version: v1
      name: v1
    - labels:
        version: v2
      name: v2
EOF

執行如下命名訪問外部服務 duckling.com :

export SLEEP_POD=$(kubectl get pods -l app=sleep -o 'jsonpath={.items[0].metadata.name}')
kubectl exec "$SLEEP_POD" -c sleep -- curl -s http://duckling.com/

多次訪問的返回結果一直是:This is the v1 version of duckling.

設置請求頭end-user爲OneMore,訪問外部服務 duckling.com :

kubectl exec "$SLEEP_POD" -c sleep -- curl -H "end-user:OneMore" -s http://duckling.com/

多次訪問的返回結果一直是:This is the v2 version of duckling.

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

微信公衆號:萬貓學社

微信掃描二維碼

關注後回覆「電子書」

獲取12本Java必讀技術書籍

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章