當您遇到跨可用性區域網路延遲導致的服務回應時間增加或成本上升等問題時,可以使用同可用性區域優先路由(簡稱同AZ路由)功能,優先保證服務要求在同一個可用性區域內完成處理,減少網路傳輸延遲,降低因跨地區流量產生的額外費用,提高整體服務的運行效率和穩定性。ASM支援在不需要修改應用代碼的情況下實現同AZ路由。本文以入口網關訪問httpbin應用為例,介紹如何使用同AZ路由。
前提條件
已添加叢集到ASM執行個體。具體操作,請參見添加叢集到ASM執行個體。
ACK叢集中的節點存在至少兩個可用性區域,本樣本中分別使用cn-hongkong-b和cn-hongkong-c,您可以在Container Service管理主控台查看叢集節點所對應的ECS所在地區及可用性區域。更多資訊,請參見地區和可用性區域。
說明本樣本中sleep應用部署在可用性區域cn-hongkong-b,helloworld-v1應用部署到可用性區域cn-hongkong-b中,helloworld-v2應用部署到可用性區域cn-hongkong-c中,您可以根據實際叢集所使用的可用性區域進行替換。
注意事項
同可用性區域優先路由啟用後,在同可用性區域存在可用目標的情況下,叢集內部應用間的調用將不會跨可用性區域。因此,為了保證啟用該能力後的負載平衡,您需要確保相關工作負載是均勻分布在多個可用性區域的。您可以通過topologySpreadConstraints使得工作負載在建立、擴容時被調度器儘可能均勻地分布到不同可用性區域。同時,如果您的工作負載存在擴縮容情境,需要進一步啟用重調度(DeScheduling)以確保在縮容時工作負載仍然保持均勻分布。
背景資訊
同AZ路由是指在用戶端對一個目標服務的訪問過程中,可以根據這個用戶端所在的地區、可用性區域拓撲資訊,優先路由到與該用戶端在同一個節點或者可用性區域的目標服務上的路由行為。同AZ路由本身屬於負載平衡策略的範疇,它能夠使流量儘可能在同一個可用性區域內流轉,以保證服務間的調用延遲最低。
步驟一:部署樣本應用
使用以下內容,建立sleep.yaml。
說明如下樣本中,sleep應用部署到可用性區域cn-hongkong-b,您可以根據實際叢集所使用的可用性區域進行替換。
執行以下命令,在叢集中部署sleep應用。
kubectl apply -f sleep.yaml
使用以下內容,建立helloworld.yaml。
說明如下樣本中,helloworld-v1應用部署到可用性區域cn-hongkong-b中,helloworld-v2應用部署到可用性區域cn-hongkong-c中,您可以根據實際叢集所使用的可用性區域進行替換。
執行以下命令,在叢集中部署helloworld應用。
kubectl apply -f helloworld.yaml
執行以下命令,查詢目標服務的註冊資訊。
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" -c sleep -- curl localhost:15000/clusters | grep helloworld
預期輸出:
outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::region::cn-hongkong outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::zone::cn-hongkong-b outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::sub_zone:: outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::canary::false outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::priority::0 ....... outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::region::cn-hongkong outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::zone::cn-hongkong-c outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::sub_zone:: outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::canary::false outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::priority::0
由預期輸出得到,兩個helloworld應用的優先順序相同,均為
priority::0
。說明當sleep用戶端調用helloworld服務時,兩個helloworld應用的路由策略相同。
步驟二:設定同AZ優先路由
通過應用目標規則來解決優先順序問題,為服務helloworld.default.svc.cluster.local
啟用同AZ路由的能力。
您可以調整連續5xx錯誤(consecutive5xxErrors
)、間隔時間(interval
)以及最小的移除時間長度(baseEjectionTime
)參數,實現同可用性區域路由的優先調用。本樣本將在第一個請求失敗時觸發容錯移轉。
使用以下內容,建立helloworld-failover.yaml。
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: helloworld-failover namespace: default spec: host: helloworld.default.svc.cluster.local trafficPolicy: connectionPool: http: maxRequestsPerConnection: 1 loadBalancer: localityLbSetting: enabled: true simple: ROUND_ROBIN outlierDetection: baseEjectionTime: 1m consecutive5xxErrors: 1 interval: 1s
執行以下命令,查看工作負載的優先順序。
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" -c sleep -- curl localhost:15000/clusters | grep helloworld
預期輸出:
outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::region::cn-hongkong outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::zone::cn-hongkong-b outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::sub_zone:: outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::canary::false outbound|5000||helloworld.default.svc.cluster.local::172.28.32.49:5000::priority::0 ....... outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::region::cn-hongkong outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::zone::cn-hongkong-c outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::sub_zone:: outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::canary::false outbound|5000||helloworld.default.svc.cluster.local::172.28.33.155:5000::priority::1
由預期輸出得到,兩個helloworld應用的優先順序不同,分別為
priority::0
和priority::1
。說明當sleep用戶端調用helloworld服務時,同AZ路由的策略生效。
步驟三:驗證同AZ優先路由
從位於可用性區域cn-hongkong-b中的用戶端sleep應用發送請求,調用helloworld服務。啟用同AZ優先路由之後,所有流量都應指向同在可用性區域cn-hongkong-b中的helloworld-v1應用。其中,sleep應用部署在可用性區域cn-hongkong-b,helloworld-v1應用部署到可用性區域cn-hongkong-b中,helloworld-v2應用部署到可用性區域cn-hongkong-c中。
重複執行以下命令,訪問helloworld服務。
kubectl exec -c sleep "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" -- curl -sSL helloworld:5000/hello
預期輸出:
Hello version: v1, instance: helloworld-v1-6f88967849-sq2h2
由預期輸出得到,返回結果始終為helloworld-v1服務。
縮容helloworld-v1服務。
執行以下命令,縮容helloworld-v1服務到0個Pod,類比該服務不可用狀態。
kubectl scale deploy helloworld-v1 --replicas=0
等待幾秒後,重複執行以下命令,訪問helloworld服務。
kubectl exec -c sleep "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" -- curl -sSL helloworld:5000/hello
預期輸出:
Hello version: v2, instance: helloworld-v2-75db5f978d-s7v4k
由預期輸出得到,當本可用性區域的helloworld-v1服務不可用時,會自動切換到另一可用性區域cn-hongkong-c中的helloworld-v2服務。
擴容helloworld-v1服務。
執行以下命令,擴容helloworld-v1服務到1個Pod,恢複可用性區域cn-hongkong-b中的helloworld-v1應用服務。
kubectl scale deploy helloworld-v1 --replicas=1
等待幾秒後,重複執行以下命令,訪問helloworld服務。
kubectl exec -c sleep "$(kubectl get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')" -- curl -sSL helloworld:5000/hello
預期輸出:
Hello version: v1, instance: helloworld-v1-6f88967849-sq2h2
由預期輸出得到,返回結果始終為helloworld-v1服務。