すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Service Mesh:ゾーン認識ルーティング機能を有効にする

最終更新日:Jan 13, 2025

ゾーン間のネットワークレイテンシによってサービスの応答時間の増加やコストの増加などの問題が発生した場合、ゾーン認識ルーティング機能を使用して、サービスリクエストが同じゾーン内で優先的に処理されるようにすることができます。これにより、ネットワーク伝送レイテンシが短縮され、ゾーン間トラフィックによる追加コストが削減され、サービス全体の効率と安定性が向上します。Service Mesh(ASM)では、アプリケーションコードを変更することなく、ゾーン認識ルーティング機能(ゾーン内ルーティングとも呼ばれます)を使用できます。このトピックでは、この機能の使用方法について説明します。次の例では、イングレスゲートウェイを使用して HTTPBin アプリケーションへのアクセスを有効にしています。

前提条件

  • クラスターが ASM インスタンスに追加されていること。詳細については、「ASM インスタンスへのクラスターの追加」をご参照ください。

  • Container Service for Kubernetes(ACK)クラスターのノードが少なくとも 2 つのゾーンに存在していること。このトピックでは、 cn-hongkong-b ゾーンと cn-hongkong-c ゾーンが使用されています。Container Service for Kubernetes (ACK) コンソールで、クラスターノードに対応する Elastic Compute Service(ECS)インスタンスが存在するリージョンとゾーンを確認できます。詳細については、「リージョンとゾーン」をご参照ください。

    説明

    この例では、 sleep アプリケーションと helloworld-v1 アプリケーションは cn-hongkong-b にデプロイされ、 helloworld-v2 アプリケーションは cn-hongkong-c にデプロイされています。アプリケーションが存在するゾーンを使用してください。

背景情報

クライアントがサービスにアクセスするためのリクエストを開始すると、リクエストは、クライアントが存在するリージョンとゾーンに関するトポロジ情報に基づいて、クライアントと同じノードまたは同じゾーンにあるサービスに優先的にルーティングされます。これがゾーン認識ルーティング機能の仕組みです。ゾーン認識ルーティングはロードバランシング機能です。同じゾーン内のトラフィックフローを作成して、サービスレイテンシを削減します。

