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. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  3. Google Cloud プロジェクトで課金が有効になっていることを確認します

  4. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  5. Google Cloud プロジェクトで課金が有効になっていることを確認します

API を有効にする

Artifact Registry, Compute Engine, GKE, and IAM Service Account Credentials API を有効にします。

API を有効にする

Cloud Shell を設定する

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

Google Cloud コンソールで、「Cloud Shell をアクティブにする」をクリックします。

Cloud Shell をアクティブにする

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

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

gcloud config set project PROJECT_ID

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

IAM ロールを付与する

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

Google アカウントにロールを付与します。次の IAM ロールごとに次のコマンドを 1 回実行します。 roles/iam.serviceAccountAdmin, roles/serviceusage.serviceUsageConsumer, roles/iam.serviceAccountUser, roles/iam.securityAdmin, roles/spanner.admin, roles/container.admin

$ gcloud projects add-iam-policy-binding PROJECT_ID --member="user:EMAIL_ADDRESS" --role=ROLE
  • PROJECT_ID は、実際のプロジェクト ID に置き換えます。
  • EMAIL_ADDRESS は実際のメールアドレスに置き換えます。
  • ROLE は、個々のロールに置き換えます。

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

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

アプリをデプロイする前に、GKE 用 Workload Identity 連携を使用して 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 アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

プロジェクトを削除する

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

Delete a Google Cloud project:

gcloud projects delete PROJECT_ID

プロジェクトを削除すると、クリーンアップが完了します。プロジェクトを削除していない場合は、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
    

次のステップ