ESP を使用した Kubernetes 用 Endpoints のスタートガイド

このチュートリアルでは、Google Cloud上で稼働していない Kubernetes クラスタに、Extensible Service Proxy(ESP)を使用して、単純な gRPC サービスをデプロイする方法を説明します。このチュートリアルでは、bookstore-grpc サンプルの Python 版を使用しています。他の言語の gRPC サンプルについては、次のステップ セクションをご覧ください。

このチュートリアルでは、事前にビルドしたサンプルコードと ESP のコンテナ イメージを使用します。これらは、Artifact Registry に保存されています。コンテナをまだよく理解していない場合は、次の情報をご覧ください。

Cloud Endpoints の概要については、Endpoints についてEndpoints アーキテクチャをご覧ください。

Endpoints を構成する

bookstore-grpc サンプルには、ローカルにコピーして構成する必要のあるファイルが含まれています。

  1. サービスの .proto ファイルから、自己完結型 protobuf 記述子ファイルを作成します。
    1. サンプル リポジトリから、bookstore.proto のコピーを保存します。このファイルは Bookstore サービスの API を定義します。
    2. 次のコマンドでディレクトリを作成します。mkdir generated_pb2
    3. protoc プロトコル バッファ コンパイラを使用して、記述子ファイル api_descriptor.pb を作成します。bookstore.proto を保存したディレクトリで次のコマンドを実行します。
      python -m grpc_tools.protoc \
          --include_imports \
          --include_source_info \
          --proto_path=. \
          --descriptor_set_out=api_descriptor.pb \
          --python_out=generated_pb2 \
          --grpc_python_out=generated_pb2 \
          bookstore.proto

      上記のコマンドでは、--proto_path が現在の作業ディレクトリに設定されています。gRPC ビルド環境で、.proto 入力ファイルに別のディレクトリを使用する場合は、bookstore.proto を保存したディレクトリをコンパイラが検索するように --proto_path を変更します。

  2. gRPC API 構成 YAML ファイルを作成します。
    1. api_config.yaml ファイルのコピーを保存します。このファイルは、Bookstore サービスの gRPC API 構成を定義します。
    2. api_config.yaml ファイルの MY_PROJECT_ID は、実際のプロジェクト ID に置き換えます。 Google Cloud 次に例を示します。
      #
      # Name of the service configuration.
      #
      name: bookstore.endpoints.example-project-12345.cloud.goog
      

      このファイルの apis.name フィールド値は、.proto ファイルの完全修飾 API 名と完全に一致させる必要があります。一致しなければ、デプロイは機能しません。Bookstore サービスは、パッケージ endpoints.examples.bookstore 内の bookstore.proto で定義されています。この完全修飾 API 名は、api_config.yaml ファイルと同じように endpoints.examples.bookstore.Bookstore になります。

      apis:
        - name: endpoints.examples.bookstore.Bookstore

詳細については、Endpoints を構成するをご覧ください。

Endpoints 構成をデプロイする

Endpoints の構成をデプロイするには、gcloud endpoints services deploy コマンドを使用します。このコマンドは、Google の基礎的なサービス プラットフォームである Service Infrastructure を使用します。このプラットフォームは、Endpoints やその他のサービスで API やサービスを作成、管理するために使用されます。

  1. api_descriptor.pb ファイルと api_config.yaml ファイルがあるディレクトリにいることを確認します。
  2. gcloud コマンドライン ツールが現在使用しているデフォルト プロジェクトが、エンドポイント構成をデプロイするプロジェクトであることを確認します。 Google Cloud それには、次のコマンドを使用して返されるプロジェクト ID を確認してください。これは、間違ったプロジェクト内にサービスが作成されないようにするためです。
    gcloud config list project
    

    デフォルト プロジェクトを変更する必要がある場合は、次のコマンドを実行します。

    gcloud config set project YOUR_PROJECT_ID
    
  3. Google Cloud CLI を使用して、proto descriptor ファイルと構成ファイルをデプロイします。
    gcloud endpoints services deploy api_descriptor.pb api_config.yaml
    

    サービスが作成され構成されるに従い、ターミナルには Service Management からの情報が出力されます。デプロイが完了すると、次のようなメッセージが表示されます。

    Service Configuration [CONFIG_ID] uploaded for service [bookstore.endpoints.example-project.cloud.goog]

    CONFIG_ID は、デプロイによって作成される一意の Endpoints サービス構成 ID です。例:

    Service Configuration [2017-02-13r0] uploaded for service [bookstore.endpoints.example-project.cloud.goog]
    

    上記の例では、2017-02-13r0 はサービス構成 ID で、bookstore.endpoints.example-project.cloud.goog はサービス名です。サービス構成 ID は、日付スタンプとそれに続くリビジョン番号で構成されます。Endpoints の構成を同じ日に再デプロイすると、サービス構成 ID のリビジョン番号が増分されます。