手順 1:サンプルアプリケーションをデプロイする

  1. 次の内容を含む sleep.yaml ファイルを作成します。

    説明

    次の例では、sleep アプリケーションは cn-hongkong-b にデプロイされています。ビジネス要件に基づいて、アプリケーションをゾーンにデプロイできます。

    展開して sleep.yaml ファイルを表示する

    # Copyright Istio Authors
    #
    #   Licensed under the Apache License, Version 2.0 (the "License");
    #   you may not use this file except in compliance with the License.
    #   You may obtain a copy of the License at
    #
    #       http://www.apache.org/licenses/LICENSE-2.0
    #
    #   Unless required by applicable law or agreed to in writing, software
    #   distributed under the License is distributed on an "AS IS" BASIS,
    #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    #   See the License for the specific language governing permissions and
    #   limitations under the License.
    
    ##################################################################################################
    # Sleep サービス
    ##################################################################################################
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: sleep
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: sleep
      labels:
        app: sleep
        service: sleep
    spec:
      ports:
      - port: 80
        name: http
      selector:
        app: sleep
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sleep
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sleep
      template:
        metadata:
          labels:
            app: sleep
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: failure-domain.beta.kubernetes.io/zone
                    operator: In
                    values:
                      - 'cn-hongkong-b'
          terminationGracePeriodSeconds: 0
          serviceAccountName: sleep
          containers:
          - name: sleep
            image: curlimages/curl
            command: ["/bin/sleep", "3650d"]
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /etc/sleep/tls
              name: secret-volume
          volumes:
          - name: secret-volume
            secret:
              secretName: sleep-secret
              optional: true
  2. 次のコマンドを実行して、ACK クラスターに sleep アプリケーションをデプロイします。

    kubectl apply -f sleep.yaml
  3. 次の内容を含む helloworld.yaml ファイルを作成します。

    説明

    次の例では、 helloworld-v1 アプリケーションは cn-hongkong-b にデプロイされ、 helloworld-v2 アプリケーションは cn-hongkong-c にデプロイされています。ビジネス要件に基づいて、アプリケーションをゾーンにデプロイできます。

    展開して helloworld.yaml ファイルを表示する

    apiVersion: v1
    kind: Service
    metadata:
      name: helloworld
      labels:
        app: helloworld
        service: helloworld
    spec:
      ports:
      - port: 5000
        name: http
      selector:
        app: helloworld
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: helloworld-v1
      labels:
        app: helloworld
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: helloworld
          version: v1
      template:
        metadata:
          labels:
            app: helloworld
            version: v1
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: failure-domain.beta.kubernetes.io/zone
                    operator: In
                    values:
                      - 'cn-hongkong-b'
          containers:
          - name: helloworld
            image: docker.io/istio/examples-helloworld-v1
            resources:
              requests:
                cpu: "100m"
            imagePullPolicy: IfNotPresent #Always
            ports:
            - containerPort: 5000
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: helloworld-v2
      labels:
        app: helloworld
        version: v2
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: helloworld
          version: v2
      template:
        metadata:
          labels:
            app: helloworld
            version: v2
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: failure-domain.beta.kubernetes.io/zone
                    operator: In
                    values:
                      - 'cn-hongkong-c'
          containers:
          - name: helloworld
            image: docker.io/istio/examples-helloworld-v2
            resources:
              requests:
                cpu: "100m"
            imagePullPolicy: IfNotPresent #Always
            ports:
            - containerPort: 5000
                            
  4. 次のコマンドを実行して、ACK クラスターに helloworld アプリケーションをデプロイします。

    kubectl apply -f helloworld.yaml
  5. 次のコマンドを実行して、アクセスするサービスの登録情報をクエリします。

    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 サービスのゾーン認識ルーティング機能を有効にします。

説明

consecutive5xxErrorsintervalbaseEjectionTime パラメーターを設定することで、この機能を有効にできます。この例では、最初のリクエストが失敗したときにフェイルオーバーがトリガーされます。

  1. 次の内容を含む 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
                            
  2. 次のコマンドを実行して、Pod の優先度を表示します。

    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::0priority::1 です。出力は、 sleep クライアントが helloworld サービスを呼び出すと、ゾーン認識ルーティング機能が有効になることを示しています。

手順 3:ゾーン認識ルーティング機能を確認する

cn-hongkong-b ゾーンにあるクライアントの sleep アプリケーションから helloworld サービスを呼び出すリクエストを送信します。ゾーン認識ルーティング機能が有効になっていると、すべてのトラフィックは、クライアントと同じゾーンにある helloworld-v1 アプリケーションにルーティングされます。 sleep アプリケーションと helloworld-v1 アプリケーションは cn-hongkong-b にデプロイされ、 helloworld-v2 アプリケーションは cn-hongkong-c にデプロイされています。

  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 アプリケーションであることを示しています。

  2. helloworld-v1 アプリケーションをスケールインします。

    1. 次のコマンドを実行して、 helloworld-v1 アプリケーションをゼロ Pod にスケールインし、アプリケーションを使用不可にします。

      kubectl scale deploy helloworld-v1 --replicas=0
    2. 数秒待ってから、次のコマンドを複数回実行して、 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 アプリケーションにルーティングされることを示しています。

  3. helloworld-v1 アプリケーションをスケールアウトします。

    1. 次のコマンドを実行して、 helloworld-v1 アプリケーションを 1 つの Pod にスケールアウトし、 helloworld-v1 アプリケーションを復元します。

      kubectl scale deploy helloworld-v1 --replicas=1
    2. 数秒待ってから、次のコマンドを複数回実行して、 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 アプリケーションであることを示しています。