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

:gRPC サーバー間のロードバランシングの実装

最終更新日:Nov 06, 2025

Service Mesh (ASM) を使用すると、さまざまなプログラミング言語を使用する gRPC サーバーにリクエストを均等に分散できます。このトピックでは、Container Service for Kubernetes (ACK) クラスターに gRPC サービスをデプロイして、gRPC サーバー間のロードバランシングを実装する方法について説明します。このトピックでは、ロードバランシングの効果を検証する方法についても説明します。

背景情報

このトピックでは、4 つの gRPC クライアントも異なるプログラミング言語を使用します。GRPC_SERVER 変数で指定された grpc-server-svc.grpc-best.svc.cluster.local サービスを gRPC クライアントが呼び出すと仮定します。ASM が内部リクエストを受信すると、リクエストは 4 つの gRPC サーバーに均等にルーティングされます。さらに、ロードバランシングポリシーに基づいて外部リクエストを 4 つの gRPC サーバーにルーティングするようにイングレスゲートウェイを設定できます。Diagram of the load balancing process

サンプルプロジェクト

gRPC のサンプルプロジェクトについては、hello-servicemesh-grpc をダウンロードしてください。このトピックのディレクトリは、hello-servicemesh-grpc のディレクトリです。

説明

このトピックのイメージリポジトリは参考用です。イメージスクリプトを使用して、イメージをビルドし、セルフマネージドイメージリポジトリにプッシュします。イメージスクリプトの詳細については、「hello-servicemesh-grpc」をご参照ください。

ステップ 1: gRPC サーバー上に gRPC サービスを作成する

この例では、grpc-server-svc という名前の gRPC サービスがすべての gRPC サーバー上に作成されます。

説明

spec.ports.name パラメーターの値は grpc で始まる必要があります。

  1. 次の内容を含む grpc-server-svc ファイルを作成します。

    apiVersion: v1
    kind: Service
    metadata:
      namespace: grpc-best
      name: grpc-server-svc
      labels:
        app: grpc-server-svc
    spec:
      ports:
        - port: 9996
          name: grpc-port
      selector:
        app: grpc-server-deploy
  2. 次のコマンドを実行して gRPC サービスを作成します。

    kubectl apply -f grpc-server-svc.yaml

ステップ 2: 各 gRPC サーバー上に Deployment を作成する

以下の手順では、Node.js 言語の gRPC サーバーの grpc-server-node.yaml ファイルを使用して gRPC サーバー上に Deployment を作成する方法を示します。他の言語の gRPC サーバーの Deployment の詳細については、「サンプルプロジェクト」セクションでダウンロードした hello-servicemesh-grpc ファイルをご参照ください。

説明

ステップ 1 で作成した gRPC サービスのセレクターに一致させるには、gRPC サーバー上の 4 つの Deployment の app ラベルを grpc-server-deploy に設定する必要があります。異なる言語の 4 つの gRPC サーバー上の各 Deployment には、一意の version ラベルが必要です。

  1. 次の内容を含むgrpc-server-node YAML ファイルを作成します:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: grpc-best
      name: grpc-server-node
      labels:
        app: grpc-server-deploy
        version: v3
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: grpc-server-deploy
          version: v3
      template:
        metadata:
          labels:
            app: grpc-server-deploy
            version: v3
        spec:
          containers:
            - name: grpc-server-deploy
              image: registry.cn-hangzhou.aliyuncs.com/aliacs-app-catalog/asm-grpc-server-node:1.0.0
              imagePullPolicy: Always
              ports:
                - containerPort: 9996
                  name: grpc-port
  2. 次のコマンドを実行して Deployment を作成します。

    kubectl apply -f grpc-server-node.yaml

ステップ 3: 各 gRPC クライアント上に Deployment を作成する

gRPC クライアントの Deployment と gRPC サーバーの Deployment は、次の点で異なります。

  • gRPC サーバーは起動後、継続的に実行されます。gRPC クライアントはリクエストが完了すると実行を停止します。したがって、クライアント側のコンテナーが停止しないようにするには、無限ループが必要です。

  • gRPC クライアントで GRPC_SERVER 変数を設定する必要があります。gRPC クライアントの Pod が起動すると、GRPC_SERVER 変数の値が gRPC クライアントに渡されます。

4 つの gRPC クライアントのそれぞれに Deployment を作成する必要があります。以下の手順では、Go 言語の gRPC クライアントの grpc-client-go.yaml ファイルを使用して gRPC クライアント上に Deployment を作成する方法を示します。

  1. 次の内容を含む grpc-client-go ファイルを作成します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: grpc-best
      name: grpc-client-go
      labels:
        app: grpc-client-go
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: grpc-client-go
      template:
        metadata:
          labels:
            app: grpc-client-go
        spec:
          containers:
            - name: grpc-client-go
              image: registry.cn-hangzhou.aliyuncs.com/aliacs-app-catalog/asm-grpc-client-go:1.0.0
              command: ["/bin/sleep", "3650d"]
              env:
                - name: GRPC_SERVER
                  value: "grpc-server-svc.grpc-best.svc.cluster.local"
              imagePullPolicy: Always
  2. 次のコマンドを実行して Deployment を作成します。

    kubectl apply -f grpc-client-go.yaml

command: ["/bin/sleep", "3650d"] の行は、Pod の起動後に Go 言語の gRPC クライアントの Pod をスリープモードで実行し続けるために実行されるコマンドを示します。env の GRPC_SERVER 変数は grpc-server-svc.grpc-best.svc.cluster.local に設定されます。