必要なサービスの確認

Endpoints と ESP を使用するには、少なくとも次の Google サービスの有効化が必要です。
名前 タイトル
servicemanagement.googleapis.com Service Management API
servicecontrol.googleapis.com Service Control API

ほとんどの場合、gcloud endpoints services deploy コマンドによってこれらの必須サービスが有効化されます。ただし、以下の状況では、gcloud コマンドは正常に完了しますが、必須サービスが有効になりません。

  • Terraform などのサードパーティのアプリケーションを使用していて、上記のサービスを含めていない場合。

  • 上記のサービスが明示的に無効にされている既存のGoogle Cloud プロジェクトに Endpoints 構成をデプロイした場合。

必要なサービスが有効になっていることを確認するには、次のコマンドを実行します。

gcloud services list

必要なサービスが表示されない場合は、次のコマンドを使用してサービスを有効にします。

gcloud services enable servicemanagement.googleapis.com
gcloud services enable servicecontrol.googleapis.com

Endpoints サービスも有効にします。

gcloud services enable ENDPOINTS_SERVICE_NAME

ENDPOINTS_SERVICE_NAME を確認するには、次のいずれかを行います。

  • Endpoints 構成をデプロイ後、Cloud コンソールの [Endpoints] ページに移動します。[サービス名] 列に、考えられる ENDPOINTS_SERVICE_NAME のリストが表示されます。

  • OpenAPI の場合、ENDPOINTS_SERVICE_NAME は OpenAPI 仕様の host フィールドで指定したものです。gRPC の場合、ENDPOINTS_SERVICE_NAME は gRPC Endpoints 構成の name フィールドで指定したものです。

gcloud コマンドの詳細については、gcloud サービスをご覧ください。

エラー メッセージが表示された場合は、Endpoints 構成のデプロイのトラブルシューティングをご覧ください。

詳しくは、Endpoints 構成をデプロイするをご覧ください。

サービスの認証情報を作成する

API を管理するには、ESP と ESPv2 のどちらにも Service Infrastructure のサービスが必要です。これらのサービスを呼び出すには、ESP と ESPv2 ではアクセス トークンを使用する必要があります。ESP または ESPv2 を Google Cloud 環境(GKE や Compute Engine など)にデプロイする場合、ESP と ESPv2 は Google Cloud メタデータ サービスを通じてアクセス トークンを取得します。

ローカル デスクトップ、オンプレミスの Kubernetes クラスタ、別のクラウド プロバイダなど、Google Cloud 以外の環境に ESP または ESPv2 をデプロイする場合は、秘密鍵を含むサービス アカウントの JSON ファイルを指定する必要があります。ESP と ESPv2 は、サービス アカウントを使用してアクセス トークンを生成し、API の管理に必要なサービスを呼び出します。

Google Cloud コンソールまたは Google Cloud CLI を使用して、サービス アカウントと秘密鍵ファイルを作成できます。

コンソール

  1. Google Cloud コンソールで、[サービス アカウント] ページを開きます。

    [サービス アカウント] ページに移動

  2. [プロジェクトの選択] をクリックします。
  3. API が作成されたプロジェクトを選択し、[開く] をクリックします。
  4. [+ サービス アカウントを作成] をクリックします。
  5. [サービス アカウント名] 項目に、サービス アカウントの名前を入力します。
  6. [作成] をクリックします。
  7. [続行] をクリックします。
  8. [完了] をクリックします。
  9. 新しく作成したサービス アカウントのメールアドレスをクリックします。
  10. [キー] をクリックします。
  11. [鍵を追加]、[新しい鍵を作成] の順にクリックします。
  12. [作成] をクリックします。JSON キーファイルがパソコンにダウンロードされます。

    鍵ファイルは、サービス アカウントとしての認証で使用できるため、安全な場所に保管してください。このファイルは任意の場所に移動できます。名前の変更も可能です。

  13. [閉じる] をクリックします。

