1. 程式人生 > >Istio 在阿里雲容器服務的部署及流量治理實踐

Istio 在阿里雲容器服務的部署及流量治理實踐

目標

  • 在阿里雲容器服務 Kubernetes 叢集上部署 Istio 服務網格
  • 實踐灰度釋出、故障注入、熔斷等 Istio 流量管理特性

準備工作

  1. 安裝和設定 kubectl 客戶端,請參考不同的作業系統,如果已經安裝請忽略:
  • macOS
curl -LO https://kubectl.oss-cn-hangzhou.aliyuncs.com/macos/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
kubectl --help
  • Linux
curl -LO https://kubectl.oss-cn-hangzhou.aliyuncs.com/linux/kubectl
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
kubectl --help
  • Windows

把 https://kubectl.oss-cn-hangzhou.aliyuncs.com/windows/kubectl.exe 放到系統PATH路徑下

kubectl --help

配置 kubectl 連線 Kubernetes 叢集的配置,可參考文件 通過kubectl連線Kubernetes叢集

實驗步驟

部署Istio

  1. 登入容器服務控制檯,在叢集列表中選擇一個叢集,開啟更多 - 部署 Istio
  2. 保持預設配置,點選"部署 Istio"

  1. 等待完成後,Istio 已經成功部署在 Kubernetes 叢集中
  2. 使用 kiali 檢視服務網格視覺化
kubectl port-forward -n istio-system "$(kubectl get -n istio-system pod --selector=app=kiali -o jsonpath='{.items..metadata.name}')" 20001

在本地瀏覽器中訪問 http://localhost:20001 ,使用預設賬戶 admin/admin 登入

灰度釋出

  1. 建立名稱空間並開啟 Sidecar 自動注入:單擊左側導航欄中的叢集 > 名稱空間,進入命令空間頁面,建立一個名稱為 demo
     的名稱空間,併為其新增一個 istio-injection:enabled 的標籤
  2. 單擊左側導航欄中服務網格 > 虛擬服務,進入虛擬服務(Virtual Service)頁面,點選建立,建立一個簡單的示例應用,指定應用名稱為istio-app,指定應用版本為v1,選擇剛剛建立的名稱空間 demo
  3. 配置應用容器,使用如下映象:registry.cn-beijing.aliyuncs.com/test-node/node-server:v1
  4. 配置服務,服務名稱為istio-app-svc,型別為虛擬叢集 IP ,服務埠容器埠均為8080
  5. 提交應用配置,將會自動建立 Deployment、Service、DestinationRule、VirtualService
  6. 單擊導航欄中的應用 > 容器組,確認所有的 Pod 都已經正確的定義和啟動
  7. 建立服務客戶端測試應用
kubectl apply -n demo -f - <<EOF
apiVersion: v1
kind: Service
metadata:
  name: sleep
  labels:
    app: sleep
spec:
  ports:
  - port: 80
    name: http
  selector:
    app: sleep
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: sleep
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: sleep
    spec:
      containers:
      - name: sleep
        image: pstauffer/curl
        command: ["/bin/sleep", "3650d"]
        imagePullPolicy: IfNotPresent
EOF
  1. 在測試應用的 Pod 中訪問 Istio 應用:登入到 sleep 應用的 Pod 中
kubectl exec -it -n demo "$(kubectl get -n demo pod --selector=app=sleep -o jsonpath='{.items..metadata.name}')" sh

執行如下命令呼叫之前部署的 Istio 應用:

for i in `seq 1000`
do
curl http://istio-app-svc.demo:8080;
echo '';
sleep 1;
done;

可以看到返回的資訊:

Hello from v1
Hello from v1
Hello from v1
  1. 單擊左側導航欄中服務網格 > 虛擬服務,進入虛擬服務(Virtual Service)頁面,找到istio-app-svc服務,點選管理,在版本管理中,點選增加灰度版本,新的版本指定為v2

在容器配置中使用以下映象:

registry.cn-beijing.aliyuncs.com/test-node/node-server:v2