ステップ 4: gRPC サービスと Deployment をデプロイする

  1. 次のコマンドを実行して、ACK クラスターに grpc-best という名前の名前空間を作成します。

    alias k="kubectl --kubeconfig $USER_CONFIG"
    k create ns grpc-best
  2. 次のコマンドを実行して、名前空間の自動サイドカーインジェクションを有効にします。

    k label ns grpc-best istio-injection=enabled
  3. 次のコマンドを実行して、gRPC サービスと 8 つの Deployment をデプロイします。

    kubectl apply -f grpc-svc.yaml
    kubectl apply -f deployment/grpc-server-java.yaml
    kubectl apply -f deployment/grpc-server-python.yaml
    kubectl apply -f deployment/grpc-server-go.yaml
    kubectl apply -f deployment/grpc-server-node.yaml
    kubectl apply -f deployment/grpc-client-java.yaml
    kubectl apply -f deployment/grpc-client-python.yaml
    kubectl apply -f deployment/grpc-client-go.yaml
    kubectl apply -f deployment/grpc-client-node.yaml

結果の検証

Pod を使用して gRPC サービスのロードバランシングを検証する

gRPC クライアントの Pod から gRPC サーバー上の gRPC サービスにリクエストを送信することで、gRPC サーバー間のロードバランシングを検証できます。

  1. 次のコマンドを実行して、4 つの gRPC クライアントの Pod の名前を取得します。

    client_java_pod=$(k get pod -l app=grpc-client-java -n grpc-best -o jsonpath={.items..metadata.name})
    client_go_pod=$(k get pod -l app=grpc-client-go -n grpc-best -o jsonpath={.items..metadata.name})
    client_node_pod=$(k get pod -l app=grpc-client-node -n grpc-best -o jsonpath={.items..metadata.name})
    client_python_pod=$(k get pod -l app=grpc-client-python -n grpc-best -o jsonpath={.items..metadata.name})
  2. 次のコマンドを実行して、gRPC クライアントの Pod から 4 つの gRPC サーバー上の gRPC サービスにリクエストを送信します。

    k exec "$client_java_pod" -c grpc-client-java -n grpc-best -- java -jar /grpc-client.jar
    k exec "$client_go_pod" -c grpc-client-go -n grpc-best -- ./grpc-client
    k exec "$client_node_pod" -c grpc-client-node -n grpc-best -- node proto_client.js
    k exec "$client_python_pod" -c grpc-client-python -n grpc-best -- sh /grpc-client/start_client.sh
  3. FOR ループを使用して、gRPC サーバー間のロードバランシングを検証します。この例では、Node.js 言語の gRPC クライアントが使用されます。

    for ((i = 1; i <= 100; i++)); do
    kubectl exec "$client_node_pod" -c grpc-client-node -n grpc-best -- node kube_client.js > kube_result
    done
    sort kube_result | grep -v "^[[:space:]]*$" | uniq -c | sort -nrk1

    期待される出力:

      26 Talk:PYTHON
      25 Talk:NODEJS
      25 Talk:GOLANG
      24 Talk:JAVA

    出力は、gRPC サービスがデプロイされている 4 つの gRPC サーバーがほぼ同数のリクエストを受信したことを示しています。ロードバランシングの結果は、ASM がロードバランシングポリシーに基づいて、gRPC サービスがデプロイされている 4 つの gRPC サーバーに外部リクエストをルーティングできることを示しています。

イングレスゲートウェイを使用して gRPC サービスのロードバランシングを検証する

イングレスゲートウェイを使用して、gRPC サーバー間のロードバランシングを検証できます。

  1. ポート 9996 を公開するイングレスゲートウェイを作成します。

    詳細については、「イングレスゲートウェイサービスの作成」をご参照ください。

  2. 次の YAML コードを使用して Istio ゲートウェイを作成します。

    詳細については、「Istio ゲートウェイの管理」をご参照ください。

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      namespace: grpc-best
      name: grpc-gateway
    spec:
      selector:
        istio: ingressgateway
      servers:
        - port:
            number: 9996
            name: grpc
            protocol: GRPC
          hosts:
            - "*"
  3. 次の YAML コードを使用して仮想サービスを作成します。

    詳細については、「仮想サービスの管理」をご参照ください。

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      namespace: grpc-best
      name: grpc-vs
    spec:
      hosts:
      - "*"
      gateways:
      - grpc-gateway
      http:
      - route:
        - destination:
            host: grpc-server-svc.grpc-best.svc.cluster.local
            port:
              number: 9996
  4. 次のコマンドを実行して、イングレスゲートウェイの IP アドレスを取得します。

    INGRESS_IP=$(k -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  5. FOR ループを使用して、gRPC サーバー間のロードバランシングを検証します。

    docker run -d --name grpc_client_node -e GRPC_SERVER="${INGRESS_IP}" registry.cn-hangzhou.aliyuncs.com/aliacs-app-catalog/asm-grpc-client-node:1.0.0 /bin/sleep 3650d
    client_node_container=$(docker ps -q)
    
    docker exec -e GRPC_SERVER="${INGRESS_IP}" -it "$client_node_container" node kube_client.js
    
    for ((i = 1; i <= 100; i++)); do
    docker exec -e GRPC_SERVER="${INGRESS_IP}" -it "$client_node_container" node kube_client.js >> kube_result
    done
    sort kube_result | grep -v "^[[:space:]]*$" | uniq -c | sort -nrk1

    期待される出力:

      26 Talk:PYTHON
      25 Talk:NODEJS
      25 Talk:GOLANG
      24 Talk:JAVA

    出力は、gRPC サービスがデプロイされている 4 つの gRPC サーバーがほぼ同数のリクエストを受信したことを示しています。ロードバランシングの結果は、ASM がロードバランシングポリシーに基づいて、gRPC サービスがデプロイされている 4 つの gRPC サーバーに外部リクエストをルーティングできることを示しています。