高度なトラフィック管理を使用した VM ベースのプロキシレス gRPC サービスの設定

このドキュメントでは、次のルーティング機能を使用して Traffic Director を構成するエンドツーエンドの手順を説明します。

  • ルート マッチング
  • トラフィック分割

この 2 つの機能のコンセプトに関する情報については、高度なトラフィック管理をご覧ください。

gRPC Wallet のサンプルのデプロイを例に、この機能を説明します。次の図で示すように、wallet-servicestats-serviceaccount-service のバックエンド サービスを作成します。

gRPC Wallet のトラフィック ルーティング構成の例(クリックして拡大)
gRPC Wallet のトラフィック ルーティング構成の例(クリックして拡大)

この例では、構成したルールに基づいたリクエストのルーティングを説明するため、サービスごとに複数のバージョンをデプロイします。異なるバージョンのサービスのビルドとデプロイをシミュレートするには、次のサーバーフラグを使用して、1 回だけビルドするバイナリの動作を変更します。

  • --port フラグには、バックエンド VM 上のサービスがリッスンするポートを指定します。
  • --hostname_suffix フラグには、リクエストに応答する VM のホスト名に追加される値を指定します。生成される値は、レスポンスの hostname メタデータとして追加されます。これは、クライアント リクエストに応答したバックエンド サービスのインスタンスの識別に役立ちます。
  • --premium_only フラグに値 true を指定すると、サービスが stats サービスのプレミアム バージョンになります。
  • --v1_behavior フラグに値 true を指定すると、ウォレットのバイナリが v1 バージョンとして動作します。
サービス インスタンス グループ インスタンス サーバーフラグ
account account 2 --port=50053
--hostname_suffix="account"
stats stats 2 --port=50052
--hostname_suffix="stats"
--account_server="xds:///account.grpcwallet.io"
stats-premium stats-premium 2 --port=50052
--hostname_suffix="stats_premium"
--account_server="xds:///account.grpcwallet.io"
--premium_only=true
wallet-v1 wallet-v1 2 --port=50051
--hostname_suffix="wallet_v1"
--v1_behavior=true
--account_server="xds:///account.grpcwallet.io"
--stats_server="xds:///stats.grpcwallet.io"
wallet-v2 wallet-v2 2 --port=50051
--hostname_suffix "wallet_v2"
--account_server="xds:///account.grpcwallet.io"
--stats_server="xds:///stats.grpcwallet.io"

次に、以下のルーティング ルールに基づいて、テスト クライアントから上記のサービスにリクエストをルーティングするように Traffic Director を構成します。

ホスト 一致ルール ルート アクション
wallet.grpcwallet.io デフォルト wallet-v1
フルパス: /grpc.examples.wallet.Wallet/FetchBalance wallet-v1: 40%
wallet-v2: 60%
パス接頭辞: /grpc.examples.wallet.Wallet/ wallet-v2
stats.grpcwallet.io デフォルト stats
パス接頭辞: "/"
ヘッダー: {"membership": "premium"}
stats-premium
account.grpcwallet.io デフォルト account

gRPC ヘルスチェックとファイアウォール ルールの作成

このセクションでは、gRPC ヘルスチェック リクエストのネットワークへのアクセスを許可する gRPC ヘルスチェックとファイアウォール ルールを作成します。その後、gRPC ヘルスチェックはバックエンド サービスに関連付けられ、このバックエンド サービスのバックエンドの健全性が確認されます。

gcloud

  1. ヘルスチェックを作成します。

    gcloud compute health-checks create grpc grpcwallet-health-check \
      --use-serving-port
    
  2. ヘルスチェック用のファイアウォール ルールを作成します。

    gcloud compute firewall-rules create grpcwallet-allow-health-checks \
       --network default --action allow --direction INGRESS \
       --source-ranges 35.191.0.0/16,130.211.0.0/22 \
       --target-tags allow-health-checks \
       --rules tcp:50051-50053
    

インスタンス テンプレートの作成

このセクションでは、ポート 50053 で公開されている account gRPC サービスをデプロイするインスタンス テンプレートを作成します。

