GKE Autopilot と Spanner を使用してアプリをデプロイする


このチュートリアルでは、コンテナ化されたウェブ アプリケーションを Google Kubernetes Engine(GKE)Autopilot クラスタにデプロイし、バックエンドで Google Spanner データベースを使用してデータを保存する方法について説明します。このサンプル アプリケーションはゲーム プレーヤーのテーブルを管理します。アプリのグラフィカル ユーザー インターフェース(GUI)を使用して、プレーヤーを追加または削除できます。

Spanner はフルマネージドで水平スケーリング可能なグローバルに分散されたリレーショナル データベース サービスで、パフォーマンスと高可用性を損なうことなく ACID トランザクションと SQL セマンティクスを提供します。

このページを読む前に、Kubernetes について理解しておいてください。

GKE と Spanner を選ぶ理由

デベロッパーは、アプリケーションに必要なストレージ リソースやコンピューティング リソースの確認、需要が変動する時間帯における RAM や CPU の消費量の予測、ピーク負荷時のアプリケーション障害の心配に時間を費やしたいとは思わないでしょう。

GKE Autopilot をフルマネージド Kubernetes サービスとして使用し、Spanner をフルマネージド データベース サービスとして使用すると、安定したインフラストラクチャ上でアプリを迅速に開発してデプロイできるため、リソースの構成と管理が簡単になります。GKE Autopilot は、ランタイムの要件に基づいてクラスタに対してノードを追加または削除することで、アプリをホストするためのインフラストラクチャの構成とスケーリングを行います。同様に、Spanner では、ストレージまたはコンピューティングの要件が変わったときに、手動での介入を最小限に抑えながら動的にスケールアウトおよびスケールインできます。

たとえば、大ヒットが期待される次のゲームをリリースするとして、その人気が急速に高まるとします。そのため、リリース期間中にウェブ トラフィックが大量に発生することになります。Spanner は、GKE Autopilot を使用してアプリケーションの最大可用性を維持しながら、コンピューティング リソースを瞬時に増加、減少、再割り当てする機能を提供して、この急激なスループットに対処します。

目標

このチュートリアルでは、以下の方法について学習します。

  • プレーヤーのレジストリを格納する Spanner データベースを作成する。

  • グラフィカル ユーザー インターフェースを使用して、hello-app-cloud-spanner というサンプル ウェブアプリをデプロイする。

次の表に、作成または使用する Google Cloud リソース、識別される変数、このチュートリアルで使用するために指定する値を示します。

リソース 変数
Google Cloud プロジェクト ID PROJECT_ID

プロジェクトの作成時に生成されたプロジェクト ID

例: my-gcp-project

コンピューティング リージョン COMPUTE_REGION

Spanner インスタンスと GKE クラスタを作成する Compute Engine のリージョン。ユーザーの地理的位置に最も近いリージョンを選択することをおすすめしますが、このチュートリアルでは us-west1 を使用します。

Spanner インスタンス - hello-instance
Spanner データベース - hello-database
GKE Autopilot クラスタ CLUSTER_NAME hello-cluster
Kubernetes Namespace NAMESPACE hello-namespace
Kubernetes サービス アカウント KSA_NAME ksa-helloapp
IAM サービス アカウント GSA_NAME gsa-helloapp
IAM サービス アカウントのプロジェクト ID GSA_PROJECT Google Cloud PROJECT_ID

このチュートリアルの目的上、新しいリソースを作成することをおすすめします。サンプルアプリをデプロイした後に簡単にリソースを削除でき、またリスクがありません。ただし、既存の Namespace、IAM サービス アカウント、Kubernetes サービス アカウントがある場合は、それらを使用できます。

費用

このドキュメントでは、課金対象である次の Google Cloudコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。

新規の Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

次の前提条件を満たしていることを確認してください。

プロジェクトの選択または作成

