为外部服务配置故障转移
了解如何为网格之外的端点配置区域性负载均衡和故障转移。
Istio 的强大 API 可用于解决各种服务网格用例。许多用户了解其强大的入口和东西向功能,但它还提供许多用于出口(出站)流量的功能。这在您的应用程序需要与外部服务进行通信时特别有用 - 例如由云提供商提供的数据库端点。根据您的工作负载运行位置,通常有多个端点可供选择。例如,亚马逊的 DynamoDB 在其各区域提供 多个端点。您通常希望选择最靠近您工作负载的端点以降低延迟,但您可能需要配置自动故障转移到另一个端点,以防情况不如预期。
与在服务网格内部运行的服务类似,您可以配置 Istio 来检测异常值并将流量转移到健康端点,同时对您的应用程序保持完全透明。在本示例中,我们将使用亚马逊 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 将这些功能中的许多扩展到不在您的服务网格中的外部服务。