gcloud

  1. 次のコマンドを入力して、Google Cloud プロジェクトのプロジェクト ID を表示します。

    gcloud projects list
  2. 次のコマンドの PROJECT_ID の部分を API が含まれているプロジェクトに置き換えて、デフォルトのプロジェクトに設定します。

    gcloud config set project PROJECT_ID
  3. Google Cloud CLI(gcloud)が、 Google Cloudにある対象のデータとサービスへのアクセスが許可されていることを確認します。

    gcloud auth login

    アカウントが複数ある場合は、API が含まれている Google Cloud プロジェクトのアカウントを選択してください。gcloud auth list を実行すると、選択したアカウントがプロジェクトの有効なアカウントとして表示されます。

  4. サービス アカウントを作成するには、次のコマンドを実行します。このとき、SERVICE_ACCOUNT_NAMEMy Service Account は、使用する名前と表示名に置き換えます。

    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
       --display-name "My Service Account"

    このコマンドは、サービス アカウントのメールアドレスを次の形式で割り当てます。

    SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

    このメールアドレスは、後で実行するコマンドで必要になります。

  5. サービス アカウントのキーファイルを作成します。

    gcloud iam service-accounts keys create ~/service-account-creds.json \
       --iam-account SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com

必要な IAM ロールを追加する

このセクションでは、ESP と ESPv2 で使用される IAM リソースと、これらのリソースにアクセスするために接続されたサービス アカウントに必要な IAM ロールについて説明します。

エンドポイント サービスの構成

ESP と ESPv2 は、エンドポイント サービス構成を使用する Service Control を呼び出します。エンドポイント サービスの構成は IAM リソースであり、ESP と ESPv2 にはサービス コントローラ ロールが必要です。

IAM ロールは、プロジェクトではなく、エンドポイント サービスの構成に対するものです。1 つのプロジェクトには、複数のエンドポイント サービス構成が存在する場合があります。

次の gcloud コマンドを使用して、エンドポイント サービス構成の接続されたサービス アカウントにロールを追加します。

gcloud endpoints services add-iam-policy-binding SERVICE_NAME \
  --member serviceAccount:SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com \
  --role roles/servicemanagement.serviceController

ここで、
* SERVICE_NAME は、エンドポイント サービス名です。
* SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com は、接続されたサービス アカウントです。

Cloud Trace

ESP と ESPv2 は Cloud Trace サービスを呼び出して、Trace をプロジェクトにエクスポートします。このプロジェクトはトレース プロジェクトと呼ばれます。ESP では、トレース プロジェクトと、エンドポイント サービス構成を有するプロジェクトは同じです。ESPv2 では、トレース プロジェクトはフラグ --tracing_project_id で指定できます。デフォルトはデプロイ プロジェクトです。

ESP と ESPv2 では、Cloud Trace を有効にするために、Cloud Trace エージェント ロールが必要です。

次の gcloud コマンドを使用して、接続されたサービス アカウントにロールを追加します。

gcloud projects add-iam-policy-binding TRACING_PROJECT_ID \
  --member serviceAccount:SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.com \
  --role roles/cloudtrace.agent

ここで、
* TRACING_PROJECT_ID は、トレース プロジェクト ID です。
* SERVICE_ACCOUNT_NAME@DEPLOY_PROJECT_ID.iam.gserviceaccount.comは、接続されたサービス アカウントです。詳細については、ロールと権限についてをご覧ください。

コマンドの詳細については、gcloud iam service-accounts をご覧ください。

API バックエンドをデプロイする

ここまでの手順でサービス構成を Service Management にデプロイしましたが、API バックエンドを処理するコードはまだデプロイされていません。ここでは、サンプル API と ESP 用のビルド済みコンテナを Kubernetes にデプロイする手順を説明します。

ESP にサービス認証情報を提供する

