このチュートリアルでは、コンテナ化されたウェブ アプリケーションを 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 を構成する
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_REGION
を us-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 \
--location=CONTROL_PLANE_LOCATION
次のように置き換えます。
CLUSTER_NAME
:hello-cluster
CONTROL_PLANE_LOCATION
: クラスタのコントロール プレーンの 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 に対する認証を行うようにクラスタを構成します。
クラスタにアクセスするための認証情報を取得します。
gcloud container clusters get-credentials CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION
次のように置き換えます。
CLUSTER_NAME
:hello-cluster
CONTROL_PLANE_LOCATION
:us-west1
これにより、クラスタの
kubectl
を指すように、適切な認証情報とエンドポイント情報でkubeconfig
ファイルが更新されます。Kubernetes サービス アカウントに使用する Namespace を作成します。デフォルトの Namespace を使用することも、既存の Namespace を使用することもできます。
kubectl create namespace NAMESPACE
NAMESPACE
は、作成する新しい Namespace の名前hello-namespace
に置き換えます。アプリケーションで使用する Kubernetes サービス アカウントを作成します。
kubectl create serviceaccount KSA_NAME \ --namespace NAMESPACE
次のように置き換えます。
KSA_NAME
:ksa-helloapp
。作成する新しい Kubernetes サービス アカウントの名前。NAMESPACE
:hello-namespace
アプリケーションの 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 CloudPROJECT_ID
は同じです。
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 プロジェクト IDGSA_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"
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 プロジェクト IDPROJECT_ID
: 実際の Google Cloud プロジェクト IDNAMESPACE
: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]"
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
をデプロイする準備が整いました。
GitHub リポジトリから Cloud Shell にサンプルアプリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
ターミナル ウィンドウのツールバーにある
[エディタを開く] をクリックして、Cloud Shell エディタを起動します。
詳しくはCloud Shell エディタのインターフェースの概要をご覧ください。
Cloud Shell エディタの [エクスプローラ] ペインを開き、
kubernetes-engine-samples/databases/hello-app-cloud-spanner/k8s
ディレクトリを参照します。deployment.yaml
ファイルを開き、<KSA_NAME>
を Kubernetes サービス アカウントの名前であるksa-helloapp
に置き換えてserviceAccountName
フィールドを更新します。図 1. デプロイ ファイル内の Kubernetes サービス アカウント名を更新する。 Cloud Shell エディタを閉じて、Cloud Shell ターミナルに戻ります。
Cloud Shell ターミナルで、
hello-app-cloud-spanner
ディレクトリに移動します。cd kubernetes-engine-samples/databases/hello-app-cloud-spanner
アプリケーションをデプロイします。
kubectl apply -f k8s/deployment.yaml -n=NAMESPACE
NAMESPACE
をhello-namespace
に置き換えます。STATUS
がRunning
の状態でアプリケーションがデプロイされるまで待ちます。kubectl get pods -n=NAMESPACE --watch
NAMESPACE
をhello-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
キーボードの Ctrl+C キーを押してコマンド プロンプトに戻り、その他のコマンドを実行します。
サンプルアプリをインターネットに公開する
クラスタの外部に Kubernetes Service を公開するには、LoadBalancer
タイプの Service を作成します。このタイプの Service では、インターネット経由で到達可能な Pod の外部ロードバランサ IP アドレスが生成されます。
ロードバランサをデプロイします。
kubectl apply -f k8s/service.yaml -n=NAMESPACE
NAMESPACE
をhello-namespace
に置き換えます。外部 IP アドレスが割り当てられることを確認します。
kubectl get service -n=NAMESPACE --watch
NAMESPACE
をhello-namespace
に置き換えます。割り当てたら、
EXTERNAL-IP
(203.0.113.0
など)をコピーして、ブラウザで開きます。プレーヤーのデータベースを表示、管理するためのウェブ インターフェースが開きます。アプリの 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