Google Kubernetes Engine とプロキシレス gRPC サービスを設定する
このガイドでは、Google Kubernetes Engine、gRPC アプリケーション、Cloud Service Mesh に必要なロード バランシング コンポーネントを構成する方法について説明します。
このガイドの手順に進む前に、プロキシレス gRPC サービスで Cloud Service Mesh を設定する準備を確認してください。
概要
GKE とプロキシレス gRPC サービスで Cloud Service Mesh をセットアップするには、次の作業が必要です。
- GKE クラスタを準備します。
- gRPC サーバー アプリケーションを Kubernetes Service としてデプロイします。GKE のデプロイ仕様にアノテーションを付けて、サービスのネットワーク エンドポイント グループ(NEG)を自動的に作成します。
- NEG とその他の Google Cloud ロード バランシング コンポーネントを使用して Cloud Service Mesh を構成します。
- プロキシレス gRPC クライアント アプリケーションを使用してトラフィックを gRPC サーバー アプリケーションに送信することで、デプロイが正しく機能していることを確認する。
Cloud Service Mesh 用に GKE クラスタを構成する
このセクションでは、GKE クラスタを Cloud Service Mesh と連携できるようにする方法について説明します。
GKE クラスタの要件
GKE クラスタは次の要件を満たす必要があります。
- ネットワーク エンドポイント グループのサポートを有効にする必要があります。詳細と例については、スタンドアロン ネットワーク エンドポイント グループをご覧ください。スタンドアロンの NEG 機能は、Cloud Service Mesh の一般提供で利用できます。
- クラスタノード インスタンスのサービス アカウントには、Cloud Service Mesh API にアクセスするための権限が必要です。必要な権限の詳細については、Cloud Service Mesh API にアクセスするためのサービス アカウントの有効化をご覧ください。
- コンテナは、OAuth 認証で保護された Cloud Service Mesh API にアクセスできる必要があります。詳細については、ホスト構成をご覧ください。
GKE クラスタの作成
次の例では、us-central1-a zone
内に grpc-td-cluster
という GKE クラスタを作成する方法を示します。
Console
Google Cloud コンソールを使用してクラスタを作成するには、次の手順を行います。
Google Cloud コンソールで Google Kubernetes Engine のメニューに移動します。
[クラスタを作成] をクリックします。
標準クラスタ テンプレートを選択するか、ワークロードに適したテンプレートを選択します。
必要に応じて、テンプレートをカスタマイズします。次のフィールドに値を入力する必要があります。
- 名前: 「
grpc-td-cluster
」と入力します。 - ロケーション タイプ:
Zonal
- ゾーン:
us-central1-a
- ノードプール:
- 名前: 「
左側のメニューで、[default-pool] をクリックします。
[名前] を
grpc-td-cluster
に変更します。[サイズ] に、作成するノード数を入力します。ノードとそのリソース(ファイアウォール ルートなど)に使用できるリソース割り当てが必要です。
左側のメニューで [ノード] をクリックします。
[マシンの構成] の [マシン ファミリー] で、[コンピューティング最適化] をクリックします。
マシンタイプを選択します。マシンタイプごとの料金については、Compute Engine の料金のページをご覧ください。
[ネットワーキング] で、ネットワーク タグ
allow-health-checks
を追加します。左側のメニューで [セキュリティ] をクリックします。
[アクセス スコープ] で [すべての Cloud API に完全アクセス権を許可] を選択します。
[作成] をクリックします。
Google Cloud コンソールでクラスタを作成したら、クラスタとやり取りするように kubectl
を構成する必要があります。詳細については、kubeconfig
エントリの生成をご覧ください。
gcloud
クラスタを作成します。
gcloud container clusters create grpc-td-cluster \ --zone us-central1-a \ --scopes=https://www.googleapis.com/auth/cloud-platform \ --tags=allow-health-checks \ --enable-ip-alias
必要な GKE クラスタ権限の取得
次のコマンドを実行して、作成したクラスタに切り替えます。これにより、kubectl
は正しいクラスタを指すようになります。
gcloud
gcloud container clusters get-credentials grpc-td-cluster \ --zone us-central1-a
GKE サービスの構成
このセクションでは、Cloud Service Mesh と連携する GKE デプロイ仕様の準備方法について説明します。これは、NEG アノテーションを使用して GKE helloworld
サンプル サービスを構成するものです。
helloworld
サンプル サービスは、gRPC クライアントのリクエストに応じてメッセージを返す gRPC サーバー アプリケーションです。helloworld
サービスには特別な役割はありません。これはプロキシレス gRPC サービスではなく、任意の gRPC クライアントからのリクエストに応答できます。
「プロキシレス」が機能するのは、gRPC クライアント アプリケーションが Cloud Service Mesh に接続されて、helloworld
サービスについて学習し、helloworld
に関連付けられた Pod にトラフィックを送信できる場合のみです。これは、IP アドレスまたは DNS ベースの名前解決に依存しません。
NEG を使用して GKE サービスを構成する
Cloud Service Mesh で使用する GKE サービスを構成する最初のステップは、NEG を通じてサービスを公開することです。NEG で公開するには、各仕様に、公開するポートと一致する次のアノテーションが必要です。
... metadata: annotations: cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}'
このアノテーションは、サービスを初めてデプロイするときにスタンドアロンの NEG を作成します。この NEG には、Pod の IP アドレスとポートのエンドポイントが含まれています。詳細と例については、スタンドアロン ネットワーク エンドポイント グループをご覧ください。
次の例では、ポート 8080
で公開されている helloworld
Kubernetes Service をデプロイします。これは、サービスがクラスタに表示されるポートです。Pod 内の gRPC サービスが targetPort
50051
でリッスンしています。これは、リクエストの送信先の Pod のポートです。通常、便宜上、port
と targetPort
に同じ値が設定されますが、この例では、NEG のアノテーションで使用する正しい値を示ために異なる値を使用しています。
cat << EOF > grpc-td-helloworld.yaml apiVersion: v1 kind: Service metadata: name: helloworld annotations: cloud.google.com/neg: '{"exposed_ports":{"8080":{"name": "example-grpc-server"}}}' spec: ports: - port: 8080 name: helloworld protocol: TCP targetPort: 50051 selector: run: app1 type: ClusterIP --- apiVersion: apps/v1 kind: Deployment metadata: labels: run: app1 name: app1 spec: selector: matchLabels: run: app1 replicas: 2 template: metadata: labels: run: app1 spec: containers: - image: grpc/java-example-hostname:1.50.2 name: app1 ports: - protocol: TCP containerPort: 50051 EOF
kubectl apply -f grpc-td-helloworld.yaml
新しい helloworld
サービスが作成されたことを確認します。
kubectl get svc
kubectl get svc
の出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE helloworld ClusterIP 10.71.9.71 <none> 8080/TCP 41m [..skip..]
アプリケーション Pod が動作していることを確認します。
kubectl get pods
kubectl get pods
の出力は次のようになります。
NAME READY STATUS RESTARTS AGE app1-6db459dcb9-zvfg2 1/1 Running 0 6m app1-6db459dcb9-hlvhj 1/1 Running 0 6m [..skip..]
NEG 名が正しいことを確認します。
Console
ネットワーク エンドポイント グループのリストを表示するには、Google Cloud コンソールの [ネットワーク エンドポイント グループ] ページに移動します。example-grpc-server
という名前の NEG が表示されます。
[ネットワーク エンドポイント グループ] ページに移動
gcloud
# List the NEGs gcloud compute network-endpoint-groups list \ --filter "name=example-grpc-server" --format "value(name)" # Optionally examine the NEG gcloud compute network-endpoint-groups describe example-grpc-server \ --zone us-central1-a # Optionally examine the endpoint(s) contained gcloud compute network-endpoint-groups list-network-endpoints example-grpc-server \ --zone us-central1-a
ロード バランシング コンポーネントを使用した Cloud Service Mesh を構成する
このセクションでは、サービスの Google Cloud 負荷分散コンポーネントを構成する方法について説明します。これらのコンポーネントには、プロキシレス gRPC クライアントと GKE サービスとの通信を可能にする構成情報が含まれています。
以下の Cloud Service Mesh の構成例では、次のことを前提としています。
- NEG とその他のリソースはすべて、ゾーン
us-central1-a
の自動モードのデフォルト ネットワークに作成されます。 - Google Cloud CLI を使用する場合、クラスタの NEG 名は
example-grpc-server
になります。
ヘルスチェック、ファイアウォール ルール、バックエンド サービスの作成
このセクションでは、ヘルスチェックとヘルスチェック用のファイアウォール ルールを作成します。ヘルスチェックでは gRPC ヘルスチェック プロトコルを使用する必要があります。このファイアウォール ルールにより、ヘルスチェック プローブはデプロイメント内の VM に接続できます。--use-serving-port
ディレクティブは、ヘルスチェックで各エンドポイントに構成されているリスニング ポートを取得するために使用されます。
このファイアウォール ルールは、ネットワーク内におけるインスタンスへのヘルスチェックの受信接続を許可します。
このセクションでは、INTERNAL_SELF_MANAGED
とプロトコル GRPC
の負荷分散方式でグローバル バックエンド サービスを作成し、ヘルスチェックをバックエンド サービスに関連付けます。
詳細については、ヘルスチェックの作成をご覧ください。
gcloud
ヘルスチェックを作成します。
gcloud compute health-checks create grpc grpc-gke-helloworld-hc \ --use-serving-port
ファイアウォール ルールを作成します。
gcloud compute firewall-rules create grpc-gke-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
バックエンド サービスを作成します。
gcloud compute backend-services create grpc-gke-helloworld-service \ --global \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --protocol=GRPC \ --health-checks grpc-gke-helloworld-hc
バックエンド サービスにバックエンド NEG を追加します。
gcloud compute backend-services add-backend grpc-gke-helloworld-service \ --global \ --network-endpoint-group example-grpc-server \ --network-endpoint-group-zone us-central1-a \ --balancing-mode RATE \ --max-rate-per-endpoint 5
ルーティング ルール マップの作成
このセクションでは、URL マップ、パスマッチャー、ホストルールを作成して、ホスト名とパスに基づいてサービスのトラフィックをルーティングします。次の例では、サービス名として helloworld-gke
を使用しています。gRPC クライアントは、helloworld
サービスに接続するときに、ターゲット URI でこのサービス名を使用します。また、ターゲット gRPC プロキシと転送ルールを作成します。
詳細については、ルーティング ルールマップをご覧ください。
次の例では、サービス名 helloworld-gke
とポート 8000
を使用します。つまり、このサービスへの接続には、gRPC クライアントが xds:///helloworld-gke:8000
を使用する必要があり、URL マップにホストルール helloworld-gke:8000
を構成する必要があります。前のセクションの Kubernetes Service 仕様に示されているサービスポート 8080
は、Cloud Service Mesh では使用されません。これは、helloworld-gke:8000
が targetPort
50051
でリッスンしている NEG エンドポイントによって直接解決されるためです。通常、URL マップのホストルールのポートと Kubernetes Service 仕様の port
および targetPort
はすべて、便宜上同じ値に設定されますが、この例では port
は Cloud Service Mesh では使用されないことを示すために異なる値を使用しています。
gcloud
URL マップを作成します。
gcloud compute url-maps create grpc-gke-url-map \ --default-service grpc-gke-helloworld-service
パスマッチャーを作成します。
gcloud compute url-maps add-path-matcher grpc-gke-url-map \ --default-service grpc-gke-helloworld-service \ --path-matcher-name grpc-gke-path-matcher \ --new-hosts helloworld-gke:8000
ターゲット gRPC プロキシを作成します。
gcloud compute target-grpc-proxies create grpc-gke-proxy \ --url-map grpc-gke-url-map \ --validate-for-proxyless
転送ルールを作成します。
gcloud compute forwarding-rules create grpc-gke-forwarding-rule \ --global \ --load-balancing-scheme=INTERNAL_SELF_MANAGED \ --address=0.0.0.0 \ --target-grpc-proxy=grpc-gke-proxy \ --ports 8000 \ --network default
これで、Cloud Service Mesh は、URL マップで指定されたサービスの NEG のエンドポイント間でトラフィックを負荷分散するように構成されます。
構成の確認
構成プロセスが完了したら、プロキシレス gRPC クライアントを使用して helloworld
gRPC サーバーに到達できることを確認します。このクライアントは Cloud Service Mesh に接続して helloworld
サービス(grpc-gke-helloworld-service
バックエンド サービスを使用して Cloud Service Mesh で構成された)に関する情報を取得し、この情報を使用してトラフィックをサービスのバックエンドに送信します。
また、Google Cloud コンソールの Cloud Service Mesh セクションで構成済みのサービス helloworld-gke
に関する情報を確認し、バックエンドが正常であると報告されたかどうかも確認できます。
プロキシレス gRPC クライアントによる確認
次の例では、gRPC クライアントを異なる言語で、または grpcurl
ツールを使用して、Cloud Service Mesh がメッシュでトラフィックが正しくルーティングされていることを確認します。クライアント Pod を作成してから、シェルを開き、シェルから検証コマンドを実行します。
環境変数とブートストラップ ファイルの設定
クライアント アプリケーションには、ブートストラップ構成ファイルが必要です。ブートストラップ ファイルとファイル転送用のボリュームを生成する initContainer
を追加して、Kubernetes アプリケーションのデプロイ仕様を変更します。既存のコンテナを更新してファイルを探します。
アプリケーションのデプロイ仕様に、次の initContainer
を追加します。
initContainers: - args: - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: IfNotPresent name: grpc-td-init resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ volumes: - name: grpc-td-conf emptyDir: medium: Memory
アプリケーション コンテナの env
セクションを更新して、次の記述を含めます。
env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/
これは、クライアントの Kubernetes 仕様の完全な例です。
cat << EOF | kubectl apply -f - apiVersion: apps/v1 kind: Deployment metadata: labels: run: client name: sleeper spec: selector: matchLabels: run: client template: metadata: labels: run: client spec: containers: - image: openjdk:8-jdk imagePullPolicy: IfNotPresent name: sleeper command: - sleep - 365d env: - name: GRPC_XDS_BOOTSTRAP value: "/tmp/grpc-xds/td-grpc-bootstrap.json" resources: limits: cpu: "2" memory: 2000Mi requests: cpu: 300m memory: 1500Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/grpc-xds/ initContainers: - args: - --output - "/tmp/bootstrap/td-grpc-bootstrap.json" image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.16.0 imagePullPolicy: IfNotPresent name: grpc-td-init resources: limits: cpu: 100m memory: 100Mi requests: cpu: 10m memory: 100Mi volumeMounts: - name: grpc-td-conf mountPath: /tmp/bootstrap/ volumes: - name: grpc-td-conf emptyDir: medium: Memory EOF
デプロイの準備ができたら、クライアント Pod へのシェルを開きます。
kubectl exec -it $(kubectl get pods -o custom-columns=:.metadata.name \ --selector=run=client) -- /bin/bash
構成を確認するには、Pod シェルで適切な例を実行します。
Java
gRPC Java クライアントでサービスを確認するには:
gRPC Java の最新バージョンをダウンロードし、最新のパッチを適用して
xds-hello-world
クライアント アプリケーションをビルドします。curl -L https://github.com/grpc/grpc-java/archive/v1.37.0.tar.gz | tar -xz cd grpc-java-1.37.0/examples/example-xds ../gradlew --no-daemon installDist
クライアントの名前を
"world"
に指定し、サービス URI とポートとして"xds:///helloworld-gke:8000"
を実行します。./build/install/example-xds/bin/xds-hello-world-client "world" \ xds:///helloworld-gke:8000
Go
gRPC Go クライアントでサービスを確認するには:
gRPC Go の最新バージョンをダウンロードし、最新のパッチを適用して
xds-hello-world
クライアント アプリケーションをビルドします。apt-get update -y apt-get install -y golang git curl -L https://github.com/grpc/grpc-go/archive/v1.37.0.tar.gz | tar -xz cd grpc-go-1.37.0/examples/features/xds/client go get google.golang.org/grpc@v1.37.0 go build .
クライアントの名前を
"world"
に指定し、サービス URI とポートとして"xds:///helloworld-gke:8000"
を実行します。./client "world" xds:///helloworld-gke:8000
C++
gRPC C++ クライアントでサービスを確認するには:
gRPC C++ の最新バージョンをダウンロードし、最新のパッチを適用して
helloworld
クライアントのサンプルをビルドします。apt-get update -y apt-get install -y build-essential cmake git git clone --recurse-submodules -b v1.37.1 https://github.com/grpc/grpc cd grpc mkdir -p cmake/build pushd cmake/build cmake ../.. make make install popd mkdir -p third_party/abseil-cpp/cmake/build pushd third_party/abseil-cpp/cmake/build cmake ../.. make make install popd cd examples/cpp/helloworld mkdir -p cmake/build cd cmake/build/ cmake ../.. make
サービス URI とポートに「xds:///helloworld-gke:8000」を指定してクライアントを実行します。
./greeter_client --target=xds:///helloworld-gke:8000
grpcurl
grpcurl
ツールは、プロキシレス gRPC クライアントとして機能することもできます。この場合、grpcurl
は環境変数とブートストラップ情報を使用して Cloud Service Mesh に接続します。次に、grpc-gke-helloworld-service
バックエンド サービスを通じて Cloud Service Mesh で構成された helloworld
サービスについて学習します。
grpcurl
ツールを使用して構成を確認するには:
grpcurl
ツールをダウンロードしてインストールします。curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.8.1/grpcurl_1.8.1_linux_x86_64.tar.gz | tar -xz
サービス URI として xds:///helloworld-gke:8000 を指定し、サービス名とメソッドとして
helloworld.Greeter/SayHello
を指定して、grpcurl
ツールを実行します。SayHello
メソッドのパラメータは-d
オプションで渡します。./grpcurl --plaintext \ -d '{"name": "world"}' \ xds:///helloworld-gke:8000 helloworld.Greeter/SayHello
Python
gRPC Python クライアントでサービスを確認するには、次のコマンドを実行します。最新バージョンの gRPC を使用して最新のパッチを適用します。
apt-get update -y apt-get install python3-pip -y pip3 install virtualenv curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz cd grpc-1.37.1/examples/python/xds virtualenv venv -p python3 source venv/bin/activate pip install -r requirements.txt python client.py xds:///helloworld-gke:8000
Ruby
gRPC Ruby クライアントでサービスを確認するには、次のコマンドを実行します。最新バージョンの gRPC を使用して最新のパッチを適用します。
apt-get update -y apt-get install -y ruby-full gem install grpc curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz cd grpc-1.37.1/examples/ruby ruby greeter_client.rb john xds:///helloworld-gke:8000
PHP
gRPC PHP クライアントでサービスを確認するには、次のコマンドを実行します。最新バージョンの gRPC を使用して最新のパッチを適用します。
apt-get update -y apt-get install -y php7.3 php7.3-dev php-pear phpunit python-all zlib1g-dev git pecl install grpc curl -sS https://getcomposer.org/installer | php mv composer.phar /usr/local/bin/composer curl -L https://github.com/grpc/grpc/archive/v1.37.1.tar.gz | tar -xz cd grpc-1.37.1 export CC=/usr/bin/gcc ./tools/bazel build @com_google_protobuf//:protoc ./tools/bazel build src/compiler:grpc_php_plugin cd examples/php composer install ../../bazel-bin/external/com_google_protobuf/protoc --proto_path=../protos \ --php_out=. --grpc_out=. \ --plugin=protoc-gen-grpc=../../bazel-bin/src/compiler/grpc_php_plugin \ ../protos/helloworld.proto php -d extension=grpc.so greeter_client.php john xds:///helloworld-gke:8000
Node.js
gRPC Node.js クライアントでサービスを確認するには、次のコマンドを実行します。最新バージョンの gRPC を使用して最新のパッチを適用します。
apt-get update -y apt-get install -y nodejs npm curl -L https://github.com/grpc/grpc/archive/v1.34.0.tar.gz | tar -xz cd grpc-1.34.0/examples/node/xds npm install node ./greeter_client.js --target=xds:///helloworld-gke:8000
このような出力が表示されます。INSTANCE_HOST_NAME
は VM インスタンスのホスト名です。
Greetings: Hello world, from INSTANCE_HOST_NAME
これにより、プロキシレス gRPC クライアントが Cloud Service Mesh に接続され、xds の名前解決機能を使用して helloworld-gke
サービスのバックエンドについて学習されたことが検証されます。クライアントは、IP アドレスの把握や DNS 解決の実行なしに、サービスのバックエンドの 1 つに対してリクエストを送信しています。
次のステップ
- Cloud Service Mesh サービス セキュリティについて学習する。
- 高度なトラフィック管理について確認する。
- オブザーバビリティの設定方法について確認する。
- プロキシレスの Cloud Service Mesh のデプロイをトラブルシューティングする方法を確認する。