ゾーン間のネットワークレイテンシによってサービスの応答時間の増加やコストの増加などの問題が発生した場合、ゾーン認識ルーティング機能を使用して、サービスリクエストが同じゾーン内で優先的に処理されるようにすることができます。 これにより、ネットワーク伝送レイテンシが短縮され、ゾーン間トラフィックによる追加コストが削減され、サービス全体の効率と安定性が向上します。 サービスメッシュ (ASM) を使用すると、アプリケーションコードを変更することなく、ゾーン認識ルーティング機能 (ゾーン内ルーティングとも呼ばれます) を使用できます。 このトピックでは、この機能の使用方法について説明します。 次の例では、イングレスゲートウェイを使用して HTTPBin アプリケーションへのアクセスを有効にしています。
前提条件
クラスターが ASM インスタンスに追加されていること。 詳細については、「ASM インスタンスへのクラスターの追加」をご参照ください。
コンテナサービス Kubernetes 版 (ACK) クラスターのノードが少なくとも 2 つのゾーンに存在していること。 このトピックでは、 cn-hongkong-b ゾーンと cn-hongkong-c ゾーンが使用されています。 クラスターノードに対応する Elastic Compute Service (ECS) インスタンスが存在するリージョンとゾーンは、Container Service for Kubernetes (ACK) コンソールで確認できます。 詳細については、「リージョンとゾーン」をご参照ください。
説明この例では、 sleep アプリケーションと helloworld-v1 アプリケーションは cn-hongkong-b にデプロイされ、 helloworld-v2 アプリケーションは cn-hongkong-c にデプロイされています。 アプリケーションが存在するゾーンを使用してください。
使用上の注意
ゾーン認識ルーティング機能が有効になっている場合、アプリケーションからのリクエストは、可能な限り常に同じゾーン内の他のアプリケーションに優先的にルーティングされます。 この場合、ロードバランシングを確保するには、ワークロードが異なるゾーンに均等に分散されていることを確認する必要があります。 スケジューラーを使用して、 topologySpreadConstraints を構成して、ゾーン全体にワークロードを分散させることができます。 さらに、ワークロードをスケールインまたはスケールアウトするには、スケールイン中にワークロードが均等に分散されるように DeScheduling を有効にする必要があります。
背景情報
クライアントがサービスにアクセスするためのリクエストを開始すると、リクエストは、クライアントが存在するリージョンとゾーンに関するトポロジ情報に基づいて、クライアントと同じノードまたは同じゾーンにあるサービスに優先的にルーティングされます。 これがゾーン認識ルーティング機能の仕組みです。 ゾーン認識ルーティングはロードバランシング機能です。 同じゾーン内のトラフィックフローを作成して、サービスレイテンシを削減します。
手順 1:サンプルアプリケーションをデプロイする
次の内容を含む sleep.yaml ファイルを作成します。
説明次の例では、 sleep アプリケーションは cn-hongkong-b にデプロイされています。 ビジネス要件に基づいて、ゾーンにアプリケーションをデプロイできます。
次のコマンドを実行して、 ACK クラスターに sleep アプリケーションをデプロイします。
kubectl apply -f sleep.yaml次の内容を含む helloworld.yaml ファイルを作成します。
説明次の例では、 helloworld-v1 アプリケーションは cn-hongkong-b にデプロイされ、 helloworld-v2 アプリケーションは cn-hongkong-c にデプロイされています。 ビジネス要件に基づいて、ゾーンにアプリケーションをデプロイできます。
次のコマンドを実行して、 ACK クラスターに 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出力は、 2 つの helloworld アプリケーションの優先順位
priority::0が同じであることを示しています。 したがって、 sleep クライアントが helloworld サービスを呼び出すと、 2 つの helloworld アプリケーションのルーティングポリシーは同じになります。
手順 2:ゾーン認識ルーティング機能を有効にする
宛先ルールを使用して、クライアントのゾーンにある helloworld アプリケーションに優先順位を付けます。 helloworld.default.svc.cluster.local サービスのゾーン認識ルーティング機能を有効にします。
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出力では、 2 つの helloworld アプリケーションの優先順位が異なり、それぞれ
priority::0とpriority::1です。 出力は、 sleep クライアントが helloworld サービスを呼び出すと、ゾーン認識ルーティング機能が有効になることを示しています。
手順 3:ゾーン認識ルーティング機能を確認する
cn-hongkong-b ゾーンにあるクライアントの sleep アプリケーションから helloworld サービスを呼び出すリクエストを送信します。 ゾーン認識ルーティング機能が有効になっている場合、すべてのトラフィックは、クライアントと同じゾーンにある helloworld-v1 アプリケーションにルーティングされます。 sleep アプリケーションと 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 アプリケーションをゼロポッドにスケールインし、アプリケーションを使用不可にします。
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 つのポッドにスケールアウトし、 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 アプリケーションであることを示しています。