コンテナ内で実行される ESP は、service-account-creds.jsonファイルにローカルに保存されている認証情報にアクセスする必要があります。ESP から認証情報にアクセスできるようにするには、Kubernetes Secret を作成し、その Kubernetes Secret を Kubernetes ボリュームとしてマウントします。

Kubernetes シークレットを作成してボリュームをマウントするには:

  1. Google Cloud コンソールを使用してサービス アカウントを作成した場合は、JSON ファイルの名前を service-account-creds.json に変更します。そのファイルを api_descriptor.pbapi_config.yaml ファイルが配置されているディレクトリに移動します。

  2. サービス アカウントの認証情報を使用して Kubernetes Secretを作成します。

     kubectl create secret generic service-account-creds
          --from-file=service-account-creds.json

    成功すると、secret "service-account-creds" created というメッセージが表示されます。

API と ESP を Kubernetes にデプロイするために使用するデプロイメント マニフェスト ファイルには、Secret ボリュームがすでに含まれています。これは、ファイルの以下の 2 つのセクションに示されています。

volumes:
  - name: service-account-creds
    secret:
      secretName: service-account-creds
volumeMounts:
  - mountPath: /etc/nginx/creds
    name: service-account-creds
    readOnly: true

サービス名を構成してサービスを開始する

ESP では、gcloud endpoints services deploy コマンドを使用して以前にデプロイされた構成を見つけるために、サービスの名前を知る必要があります。

サービス名を構成してサービスを開始するには:

  1. デプロイメント マニフェスト ファイル k8s-grpc-bookstore.yaml のコピーを service-account-creds.json と同じディレクトリに保存します。

  2. k8s-grpc-bookstore.yaml を開き、SERVICE_NAME を Endpoints サービスの名前に置き換えます。これは、api_config.yaml ファイルの name フィールドで構成した名前と同じです。

    containers:
      - name: esp
        image: gcr.io/endpoints-release/endpoints-runtime:1
        args: [
          "--http2_port=9000",
          "--service=SERVICE_NAME",
          "--rollout_strategy=managed",
          "--backend=grpc://127.0.0.1:8000",
          "--service_account_key=/etc/nginx/creds/service-account-creds.json"
        ]

    --rollout_strategy=managed オプションを指定すると、デプロイ済みの最新のサービス構成を使用するように ESP が構成されます。このオプションを指定すると、新しいサービス構成をデプロイしてから 5 分以内に ESP が変更を検出し、自動的に使用します。ESP が特定の構成 ID でなく、このオプションを使用するようにしてください。ESP 引数の詳細については、ESP 起動オプションをご覧ください。

  3. サービスを開始して、Kubernetes にサービスをデプロイします。

    kubectl create -f k8s-grpc-bookstore.yaml

    次のようなエラー メッセージが表示される場合があります。

    The connection to the server localhost:8080 was refused - did you specify the right host or port?

    これは、kubectl が正しく構成されていないことを示しています。詳細については、kubectl を構成するをご覧ください。

サービスの外部 IP アドレスを取得する

サンプル API にリクエストを送信するには、サービスの外部 IP アドレスが必要です。コンテナでサービスを開始してから外部 IP アドレスを確認できるまで数分かかる場合があります。

  1. 外部 IP アドレスを表示します。

    kubectl get service

  2. EXTERNAL-IP の値をメモし、サンプル API へのリクエストの送信時に使われる SERVER_IP 環境変数にそれを保存します。

    export SERVER_IP=YOUR_EXTERNAL_IP
    

API にリクエストを送信する

サンプル API にリクエストを送信するには、Python で作成された gRPC クライアントを使用できます。

  1. gRPC クライアント コードがホストされる git リポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
       

  2. 作業ディレクトリに移動します。

    cd python-docs-samples/endpoints/bookstore-grpc/
      

  3. 依存関係をインストールします。

    pip install virtualenv
    virtualenv env
    source env/bin/activate
    python -m pip install -r requirements.txt

  4. サンプル API にリクエストを送信します。

    python bookstore_client.py --host SERVER_IP --port 80
    

正常なレスポンスが返されない場合は、レスポンス エラーのトラブルシューティングをご覧ください。

これで Endpoints の API のデプロイとテストが完了しました。