地域故障转移

按照本指南配置您的网格以进行地域故障转移。

在继续之前,请确保已完成 开始之前 部分中的步骤。

在此任务中,您将使用 region1.zone1 中的 curl pod 作为请求 HelloWorld 服务的源。然后,您将触发故障,这些故障将导致按照以下顺序在地域之间进行故障转移

Locality failover sequence
地域故障转移顺序

在内部,Envoy 优先级 用于控制故障转移。对于来自 curl pod(在 region1 zone1 中)的流量,这些优先级将按如下方式分配

优先级区域详情
0region1.zone1区域、区域和子区域全部匹配。
1由于此任务不使用子区域,因此没有与不同子区域匹配的内容。
2region1.zone2同一区域内的不同区域。
3region2.zone3无匹配,但为region1->region2定义了故障转移。
4region3.zone4无匹配,并且未为region1->region3定义故障转移。

配置地域故障转移

应用一个配置以下内容的DestinationRule

  • 异常检测 用于HelloWorld服务。这对于故障转移正常运行是必需的。特别是,它配置了 sidecar 代理,以便它们了解服务的端点何时不健康,最终触发故障转移到下一个区域。

  • 故障转移 区域之间的策略。这确保跨区域边界的故障转移行为可预测。

  • 连接池 策略,强制每个 HTTP 请求使用新的连接。此任务利用 Envoy 的 drain 功能来强制故障转移到下一个区域。排空后,Envoy 将拒绝新的连接请求。由于每个请求都使用新的连接,因此这会导致在排空之后立即进行故障转移。此配置仅用于演示目的。

$ kubectl --context="${CTX_PRIMARY}" apply -n sample -f - <<EOF
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
  name: helloworld
spec:
  host: helloworld.sample.svc.cluster.local
  trafficPolicy:
    connectionPool:
      http:
        maxRequestsPerConnection: 1
    loadBalancer:
      simple: ROUND_ROBIN
      localityLbSetting:
        enabled: true
        failover:
          - from: region1
            to: region2
    outlierDetection:
      consecutive5xxErrors: 1
      interval: 1s
      baseEjectionTime: 1m
EOF

验证流量是否停留在 region1.zone1

curl pod 调用HelloWorld服务

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region1.zone1, instance: helloworld-region1.zone1-86f77cd7b-cpxhv

验证响应中的version是否为region1.zone

重复此操作数次,并验证响应始终相同。

故障转移到 region1.zone2

接下来,触发故障转移到region1.zone2。为此,您需要 排空region1.zone1HelloWorld 的 Envoy sidecar 代理

$ kubectl --context="${CTX_R1_Z1}" exec \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l app=helloworld \
  -l version=region1.zone1 -o jsonpath='{.items[0].metadata.name}')" \
  -n sample -c istio-proxy -- curl -sSL -X POST 127.0.0.1:15000/drain_listeners

curl pod 调用HelloWorld服务

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region1.zone2, instance: helloworld-region1.zone2-86f77cd7b-cpxhv

第一次调用将失败,这将触发故障转移。重复执行命令数次,并验证响应中的version始终为region1.zone2

故障转移到 region2.zone3

现在触发故障转移到region2.zone3。与之前一样,将region1.zone2 中的HelloWorld 配置为在被调用时失败

$ kubectl --context="${CTX_R1_Z2}" exec \
  "$(kubectl get pod --context="${CTX_R1_Z2}" -n sample -l app=helloworld \
  -l version=region1.zone2 -o jsonpath='{.items[0].metadata.name}')" \
  -n sample -c istio-proxy -- curl -sSL -X POST 127.0.0.1:15000/drain_listeners

curl pod 调用HelloWorld服务

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region2.zone3, instance: helloworld-region2.zone3-86f77cd7b-cpxhv

第一次调用将失败,这将触发故障转移。重复执行命令数次,并验证响应中的version始终为region2.zone3

故障转移到 region3.zone4

现在触发故障转移到region3.zone4。与之前一样,将region2.zone3 中的HelloWorld 配置为在被调用时失败

$ kubectl --context="${CTX_R2_Z3}" exec \
  "$(kubectl get pod --context="${CTX_R2_Z3}" -n sample -l app=helloworld \
  -l version=region2.zone3 -o jsonpath='{.items[0].metadata.name}')" \
  -n sample -c istio-proxy -- curl -sSL -X POST 127.0.0.1:15000/drain_listeners

curl pod 调用HelloWorld服务

$ kubectl exec --context="${CTX_R1_Z1}" -n sample -c curl \
  "$(kubectl get pod --context="${CTX_R1_Z1}" -n sample -l \
  app=curl -o jsonpath='{.items[0].metadata.name}')" \
  -- curl -sSL helloworld.sample:5000/hello
Hello version: region3.zone4, instance: helloworld-region3.zone4-86f77cd7b-cpxhv

第一次调用将失败,这将触发故障转移。重复执行命令数次,并验证响应中的version始终为region3.zone4

恭喜!您已成功配置区域故障转移!

下一步

清理 此任务中的资源和文件。

这些信息对您有用吗?
您有任何改进建议吗?

感谢您的反馈!