在灰度策略中選擇基於流量比例釋出,流量比例 50%

  1. 提交灰度釋出後,檢視 sleep 應用的呼叫結果,可以看到,v1v2版本的返回結果
Hello from v1
Hello from v2
Hello from v1
Hello from v1
Hello from v2
Hello from v1
  1. 在 kiali 中檢視,可以確認,呼叫被分發到兩個版本中

故障注入

  1. 目前應用工作正常,我們為 istio-app-svc 注入故障,以測試整個應用的彈性。在 istio-app-svc 的管理介面中,開啟故障注入策略,選擇注入中斷故障,百分比 50%,狀態碼 503

  1. 提交後,繼續檢視 sleep 應用的呼叫結果,即可看到 istio-app-svc 服務約有 50% 的概率無法訪問,輸出fault filter abort
Hello from v1
Hello from v1
Hello from v1
fault filter abort
fault filter abort
fault filter abort
Hello from v1
Hello from v2
fault filter abort
Hello from v2
Hello from v2

同時,在 kiali 視覺化介面中,也可以看到 sleep 服務對 istio-app-svc 服務的呼叫有 50% 左右的失敗比例

  1. 除此之外,我們也可以為服務注入時延故障,例如在上述介面中,選擇時延故障,為 50% 的請求新增 5s 的時延

  1. 確認提交之後,我們可以看到,部分呼叫的耗時顯著增加。在 kiali 中也可以檢視呼叫的平均請求耗時

  1. 刪除故障注入策略和灰度版本 v2

熔斷

  1. 在 DestinationRule 中設定熔斷規則
kubectl delete destinationrule -n demo istio-app-svc
kubectl apply -n demo -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: istio-app-svc
spec:
  host: istio-app-svc
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 1
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
  subsets:
  - labels:
      version: v1
    name: v1
  - labels:
      version: v2
    name: v2
EOF
  1. 部署一個 HTTP 客戶端,用於負載測試
kubectl apply -n demo -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/sample-client/fortio-deploy.yaml
  1. 在上面的熔斷設定中指定了 maxConnections: 1 以及 http1MaxPendingRequests: 1。這意味著如果超過了一個連線同時發起請求,Istio 就會熔斷,阻止後續的請求或連線。因此我們以併發數為 3,發出 100 個請求:
FORTIO_POD=$(kubectl -n demo get pod | grep fortio | awk '{ print $1 }')
kubectl -n demo exec -it $FORTIO_POD  -c fortio /usr/bin/fortio -- load -c 3 -qps 0 -n 100 -loglevel Warning http://istio-app-svc:8080

從結果中,可以看到,有超過 40% 的請求被 Istio 阻斷了。

Code 200 : 57 (57.0 %)
Code 503 : 43 (43.0 %)
Response Header Sizes : count 100 avg 130.53 +/- 113.4 min 0 max 229 sum 13053
Response Body/Total Sizes : count 100 avg 242.14 +/- 0.9902 min 241 max 243 sum 24214
All done 100 calls (plus 0 warmup) 0.860 ms avg, 2757.6 qps

在 kiali 中觀察可以發現,這部分請求並沒有真正到達 istio-app-svc 的 Pod

  1. 通過查詢 istio-proxy 的狀態,可以獲得更多資訊,upstream_rq_pending_overflow 的值即為被熔斷策略阻止的請求數
kubectl -n demo exec -it $FORTIO_POD -c istio-proxy -- sh -c 'curl localhost:15000/stats' | grep istio-app-svc | grep pending

cluster.outbound|8080|v1|istio-app-svc.demo-ab.svc.cluster.local.upstream_rq_pending_active: 0
cluster.outbound|8080|v1|istio-app-svc.demo-ab.svc.cluster.local.upstream_rq_pending_failure_eject: 0
cluster.outbound|8080|v1|istio-app-svc.demo-ab.svc.cluster.local.upstream_rq_pending_overflow: 99
cluster.outbound|8080|v1|istio-app-svc.demo-ab.svc.cluster.local.upstream_rq_pending_total: 199

清理實驗環境

執行以下命令:

kubectl delete ns demo


原文連結
本文為雲棲社群原創內容,未經