既存のプロジェクトを使用することも、このチュートリアル用の新しいプロジェクトを作成することもできます。

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. API を有効にする

  7. Enable the Artifact Registry, Compute Engine, GKE, and IAM Service Account Credentials APIs.

    Enable the APIs

  8. Cloud Shell を設定する

    このチュートリアルでは、Cloud Shell を使用して gcloud コマンドと kubectl コマンドを実行します。Cloud Shell は、 Google Cloudでホストされているリソースを管理するためのシェル環境です。Google Cloud CLIkubectl コマンドライン ツールがプリインストールされています。

  9. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  10. コンソールの下部にあるフレーム内で Cloud Shell セッションが開きます。

    このチュートリアルでコマンドを実行する前に、デフォルト プロジェクトがサンプルアプリをデプロイするプロジェクト ID に設定されていることを確認します。まだ設定していない場合は、Cloud Shell で次のコマンドを実行します。

    gcloud config set project PROJECT_ID
    

    PROJECT_ID を実際のプロジェクト ID に置き換えます。

    IAM ロールを付与する

    Google Cloud アカウントに、このチュートリアルに必要な IAM ロールがあることを確認します。

  11. Make sure that you have the following role or roles on the project: roles/iam.serviceAccountAdmin, roles/serviceusage.serviceUsageConsumer, roles/iam.serviceAccountUser, roles/iam.securityAdmin, roles/spanner.admin, roles/container.admin

    Check for the roles

    1. In the Google Cloud console, go to the IAM page.

      Go to IAM
    2. Select the project.
    3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

    4. For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.

    Grant the roles

    1. In the Google Cloud console, go to the IAM page.

      IAM に移動
    2. プロジェクトを選択します。
    3. [ アクセスを許可] をクリックします。
    4. [新しいプリンシパル] フィールドに、ユーザー ID を入力します。 これは通常、Google アカウントのメールアドレスです。

    5. [ロールを選択] リストでロールを選択します。
    6. 追加のロールを付与するには、 [別のロールを追加] をクリックして各ロールを追加します。
    7. [保存] をクリックします。
    8. Spanner を構成する

      Spanner を構成するには、Spanner インスタンスと Spanner データベースを作成する必要があります。

      Spanner インスタンスを作成する

      Spanner インスタンスとは、そのインスタンスで作成された Spanner データベースによって使用されるリソースの割り当てです。

      リージョン構成で hello-instance という Spanner インスタンスを作成し、100 処理単位のコンピューティング容量を計算します。

      gcloud spanner instances create hello-instance \
          --config=regional-COMPUTE_REGION \
          --description="Spanner sample instance" \
          --processing-units=100
      

      このチュートリアルでは、COMPUTE_REGIONus-west1 に置き換えます。

      Spanner データベースの作成

      Spanner データベースには、テーブル、ビュー、インデックスが含まれます。データベースは、構成(リージョンまたはマルチリージョン)、使用可能なコンピューティング容量、ストレージなどのプロパティを、親インスタンスから継承します。

      GoogleSQL 言語を使用して、Players というテーブルを持つ hello-database という名前の Spanner データベースを作成します。Cloud Shell で次のクエリを実行します。

      gcloud spanner databases create hello-database \
          --instance=hello-instance \
          --database-dialect=GOOGLE_STANDARD_SQL \
          --ddl="CREATE TABLE Players (
              PlayerUuid STRING(36) NOT NULL,
              FirstName STRING(1024),
              LastName STRING(1024),
              BirthDate DATE) PRIMARY KEY(PlayerUuid)"
      

      GKE Autopilot クラスタを作成する

      Spanner を構成したら、Autopilot クラスタを作成し、GKE 用 Workload Identity 連携を使用して、安全かつ管理しやすい方法でデータベースにアクセスします。

      hello-cluster という名前の Autopilot クラスタを作成します。Autopilot クラスタでは、GKE 用 Workload Identity 連携がデフォルトで有効になっています。

      gcloud container clusters create-auto CLUSTER_NAME \
        --region=COMPUTE_REGION
      

      次のように置き換えます。

      • CLUSTER_NAME: hello-cluster
      • COMPUTE_REGION: クラスタの Compute Engine のリージョン。このチュートリアルでは、Spanner インスタンスを作成したのと同じリージョン us-west1 を使用します。レイテンシを短縮するために、同じリージョン内に Spanner インスタンスと GKE Autopilot クラスタを作成することをおすすめします。

      クラスタの作成には最大 8~10 分かかることがあります。

      出力は次のようになります。

      NAME: hello-cluster
      LOCATION: us-west1
      MASTER_VERSION: 1.26.5-gke.1200
      MASTER_IP: 192.0.2.1
      MACHINE_TYPE: e2-medium
      NODE_VERSION: 1.26.5-gke.1200
      NUM_NODES: 3
      STATUS: RUNNING
      

      Workload Identity Federation for GKE を使用するようにクラスタを構成する

      アプリをデプロイする前に、Workload Identity Federation for GKE を使用して Google Cloud に対する認証を行うようにクラスタを構成します。

      1. クラスタにアクセスするための認証情報を取得します。

        gcloud container clusters get-credentials CLUSTER_NAME \
          --region=COMPUTE_REGION
        

        次のように置き換えます。

        • CLUSTER_NAME: hello-cluster
        • COMPUTE_REGION: us-west1

        これにより、クラスタの kubectl を指すように、適切な認証情報とエンドポイント情報で kubeconfig ファイルが更新されます。

      2. Kubernetes サービス アカウントに使用する Namespace を作成します。デフォルトの Namespace を使用することも、既存の Namespace を使用することもできます。

        kubectl create namespace NAMESPACE
        

        NAMESPACE は、作成する新しい Namespace の名前 hello-namespace に置き換えます。

      3. アプリケーションで使用する Kubernetes サービス アカウントを作成します。

        kubectl create serviceaccount KSA_NAME \
          --namespace NAMESPACE
        

        次のように置き換えます。

        • KSA_NAME: ksa-helloapp。作成する新しい Kubernetes サービス アカウントの名前。
        • NAMESPACE: hello-namespace
      4. アプリケーションの IAM サービス アカウントを作成します。

        gcloud iam service-accounts create GSA_NAME \
          --project=GSA_PROJECT
        

        次のように置き換えます。

        • GSA_NAME: gsa-helloapp。作成する新しい IAM サービス アカウントの名前。
        • GSA_PROJECT: 実際の Google Cloudプロジェクト ID。このチュートリアルでは、サンプルアプリをデプロイするのと同じ Google Cloud プロジェクトで IAM サービス アカウントを作成します。したがって、GSA_PROJECT とGoogle Cloud PROJECT_ID は同じです。
      5. IAM サービス アカウントの IAM ポリシー バインディングを追加して、Spanner に対する読み取りと書き込みを行います。

        gcloud projects add-iam-policy-binding PROJECT_ID \
          --member "serviceAccount:GSA_NAME@PROJECT_ID.iam.gserviceaccount.com" \
          --role "roles/spanner.admin"
        

        次のように置き換えます。

        • PROJECT_ID: 実際の Google Cloud プロジェクト ID
        • GSA_NAME: gsa-helloapp

        例:

        gcloud projects add-iam-policy-binding my-gcp-project \
          --member "serviceAccount:gsa-helloapp@my-gcp-project.iam.gserviceaccount.com" \
          --role "roles/spanner.admin"
      6. 2 つのサービス アカウントの間に IAM ポリシー バインディングを追加して、Kubernetes サービス アカウントが IAM サービス アカウントの権限を借用できるようにします。このバインドで、Kubernetes サービス アカウントが IAM サービス アカウントとして機能するようになるため、Kubernetes サービス アカウントが Spanner に対して読み書きを行うことができます。

        gcloud iam service-accounts add-iam-policy-binding GSA_NAME@GSA_PROJECT.iam.gserviceaccount.com \
          --role roles/iam.workloadIdentityUser \
          --member "serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]"
        

        次のように置き換えます。

        • GSA_NAME: gsa-helloapp
        • GSA_PROJECT: 実際の Google Cloud プロジェクト ID
        • PROJECT_ID: 実際の Google Cloud プロジェクト ID
        • NAMESPACE: hello-namespace
        • KSA_NAME: ksa-helloapp

        例:

        gcloud iam service-accounts add-iam-policy-binding gsa-helloapp@my-gcp-project.iam.gserviceaccount.com \
          --role roles/iam.workloadIdentityUser \
          --member "serviceAccount:my-gcp-project.svc.id.goog[hello-namespace/ksa-helloapp]"
      7. Kubernetes サービス アカウントに IAM サービス アカウントのメールアドレスでアノテーションを付けます。これにより、サンプルアプリが Google Cloud サービスへのアクセスに使用するサービス アカウントを認識できます。そのため、アプリが標準の Google API クライアント ライブラリを使用して Google Cloud サービスにアクセスする場合は、その IAM サービス アカウントを使用します。

        kubectl annotate serviceaccount KSA_NAME \
          --namespace NAMESPACE \
          iam.gke.io/gcp-service-account=GSA_NAME@GSA_PROJECT.iam.gserviceaccount.com
        

        次のように置き換えます。

        • KSA_NAME: ksa-helloapp
        • NAMESPACE: hello-namespace
        • GSA_NAME: gsa-helloapp
        • GSA_PROJECT: 実際の Google Cloud プロジェクト ID

        例:

        kubectl annotate serviceaccount ksa-helloapp \
          --namespace hello-namespace \
          iam.gke.io/gcp-service-account=gsa-helloapp@my-gcp-project.iam.gserviceaccount.com

      サンプルアプリをクラスタにデプロイする

      必要なサービスと認証を使用して GKE と Spanner を設定したので、サンプルアプリ hello-app-cloud-spanner をデプロイする準備が整いました。

      1. GitHub リポジトリから Cloud Shell にサンプルアプリのクローンを作成します。

        git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
        
      2. ターミナル ウィンドウのツールバーにある コードエディタ ボタン [エディタを開く] をクリックして、Cloud Shell エディタを起動します。

        詳しくはCloud Shell エディタのインターフェースの概要をご覧ください。

      3. Cloud Shell エディタの [エクスプローラ] ペインを開き、kubernetes-engine-samples/databases/hello-app-cloud-spanner/k8s ディレクトリを参照します。

      4. deployment.yaml ファイルを開き、<KSA_NAME> を Kubernetes サービス アカウントの名前である ksa-helloapp に置き換えて serviceAccountName フィールドを更新します。

        KSA_NAME を更新するように yaml を編集します。
        図 1. デプロイ ファイル内の Kubernetes サービス アカウント名を更新する。
      5. Cloud Shell エディタを閉じて、Cloud Shell ターミナルに戻ります。

      6. Cloud Shell ターミナルで、hello-app-cloud-spanner ディレクトリに移動します。

        cd kubernetes-engine-samples/databases/hello-app-cloud-spanner
        
      7. アプリケーションをデプロイします。

        kubectl apply -f k8s/deployment.yaml -n=NAMESPACE
        

        NAMESPACEhello-namespace に置き換えます。

      8. STATUSRunning の状態でアプリケーションがデプロイされるまで待ちます。

        kubectl get pods -n=NAMESPACE --watch
        

        NAMESPACEhello-namespace に置き換えます。

        出力は次のようになります。

        NAME                                       READY   STATUS              RESTARTS   AGE
        hello-app-cloud-spanner-765c9b8779-lfcrc   0/1     ContainerCreating   0          87s
        hello-app-cloud-spanner-765c9b8779-lfcrc   1/1     Running             0          3m15s
        
      9. キーボードの Ctrl+C キーを押してコマンド プロンプトに戻り、その他のコマンドを実行します。

      サンプルアプリをインターネットに公開する

      クラスタの外部に Kubernetes Service を公開するには、LoadBalancer タイプの Service を作成します。このタイプの Service では、インターネット経由で到達可能な Pod の外部ロードバランサ IP アドレスが生成されます。

      1. ロードバランサをデプロイします。

        kubectl apply -f k8s/service.yaml -n=NAMESPACE
        

        NAMESPACEhello-namespace に置き換えます。

      2. 外部 IP アドレスが割り当てられることを確認します。

        kubectl get service -n=NAMESPACE --watch
        

        NAMESPACEhello-namespace に置き換えます。

      3. 割り当てたら、EXTERNAL-IP203.0.113.0 など)をコピーして、ブラウザで開きます。プレーヤーのデータベースを表示、管理するためのウェブ インターフェースが開きます。

      4. アプリの GUI を使用してプレーヤー レコードを作成または削除できます。このプレーヤー レコードは Spanner データベースに保存されます。

        プレーヤーを追加または削除します。
        図 2. レジストリでプレーヤーを作成または削除する。

        次のクエリを実行して、Spanner データベースがエントリで更新されたかどうかを確認します。

        gcloud spanner databases execute-sql hello-database \
          --instance=hello-instance \
          --sql="SELECT * FROM Players LIMIT 10"
        

        出力は次のようになります。

        PlayerUuid: a1f34bbf-929c-498d-8b16-39bbb29d70e3
        FirstName: John
        LastName: Smith
        BirthDate: 1997-07-12
        
        PlayerUuid: d634e157-96ea-45f2-be3f-fb907ced188e
        FirstName: Jane
        LastName: Doe
        BirthDate: 2013-07-12
        

      クリーンアップ

      このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

      プロジェクトを削除する

      課金が発生しないようにする最も簡単な方法は、このチュートリアル用に作成したプロジェクトを削除することです。

    9. In the Google Cloud console, go to the Manage resources page.

      Go to Manage resources

    10. In the project list, select the project that you want to delete, and then click Delete.
    11. In the dialog, type the project ID, and then click Shut down to delete the project.
    12. プロジェクトを削除すると、クリーンアップが完了します。プロジェクトを削除していない場合は、GKE と Spanner のリソースを削除します。

      GKE リソースを削除する

      1. Service を削除します。これにより、Service に作成された Google Cloud ロードバランサの割り当てが解除されます。

        kubectl delete service hello-app-cloud-spanner -n=NAMESPACE
        

        NAMESPACEhello-namespace に置き換えます。

      2. GKE クラスタを削除します。これにより、クラスタを構成するリソース(コンピューティング インスタンス、ディスク、ネットワーク リソースなど)が削除されます。

        gcloud container clusters delete CLUSTER_NAME --region=COMPUTE_REGION
        

        次のように置き換えます。

        • CLUSTER_NAME: hello-cluster
        • COMPUTE_REGION: us-west1

      Spanner リソースを削除する

      1. Spanner データベースを削除します。

        gcloud spanner databases delete hello-database --instance=hello-instance
        
      2. Spanner インスタンスを削除します。

        gcloud spanner instances delete hello-instance
        

      次のステップ