gcloud

  1. インスタンス テンプレートを作成します。

    gcloud compute instance-templates create grpcwallet-account-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=allow-health-checks \
      --image-family=debian-10 \
      --image-project=debian-cloud \
      --metadata-from-file=startup-script=<(echo '#! /bin/bash
    set -ex
    cd /root
    export HOME=/root
    sudo apt-get update -y
    curl -L https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples/archive/master.tar.gz | tar -xz
    cd traffic-director-grpc-examples-master/go/account_server/
    sudo apt-get install -y golang git
    go build .
    sudo systemd-run ./account_server --port 50053 --hostname_suffix account')
    

マネージド インスタンス グループの作成

マネージド インスタンス グループは、自動スケーリングを使用して必要に応じて新しいバックエンド VM を作成します。このセクションでは、前のセクションで作成したインスタンス テンプレートを使用してマネージド インスタンス グループを作成します。

gcloud

  1. インスタンス グループを作成します。

    gcloud compute instance-groups managed create grpcwallet-account-mig-us-central1 \
      --zone us-central1-a \
      --size=2 \
      --template=grpcwallet-account-template
    

名前付きポートの構成

このセクションでは、gRPC サービスの名前付きポートを構成します。名前付きポートとは、gRPC サービスがリクエストをリッスンするポートです。この例では、名前付きポートはポート 50053 です。

gcloud

  1. 名前付きポートを作成します。

    gcloud compute instance-groups set-named-ports grpcwallet-account-mig-us-central1 \
      --named-ports=grpcwallet-account-port:50053 \
      --zone us-central1-a
    

バックエンド サービスの作成

このセクションでは、INTERNAL_SELF_MANAGED とプロトコル GRPC の負荷分散方式でグローバル バックエンド サービスを作成し、バックエンド サービスにヘルスチェックとインスタンス グループを関連付けます。この例では、マネージド インスタンス グループの作成で作成したマネージド インスタンス グループを使用します。このマネージド インスタンス グループは、account gRPC サービスを実行します。--port-name フラグのポートは、名前付きポートの構成で作成した名前付きポートです。

gcloud

  1. バックエンド サービスを作成し、新しいバックエンド サービスにヘルスチェックを関連付けます。

    gcloud compute backend-services create grpcwallet-account-service \
        --global \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --protocol=GRPC \
        --port-name=grpcwallet-account-port \
        --health-checks grpcwallet-health-check
    
  2. マネージド インスタンス グループをバックエンドとして追加します。

    gcloud compute backend-services add-backend grpcwallet-account-service \
      --instance-group grpcwallet-account-mig-us-central1 \
      --instance-group-zone us-central1-a \
      --global
    

gRPC Wallet の例で使用される残りのバックエンド サービスを作成する手順は、上記の手順と同様です。シェル スクリプトを実行して残りのサービスを作成します。このスクリプトは、次のバックエンド サービスをデプロイします。

  • stats
  • stats-premium
  • wallet-v1
  • wallet-v2

追加のバックエンド サービスを作成するシェル スクリプトを実行します。

curl -O https://raw.githubusercontent.com/GoogleCloudPlatform/traffic-director-grpc-examples/master/scripts/create_service.sh
chmod +x ./create_service.sh

./create_service.sh go stats 50052 stats '--account_server="xds:///account.grpcwallet.io"'

./create_service.sh go stats 50052 stats-premium '--account_server="xds:///account.grpcwallet.io" --premium_only=true'

./create_service.sh java wallet 50051 wallet-v1 '--account_server="xds:///account.grpcwallet.io" --stats_server="xds:///stats.grpcwallet.io" --v1_behavior=true'

./create_service.sh java wallet 50051 wallet-v2 '--account_server="xds:///account.grpcwallet.io" --stats_server="xds:///stats.grpcwallet.io"'

ルーティング ルールの作成

このセクションでは、この例のサービスの仮想ホスト名と、関連するルーティング ルールを指定する URL マップを作成します。詳細については、ルーティング ルールマップをご覧ください。

URL マップでは、この例のサービスのホスト名を hostRules で指定します。このホスト名は、特定のサービスに接続するためにクライアントがチャネル URI で使用する名前です。たとえば、account サービスにリクエストを送信する場合は、クライアントがチャンネル URI で xds:///account.grpcwallet.io を使用します。hostRules に値 account.grpcwallet.io を指定した hosts エントリを構成する必要があります。

hosts エントリに関連付けられた pathMatcher は、その仮想ホストのすべてのルーティング ルールを含む pathMatcher の名前を指定します。pathMatcher 構成は、マッチング ルールと対応するアクション ルールで構成されます。この例では、次の構成になります。

  • リクエストが account.grpcwallet.io に送信された場合、そのリクエストは grpcwallet-account-service バックエンド サービスに送信されます。
  • リクエストが stats.grpcwallet.io に送信された場合、次のようになります。
    • リクエストに値が premium のヘッダー membership が含まれている場合、そのリクエストは grpcwallet-stats-premium-service バックエンド サービスに送信されます。
    • それ以外の場合は、リクエストはデフォルトのバックエンド サービス grpcwallet-stats-service に送信されます。
  • リクエストが wallet.grpcwallet.io に送信された場合、次のようになります。

    • ServiceName または MethodName が /grpc.examples.wallet.Wallet/FetchBalance と一致する場合、このようなリクエストの 40% が grpcwallet-wallet-v2-service バックエンド サービスに、残りのリクエストが grpcwallet-wallet-v1-service バックエンド サービスに送信されます。
    • それ以外の場合は、ServiceName/grpc.examples.wallet.Wallet/ と一致すれば、呼び出されたメソッドに関係なく、リクエストは grpcwallet-wallet-v1-service バックエンド サービスに送信されます。

gcloud

次のコマンドを実行して URL マップを作成します。

export PROJECT_ID=$(gcloud config list --format 'value(core.project)')

gcloud compute url-maps import grpcwallet-url-map << EOF
defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-account-service
name: grpcwallet-url-map
hostRules:
- hosts:
  - account.grpcwallet.io
  pathMatcher: grpcwallet-account-path-matcher
- hosts:
  - stats.grpcwallet.io
  pathMatcher: grpcwallet-stats-path-matcher
- hosts:
  - wallet.grpcwallet.io
  pathMatcher: grpcwallet-wallet-path-matcher
pathMatchers:
- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-account-service
  name: grpcwallet-account-path-matcher
- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-stats-service
  name: grpcwallet-stats-path-matcher
  routeRules:
  - matchRules:
    - prefixMatch: /
      headerMatches:
      - headerName: membership
        exactMatch: premium
    priority: 0
    service: projects/$PROJECT_ID/global/backendServices/grpcwallet-stats-premium-service
- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v1-service
  name: grpcwallet-wallet-path-matcher
  routeRules:
  - matchRules:
    - fullPathMatch: /grpc.examples.wallet.Wallet/FetchBalance
    priority: 0
    routeAction:
      weightedBackendServices:
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v2-service
        weight: 40
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v1-service
        weight: 60
  - matchRules:
    - prefixMatch: /grpc.examples.wallet.Wallet/
    priority: 1
    routeAction:
      weightedBackendServices:
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v2-service
        weight: 100
EOF

ターゲット プロキシと転送ルールの作成

このセクションでは、ターゲット gRPC プロキシと転送ルールを作成します。

ターゲット gRPC プロキシは、前の手順で作成した URL マップを参照します。--validate-for-proxyless フラグを指定すると、構成チェックが有効になり、プロキシレス gRPC デプロイと互換性のない機能が誤って有効にならないようにできます。

gcloud

  1. ターゲット gRPC プロキシを作成します。

    gcloud compute target-grpc-proxies create grpcwallet-proxy \
      --url-map grpcwallet-url-map \
      --validate-for-proxyless
    

作成したターゲット gRPC プロキシが転送ルールによって参照されます。負荷分散スキームが INTERNAL_SELF_MANAGED に設定され、この転送ルールが Traffic Director によって使用されていることを示します。これはグローバル転送ルールである必要があります。プロキシレス gRPC クライアントは、DNS ルックアップを実行する代わりに LDS リクエストを Traffic Director に送信することで、ターゲット URI で hostname:port を解決するため、IP アドレスは 0.0.0.0 に設定されます。詳細については、名前解決スキームをご覧ください。

ターゲット URI にポートが指定されていない場合、デフォルト値は 80 です。たとえば、ターゲット URI xds:///foo.myservice:8080 は、ポート 8080 を使用して構成された転送ルールと一致します。この例では、転送ルールはポート 80 を使用して構成されています。

gcloud

  1. 転送ルールを作成します。

    gcloud compute forwarding-rules create grpcwallet-forwarding-rule \
       --global \
       --load-balancing-scheme=INTERNAL_SELF_MANAGED \
       --address=0.0.0.0 --address-region=us-central1 \
       --target-grpc-proxy=grpcwallet-proxy \
       --ports 80 \
       --network default
    

構成の確認

構成プロセスが完了したら、Console の [Traffic Director] ページで、構成したバックエンド サービスが使用可能であることを確認します。バックエンド サービスと関連するバックエンドが正常であると報告されていることを確認します。

ルーティング構成の確認

このセクションでは、ルーティング構成が正しく機能していることを確認します。grpcurl ツールを使用して構成をテストします。

gcloud

  1. クライアントを実行するクライアント VM を作成し、サービスをテストします。

    gcloud compute instances create grpc-wallet-client \
      --zone us-central1-a \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --image-family=debian-10 \
      --image-project=debian-cloud \
      --metadata-from-file=startup-script=<(echo '#! /bin/bash
    set -e
    export GRPC_XDS_BOOTSTRAP=/run/td-grpc-bootstrap.json
    # Expose bootstrap variable to SSH connections
    echo export GRPC_XDS_BOOTSTRAP=$GRPC_XDS_BOOTSTRAP | sudo tee /etc/profile.d/grpc-xds-bootstrap.sh
    # Create the bootstrap file
    curl -L https://storage.googleapis.com/traffic-director/td-grpc-bootstrap-0.9.0.tar.gz | tar -xz
    ./td-grpc-bootstrap-0.9.0/td-grpc-bootstrap | tee $GRPC_XDS_BOOTSTRAP')
    
  2. SSH を使用して VM にアクセスします。

サイドカー プロキシなしでサービスにアクセスするには、gRPC クライアントが xds 名前解決スキームを使用する必要があります。このスキームは、クライアントで使用される gRPC ライブラリに、xDS サーバーを使用してホスト名を解決するように指示します。これを実行するには、ブートストラップの構成が必要です。前のセクションの起動スクリプトで GRPC_XDS_BOOTSTRAP 環境変数を設定し、ヘルパー スクリプトを使用してブートストラップ ファイルを生成します。生成されたブートストラップ ファイル内の TRAFFICDIRECTOR_GCP_PROJECT_NUMBERTRAFFICDIRECTOR_NETWORK_NAME、ゾーンの値は、Compute Engine VM インスタンスの詳細を把握しているメタデータ サーバーから取得されます。これらの値は、-gcp-project-number オプションと -vpc-network-name オプションを使用してヘルパー スクリプトに手動で指定できます。

grpcurl ツールを使用した構成の確認

まず、grpcurl ツールをインストールします。

curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.6.1/grpcurl_1.6.1_linux_x86_64.tar.gz | tar -xz
chmod +x grpcurl

続いて、次のコマンドを実行して、AccountStatsWallet の各サービスが実行されていることを確認します。

$ ./grpcurl -plaintext xds:///account.grpcwallet.io list
grpc.examples.wallet.account.Account
grpc.health.v1.Health
grpc.reflection.v1alpha.ServerReflection

$ ./grpcurl -plaintext -d '{"token": "2bd806c9"}' xds:///account.grpcwallet.io grpc.examples.wallet.account.Account/GetUserInfo
{
  "name": "Alice",
  "membership": "PREMIUM"
}

$ ./grpcurl -plaintext -H 'authorization:2bd806c9' -H 'membership:premium' xds:///stats.grpcwallet.io grpc.examples.wallet.stats.Stats/FetchPrice
{
  "price": "10295"
}

$ ./grpcurl -plaintext -H 'authorization:2bd806c9' -H 'membership:premium' -d '{"include_balance_per_address": true}' xds:///wallet.grpcwallet.io grpc.examples.wallet.Wallet/FetchBalance
{
  "balance": "5089953"
}

grpc-wallet クライアントによる確認

次の言語別の手順で構成を確認します。一連のコマンドで複数の RPC(追加のメタデータを含む)が送信され、URL マップのマッチング ルールに基づいてバックエンド サービスにリクエストがルーティングされます。リクエストがルーティングされたバックエンド サービスを示す各レスポンスのバックエンド ホスト名も出力されます。

C++

  1. gRPC C++ クライアントでサービスを確認するには、次のコマンドを実行します。

    sudo apt-get update
    sudo apt-get install -y build-essential git
    
    git clone https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    cd traffic-director-grpc-examples/cpp
    ../tools/bazel build :client
    
    # This command calls FetchBalance from the Wallet service in a loop, to demonstrate that
    # FetchBalance gets responses from wallet-v1 (40%) and wallet-v2 (60%).
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch=true
    
    # This command calls the streaming RPC WatchBalance from the Wallet
    # service. The RPC path matches the service prefix, so all requests are sent to wallet-v2.
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true
    
    # This command calls WatchPrice from the Stats service. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to stats-premium, and get faster responses. Alice's requests
    # always go to premium, and Bob goes to regular.
    ../bazel-bin/cpp/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Bob
    ../bazel-bin/cpp/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Alice
    

Go

  1. gRPC Go クライアントでサービスを確認するには、次のコマンドを実行します。

    sudo apt-get update
    sudo apt install -y golang git
    
    git clone https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    cd traffic-director-grpc-examples/go/wallet_client
    go build .
    
    # This command calls FetchBalance from the Wallet service in a loop,
    # to demonstrate that FetchBalance gets responses from wallet-v1 (40%)
    # and wallet-v2 (60%).
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch
    
    # This command calls the streaming RPC WatchBalance from the Wallet
    # service. The RPC path matches the service prefix, so all requests
    # are sent to wallet-v2.
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch
    
    # This command calls WatchPrice from the Stats service. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to stats-premium, and get faster responses. Alice's requests
    # always go to premium and Bob goes to regular.
    ./wallet_client price --stats_server="xds:///stats.grpcwallet.io" --watch --user=Bob
    ./wallet_client price --stats_server="xds:///stats.grpcwallet.io" --watch --user=Alice
    

Java

  1. gRPC Java クライアントでサービスを確認するには、次のコマンドを実行します。

    sudo apt-get update
    sudo apt-get install -y openjdk-11-jdk-headless git
    
    git clone https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    cd traffic-director-grpc-examples/java
    ./gradlew installDist
    
    # This command calls FetchBalance from the Wallet service in a loop,
    # to demonstrate that FetchBalance gets responses from wallet-v1 (40%)
    # and wallet-v2(60%).
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch=true
    
    # This command calls the streaming RPC WatchBalance from the Wallet
    # service. The RPC path matches the service prefix, so all requests are
    # sent to wallet-v2.
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true
    
    # This command calls WatchPrice from the Stats service. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to stats-premium, and get faster responses. Alice's requests
    # always go to premium and Bob goes to regular.
    ./build/install/wallet/bin/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Bob
    ./build/install/wallet/bin/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Alice
    

リソースのクリーンアップ

次のスクリプトを実行して、リソースをクリーンアップします。

bash <(curl -s https://raw.githubusercontent.com/GoogleCloudPlatform/traffic-director-grpc-examples/master/scripts/cleanup.sh)
gcloud compute instances delete grpc-wallet-client --zone us-central1-a -q

次のステップ

構成プロセス中に予期しない動作が発生した場合は、プロキシレスの Traffic Director のデプロイに関するトラブルシューティングプロキシレス gRPC アプリケーションに関する Traffic Director の制限事項をご覧ください。