為外部服務設定容錯移轉
了解如何為網格外部的端點設定區域性負載平衡和容錯移轉。
Istio 強大的 API 可以用來解決各種服務網格的使用案例。許多用戶知道它強大的入口和東西向功能,但它也為出口(向外)流量提供了許多功能。當您的應用程式需要與外部服務(例如雲提供商提供的資料庫端點)通信時,這特別有用。通常,根據您的工作負載在哪裡執行,有多個端點可供選擇。例如,Amazon 的 DynamoDB 在其各個區域提供多個端點。您通常會選擇最接近您的工作負載的端點以獲得較低的延遲,但是如果情況不如預期,您可能需要設定自動容錯移轉到另一個端點。
與在服務網格內執行的服務類似,您可以設定 Istio 來偵測異常值並容錯移轉到健康的端點,同時對您的應用程式完全透明。在此範例中,我們將使用 Amazon DynamoDB 端點,並選擇與在 Google Kubernetes Engine (GKE) 叢集中執行的工作負載相同或接近的主要區域。我們還將設定容錯移轉區域。
路由 | 端點 |
---|---|
主要 | http://dynamodb.us-east-1.amazonaws.com |
容錯移轉 | http://dynamodb.us-west-1.amazonaws.com |
使用 ServiceEntry 定義外部端點
區域性負載平衡根據 region
或 zone
運作,它們通常是從 Kubernetes 節點上設定的標籤推斷出來的。首先,確定您的工作負載的位置
$ kubectl describe node | grep failure-domain.beta.kubernetes.io/region
failure-domain.beta.kubernetes.io/region=us-east1
failure-domain.beta.kubernetes.io/region=us-east1
在此範例中,GKE 叢集節點在 us-east1
中執行。
接下來,建立一個 ServiceEntry
,它會聚合您想要使用的端點。在此範例中,我們選擇了 mydb.com
作為主機。這是您的應用程式應設定為連線的位址。將主要端點的 locality
設定為與您的工作負載相同的區域
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-svc-dns
spec:
hosts:
- mydb.com
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
endpoints:
- address: dynamodb.us-east-1.amazonaws.com
locality: us-east1
ports:
http: 80
- address: dynamodb.us-west-1.amazonaws.com
locality: us-west
ports:
http: 80
讓我們部署一個 sleep 容器,以用作傳送請求的測試來源。
$ kubectl apply -f @samples/sleep/sleep.yaml@
從 sleep 容器嘗試前往 http://mydb.com
5 次
$ for i in {1..5}; do kubectl exec deploy/sleep -c sleep -- curl -sS http://mydb.com; echo; sleep 2; done
healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-west-1.amazonaws.com
healthy: dynamodb.us-west-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com
您會看到 Istio 正在將請求傳送到兩個端點。我們只希望它傳送到標記為與我們節點相同區域的端點。
為此,我們需要設定一個 DestinationRule
。
使用 DestinationRule
設定容錯移轉條件
Istio 的 DestinationRule
可讓您設定負載平衡、連線池和異常值偵測設定。我們可以指定用於識別端點為不健康的條件,並將其從負載平衡池中移除。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: mydynamodb
spec:
host: mydb.com
trafficPolicy:
outlierDetection:
consecutive5xxErrors: 1
interval: 15s
baseEjectionTime: 1m
上述 DestinationRule
設定為每 15 秒掃描一次端點,並且如果任何端點發生 5xx 錯誤碼,即使只有一次,也會被標記為不健康一分鐘。如果未觸發此斷路器,流量將路由到與 Pod 相同的區域。
如果我們再次執行 curl,我們應該會看到流量始終傳送到 us-east1
端點。
$ for i in {1..5}; do kubectl exec deploy/sleep -c sleep -- curl -sS http://mydb.com; echo; sleep 2; done
healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com
healthy: dynamodb.us-east-1.amazonaws.com
模擬失敗
接下來,讓我們看看如果 us-east 端點當機會發生什麼事。為了模擬這種情況,讓我們修改 ServiceEntry 並將 us-east
端點設定為無效的連接埠
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-svc-dns
spec:
hosts:
- mydb.com
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
endpoints:
- address: dynamodb.us-east-1.amazonaws.com
locality: us-east1
ports:
http: 81 # INVALID - This is purposefully wrong to trigger failover
- address: dynamodb.us-west-1.amazonaws.com
locality: us-west
ports:
http: 80
再次執行 curl 會顯示,在無法連線到 us-east 端點後,流量會自動容錯移轉到我們的 us-west 區域
$ for i in {1..5}; do kubectl exec deploy/sleep -c sleep -- curl -sS http://mydb.com; echo; sleep 2; done
upstream connect error or disconnect/reset before headers. reset reason: connection failure
healthy: dynamodb.us-west-1.amazonaws.com
healthy: dynamodb.us-west-1.amazonaws.com
healthy: dynamodb.us-west-1.amazonaws.com
healthy: dynamodb.us-west-1.amazonaws.com
您可以透過執行以下命令來檢查 us-east 端點的異常值狀態
$ istioctl pc endpoints <sleep-pod> | grep mydb
ENDPOINT STATUS OUTLIER CHECK CLUSTER
52.119.226.80:81 HEALTHY FAILED outbound|80||mydb.com
52.94.12.144:80 HEALTHY OK outbound|80||mydb.com
HTTPS 容錯移轉
為外部 HTTPS 服務設定容錯移轉也很容易。您的應用程式仍然可以繼續使用純 HTTP,您可以讓 Istio 代理執行到 HTTPS 端點的 TLS 起源。
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-svc-dns
spec:
hosts:
- mydb.com
ports:
- number: 80
name: http-port
protocol: HTTP
targetPort: 443
resolution: DNS
endpoints:
- address: dynamodb.us-east-1.amazonaws.com
locality: us-east1
- address: dynamodb.us-west-1.amazonaws.com
locality: us-west
上述 ServiceEntry 在連接埠 80 上定義 mydb.com
服務,並將流量重新導向到連接埠 443 上的實際 DynamoDB 端點。
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: mydynamodb
spec:
host: mydb.com
trafficPolicy:
tls:
mode: SIMPLE
loadBalancer:
simple: ROUND_ROBIN
localityLbSetting:
enabled: true
failover:
- from: us-east1
to: us-west
outlierDetection:
consecutive5xxErrors: 1
interval: 15s
baseEjectionTime: 1m
現在,DestinationRule
執行 TLS 起源並設定異常值偵測。該規則還設定了一個 容錯移轉 欄位,您可以在其中指定確切的區域作為容錯移轉目標。當您定義了多個區域時,這很有用。
總結
Istio 的 VirtualService
和 DestinationRule
API 提供流量路由、故障復原和錯誤注入功能,以便您可以建立具彈性的應用程式。ServiceEntry API 將許多這些功能擴展到不屬於您的服務網格的外部服務。