ノードの自動プロビジョニングを使用したマルチテナント GKE クラスタでのリソース使用量の最適化


このチュートリアルでは、ノードの自動プロビジョニングを使用してマルチテナントの Google Kubernetes Engine(GKE)クラスタをスケーリングする方法と、Workload Identity を使用して Cloud Storage バケットなどのリソースに対するテナント アクセスを制御する方法について説明します。このガイドは、デベロッパーとアーキテクトを対象としており、Kubernetes と GKE の基本的な知識があることを前提にしています。概要についての説明が必要な場合は、GKE の概要をご覧ください。

クラスタ マルチテナンシーは、多くの場合に、コストの削減、またはテナント間でのオペレーションを標準化することを目的として実装されます。コストの削減を全面的に実現するには、クラスタ リソースを効率的に使用できるようにクラスタのサイズを設定する必要があります。クラスタを自動スケーリングする場合は、追加するクラスタノードのサイズを適切なものにすることで、リソースの浪費を最小限に抑えることも必要です。

このチュートリアルでは、ノードの自動プロビジョニングを使用してクラスタをスケーリングします。ノードの自動プロビジョニングによって、クラスタ リソースの使用量を最適化し、それによって保留中のワークロードに最適なクラスタノードを追加することで費用を制御できます。

目標

  • ノードの自動プロビジョニングと Workload Identity を有効にした GKE クラスタを作成する。
  • マルチテナンシーに対応したクラスタを設定する。
  • ノードの自動プロビジョニングによって最適化されたサイズのノードが作成および破棄される方法を示すために、クラスタにジョブを送信する。
  • 各テナント用に専用のノードプールを作成するようにノードの自動プロビジョニングに指示するには、taint とラベルを使用します。
  • Workload Identity を使用して、Cloud Storage バケットなどのテナント固有のリソースへのアクセスを制御する。

費用

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

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

  1. Google Cloud アカウントにログインします。Google Cloud を初めて使用する場合は、アカウントを作成して、実際のシナリオでの Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
  2. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

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

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

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

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

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

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

    Cloud Shell をアクティブにする

    Google Cloud コンソールの下部で Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。Cloud Shell はシェル環境です。Google Cloud CLI がすでにインストールされており、現在のプロジェクトの値もすでに設定されています。セッションが初期化されるまで数秒かかることがあります。

  7. Cloud Shell で、GKE と Cloud Build API 用の API を有効にします。
    gcloud services enable container.googleapis.com \
        cloudbuild.googleapis.com
    

    このオペレーションには数分かかることがあります。

環境の準備

このセクションでは、このチュートリアルで必要なコードを取得し、チュートリアル全体を通して使用する値で環境を設定します。

  1. Cloud Shell で、このチュートリアルで使用する環境変数を定義します。

    export PROJECT_ID=$(gcloud config get-value project)
    
  2. このチュートリアル用のコードを格納する GitHub リポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/solutions-gke-autoprovisioning
    
  3. リポジトリ ディレクトリに移動します。

    cd solutions-gke-autoprovisioning
    
  4. Google プロジェクト ID を使用して、Kubernetes YAML のジョブ構成ファイルを更新します。

    sed -i "s/MY_PROJECT/$PROJECT_ID/" manifests/bases/job/base-job.yaml
    
  5. Cloud Build ジョブを送信してコンテナ イメージをビルドします。

    gcloud builds submit pi/ --tag gcr.io/$PROJECT_ID/generate-pi
    

    このイメージは、円周率の近似値を生成する Go プログラムです。このコンテナ イメージは後で使用します。

    Cloud Build がイメージをプロジェクトの Container Registry にエクスポートします。

GKE クラスタの作成

このセクションでは、ノードの自動プロビジョニングと Workload Identity を有効にした GKE クラスタを作成します。クラスタ作成プロセスの詳細は次のとおりです。

  • クラスタに CPU とメモリの上限を指定します。ノードの自動プロビジョニングでは、クラスタに対してノードを追加または削除する際に、これらの上限が考慮されます。詳細については、GKE ドキュメントのノード自動プロビジョニングの有効化をご覧ください。
  • 自動プロビジョニングされたノードプール内のノードで使用されるデフォルトのサービス アカウントとスコープを指定します。これらの設定を使用して、プロビジョニングされたノードのアクセス権限を制御できます。詳細については、GKE ドキュメントの自動プロビジョニングされたノードの ID のデフォルトの設定をご覧ください。
  • 使用率を優先する自動スケーリング プロファイルを設定します。このプロファイルは、未使用のリソースを最小限に抑えるためにクラスタをすぐにスケールダウンするようクラスタ オートスケーラーに指示します。これにより、バッチまたはジョブ中心のワークロードのリソースの効率性も向上します。この設定は、クラスタ内のすべてのノードプールに適用されます。
  • Workload Identity を有効にするには、ワークロード プールを指定します。

クラスタを作成するには:

  1. サービス アカウントを作成します。

    gcloud iam service-accounts create nap-sa
    

    このサービス アカウントは、自動プロビジョニングされたノードによって使用されます。

  2. Container Registry で使用されている Cloud Storage バケットからイメージを pull する権限を新しいサービス アカウントに付与します。

    gsutil iam ch \
        serviceAccount:nap-sa@$PROJECT_ID.iam.gserviceaccount.com:objectViewer \
        gs://artifacts.$PROJECT_ID.appspot.com
    
  3. ノードの自動プロビジョニングと Workload Identity を有効にした GKE クラスタを作成します。

    gcloud container clusters create multitenant \
        --release-channel=regular \
        --zone=us-central1-c \
        --num-nodes=2 \
        --machine-type=n1-standard-2 \
        --workload-pool=${PROJECT_ID}.svc.id.goog \
        --autoscaling-profile=optimize-utilization \
        --enable-autoprovisioning \
        --autoprovisioning-service-account=nap-sa@${PROJECT_ID}.iam.gserviceaccount.com \
        --autoprovisioning-scopes=\
    https://www.googleapis.com/auth/devstorage.read_write,\
    https://www.googleapis.com/auth/cloud-platform \
        --min-cpu 1 \
        --min-memory 1 \
        --max-cpu 50 \
        --max-memory 256 \
        --enable-network-policy \
        --enable-ip-alias
    
  4. デフォルトのクラスタ名とコンピューティング ゾーンを設定します。

    gcloud config set container/cluster multitenant
    gcloud config set compute/zone us-central1-c
    

マルチテナンシーに対応したクラスタの設定

マルチテナントの Software-as-a-Service(SaaS)アプリを実行する場合、通常はテナントを分離する必要があります。テナントを分離すると、不正使用されたテナントからの被害を最小限に抑えることができます。また、テナント間でクラスタ リソースを均等に割り当て、各テナントが使用しているリソース数を追跡することもできます。Kubernetes はテナント間の分離の完全な安全性を保証することはできませんが、特定のユースケースに対して十分と考えられる機能を備えています。GKE マルチテナンシー機能の詳細については、GKE ドキュメントの概要ベスト プラクティス ガイドをご覧ください。

サンプルアプリで、2 つのテナント、tenant1tenant2 を作成します。各テナントとその Kubernetes リソースをそれぞれ独自の名前空間に分離します。他の名前空間との通信を妨げて、テナントの分離を実現するシンプルなネットワーク ポリシーを作成します。後で、Node TaintsnodeSelector フィールドを使用して、異なるテナントの Pod が同じノードでスケジュールされないようにします。専用ノードでテナントのワークロードを実行することで、さらなる分離を指定できます。

Kustomize を使用して、クラスタに送信する Kubernetes マニフェストを管理します。Kustomize を使用すると、複数の目的のために YAML ファイルを組み合わせてカスタマイズできます。

  1. 名前空間、サービス アカウント、tenant1 のネットワーク ポリシー リソースを作成します。

    kubectl apply -k manifests/setup/tenant1
    

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

    namespace/tenant1-ns created
    serviceaccount/tenant1-ksa created
    networkpolicy.networking.k8s.io/tenant1-deny-from-other-namespaces created
    
  2. tenant2 のクラスタ リソースを作成します。

    kubectl apply -k manifests/setup/tenant2
    

ノードの自動プロビジョニングの動作を確認する

GKE クラスタは、1 つ以上のノードプールで構成されます。ノードプール内のすべてのノードは同じマシンタイプであるため、CPU とメモリの量は同じになります。ワークロード リソースの需要が変動する場合は、クラスタ内で異なるマシンタイプのノードプールを複数使用することでメリットが得られます。このように、クラスタ オートスケーラーは最も適切なタイプのノードを追加できます。これにより、リソースの効率が向上するだけでなく、コストも削減できます。ただし、多数のノードプールを維持すると、管理オーバーヘッドが増えます。また、専用ノードプールでテナント ワークロードを実行する際は、マルチテナント クラスタでは実用的ではない場合があります。

代わりに、ノードの自動プロビジョニングを使用してクラスタ オートスケーラーを拡張できます。ノードの自動プロビジョニングが有効になっていると、クラスタ オートスケーラーは保留中の Pod の仕様に基づいて、新しいノードプールを自動的に作成できます。結果として、クラスタ オートスケーラーは最も適切なタイプのノードを作成できますが、ユーザーが自身でノードプールを作成および管理する必要はありません。ノードの自動プロビジョニングを使用すると、クラスタは過剰なプロビジョニングを行うことなく効率的に自動スケーリングでき、それによって費用を削減できます。

さらに、保留中の Pod にワークロードの分離の制約がある場合、ノードの自動プロビジョニングにより、制約を満たすノードを作成できます。このようにして、ノードの自動プロビジョニングを使用して、単一のテナントのみが使用するノードプールを自動的に作成できます。

このセクションでは、さまざまなジョブをクラスタに送信して、ノードの自動プロビジョニングの動作を確認します。ジョブは、先ほど作成した generate-pi イメージを使用します。

シンプルなジョブの送信

まず、クラスタにシンプルなジョブを送信します。ジョブは、テナント固有の制約を指定していません。ジョブの CPU リクエストとメモリ リクエストを処理するのに十分な空きスペースがクラスタにあります。そのため、このジョブがデフォルトのノードプール内の既存のノードのいずれかにスケジュールされることが想定されます。追加のノードはプロビジョニングされません。

  1. クラスタ内のノードプールを一覧表示します。

    gcloud container node-pools list
    

    デフォルト プールが 1 つだけ表示されます。

  2. ジョブの構成をコンソールに出力します。

    kubectl kustomize manifests/jobs/simple-job/
    

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

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: pi-job
    spec:
    ...
    

    この構成では、Node Taints やセレクタは指定されません。

  3. ジョブを送信します。

    kubectl apply -k manifests/jobs/simple-job/
    
  4. クラスタ内のノードプールを監視します。

    watch -n 5 gcloud container node-pools list
    

    デフォルトのプールは引き続き 1 つです。新しいノードプールは作成されません。

  5. 約 30 秒後に Control+C を押してノードプールの監視を停止します。

  6. クラスタ内のノードを監視します。

    kubectl get nodes -w
    

    作成中の新しいノードは表示されません。

  7. 1 分間監視を行った後、Control+C を押して監視を停止します。

  8. クラスタ内のジョブを一覧表示します。

    kubectl get jobs --all-namespaces
    

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

    NAMESPACE   NAME     COMPLETIONS   DURATION   AGE
    default     pi-job   1/1           14s        21m
    

    Completions 列の値 1/1 は、合計 1 つのジョブのうち、1 つのジョブが完了したことを示しています。

テナント固有の制約があるジョブの送信

このセクションでは、別のジョブを送信して、ノードの自動プロビジョニングがワークロードの別の制約を満たしていることを確認します。ジョブの構成には、テナント固有のノードセレクタとテナント固有の容認機能が含まれます。ジョブは、セレクタの Key-Value ペアと一致するラベルを持つノードにのみスケジュール設定できます。容認機能は Node Taints と連携して動作します。これにより、ノードにスケジュール設定できるジョブの制限も行われます。ノードの自動プロビジョニングに関するベスト プラクティスは、ノードセレクタとワークロード分離用の容認機能の両方を含めることです。

セレクタの制約を満たすノードがないため、このジョブをデフォルトのノードプールにスケジュール設定できません。そのため、ノードの自動プロビジョニングにより、セレクタの要件を満たすノードラベルを持つ新しいノードプールが作成されます。ノードの自動プロビジョニングでは、ジョブ構成の許容範囲に一致するテナント固有の taint もノードに追加されます。一致する容認機能を備えた Pod のみをプール内のノードにスケジュール設定できます。これにより、テナント ワークロードの分離をさらに強化できます。

  1. クラスタ内のノードプールを一覧表示します。

    gcloud container node-pools list
    

    デフォルト プールが 1 つだけ表示されます。

  2. ジョブの構成をコンソールに出力します。

    kubectl kustomize manifests/jobs/one-tenant/
    

    この構成には、テナント固有のノードセレクタの要件と容認機能が含まれています。出力は次のようになります。

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: tenant1-pi-job
    spec:
    ...
    
  3. ジョブを送信します。

    kubectl apply -k manifests/jobs/one-tenant/
    
  4. クラスタ内のノードプールを監視します。

    watch -n 5 gcloud container node-pools list
    

    しばらくすると、新しいノードプールが表示されます。出力は次のようになります。

    NAME                            MACHINE_TYPE       DISK_SIZE_GB
    default-pool                    n1-standard-2      100
    nap-n1-standard-1-15jwludl      n1-standard-1      100
    

    ノードプール名の先頭には nap- が付きます。これは、ノードの自動プロビジョニングによって作成されたことを示します。ノードプール名には、プール内のノードのマシンタイプ(例: n1-standard-1)も含まれます。

  5. クラスタ内のノードを監視します。

    kubectl get nodes -w
    

    約 1 分後、新しいノードがリストに表示されます。ノード名には、nap- ノードプールの名前が含まれます。新しいノードのステータスは、最初は Not Ready ステータスになります。しばらくすると、新しいノードのステータスが Ready に変わります。これにより、ノードは保留中の作業を承認できるようになります。

  6. ノードの監視を停止するには、Control+C を押します。

  7. Node Taints を一覧表示します。

    kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
    

    新しいノードには、Key-Value ペア tenant: tenant1NoSchedule taint があることが確認できす。したがって、tenant: tenant1 に対応する容認機能を持つ Pod のみをノードにスケジュール設定できます。

  8. クラスタ内のジョブを監視します。

    kubectl get jobs -w --all-namespaces
    

    しばらくすると、tenant1-pi-job1/1 完了となります。これは、正常に完了したことを示しています。

  9. ジョブの監視を停止するには、Control+C を押します。

  10. クラスタ内のノードプールを監視します。

    watch -n 5 gcloud container node-pools list
    

    しばらくすると、nap- プールが削除され、クラスタのデフォルト ノードプールが再び 1 つのみになったことを確認できます。ノードの自動プロビジョニングによって nap- ノードプールが削除されました。これは、プールの制約に一致する保留中の作業がなくなったためです。

  11. ノードプールの監視を停止するには、Control+C を押します。

テナントに関連した制約のある 2 つの大規模なジョブを送信する

このセクションでは、テナント固有の制約を持つ 2 つのジョブを送信し、各ジョブのリソース リクエストも増やします。ここでもノードセレクタの制約により、これらのジョブはデフォルトのノードプールにスケジュール設定できません。各ジョブには独自のセレクタ制約があるため、ノードの自動プロビジョニングによって 2 つの新しいノードプールが作成されます。このようにすると、ノードの自動プロビジョニングを使用してテナントジョブを分離した状態で保持できます。ジョブには前のジョブよりも多数のリソース リクエストがあるため、ノードの自動プロビジョニングによって前回のジョブより大きなマシンタイプのノードプールが作成されます。

  1. クラスタ内のノードプールを一覧表示します。

    gcloud container node-pools list
    

    デフォルト プールが 1 つだけ表示されます。

  2. 結合された構成を出力します。

    kubectl kustomize manifests/jobs/two-tenants/
    

    この構成には 2 つの個別のジョブがあり、それぞれにテナント固有のノードセレクタと許容値が設定され、リソース リクエストが増分されています。

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

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: tenant1-larger-pi-job
    spec:
    ...
    
  3. ジョブを送信します。

    kubectl apply -k manifests/jobs/two-tenants/
    
  4. クラスタ内のノードプールを監視します。

    watch -n 5 gcloud container node-pools list
    

    しばらくすると、2 つのノードプールが追加されます。出力は次のようになります。

    NAME                            MACHINE_TYPE       DISK_SIZE_GB
    default-pool                    n1-standard-2      100
    nap-n1-standard-2-6jxjqobt      n1-standard-2      100
    nap-n1-standard-2-z3s06luj      n1-standard-2      100
    

    ノードプール名には、ノードの自動プロビジョニングによって作成されたことを示す nap- という接頭辞が付きます。ノードプール名には、プール内のノードのマシンタイプ(例: n1-standard-2)も含まれます。

  5. ノードの監視を停止するには、Control+C を押します。

  6. クラスタ内のノードを監視します。

    kubectl get nodes -w
    

    約 1 分後、2 つのノードがリストに表示されます。ノード名には、関連付けられている nap- ノードプールの名前が含まれます。新しいノードのステータスは、最初は Not Ready になります。しばらくすると、新しいノードのステータスが Ready に変わります。これにより、ノードが保留中の作業を受け入れられるようになります。

  7. ノードの監視を停止するには、Control+C を押します。

  8. Node Taints を一覧表示します。

    kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
    

    新しいノードには NoSchedule taint があり、1 つは Key-Value ペア tenant: tenant1 で、もう 1 つは tenant: tenant2 であることを確認できます。対応するテナントの容認機能を備えた Pod のみをノードにスケジュール設定できます。

  9. クラスタ内のジョブを監視します。

    kubectl get jobs -w --all-namespaces
    

    しばらくすると、tenant1-larger-pi-jobtenant2-larger-pi-job がそれぞれ 1/1 完了に変わったことを確認できます。これは、ジョブが正常に完了したことを示します。

  10. ジョブの監視を停止するには、Control+C を押します。

  11. クラスタ内のノードプールを監視します。

    watch -n 5 gcloud container node-pools list
    

    しばらくすると、両方の nap- プールが削除され、再度クラスタのデフォルト ノードプールが 1 つのみになったことを確認できます。ノードの自動プロビジョニングによって nap- ノードプールが削除されました。これは、プールの制約に一致する保留中の作業がなくなったためです。

  12. ノードプールの監視を停止するには、Control+C を押します。

Google Cloud リソースへのアクセス制御

クラスタ内のテナントを分離した状態で保持することに加えて、通常は、Cloud Storage バケットや Pub/Sub トピックなどの Google Cloud リソースへのテナント アクセスを制御する必要があります。たとえば、各テナントで他のテナントからアクセスできるように設定できない Cloud Storage バケットが必要になる場合があります。

Workload Identity を使用すると、Kubernetes サービス アカウントと Google Cloud サービス アカウント間のマッピングを作成できます。その後、適切な Identity and Access Management(IAM)ロールを Google Cloud サービス アカウントに割り当てることができます。これにより、最小権限の原則が適用され、テナントのジョブは割り当てられたリソースにアクセスできますが、他のテナントが所有するリソースにはアクセスできません。

GKE Workload Identity を設定する

Kubernetes サービス アカウントと作成する Google Cloud サービス アカウントのマッピングを構成します。

  1. tenant1 の Google Cloud サービス アカウントを作成します。

    gcloud iam service-accounts create tenant1-gsa
    
  2. tenant1 の Kubernetes サービス アカウントに IAM 権限を付与し、tenant1 に対応する Google Cloud サービス アカウントを使用できるようにします。

    gcloud iam service-accounts add-iam-policy-binding \
        tenant1-gsa@${PROJECT_ID}.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:${PROJECT_ID}.svc.id.goog[tenant1-ns/tenant1-ksa]"
    
  3. Google Cloud サービス アカウントで Kubernetes サービス アカウントにアノテーションを付けて、サービス アカウント間のマッピングを完了します。

    kubectl annotate serviceaccount tenant1-ksa -n tenant1-ns \
        iam.gke.io/gcp-service-account=tenant1-gsa@${PROJECT_ID}.iam.gserviceaccount.com
    

Cloud Storage バケットへの書き込みを行うジョブを送信する

このセクションでは、特定の Kubernetes サービス アカウントとして実行されるジョブで、マッピングされた Google Cloud サービス アカウントの IAM 権限を使用できることを確認します。

  1. tenant1 の新しい Cloud Storage バケットを作成します。

    export BUCKET=tenant1-$PROJECT_ID
    gsutil mb -b on -l us-central1 gs://$BUCKET
    

    一意の名前にするには、バケット名に対してプロジェクト ID をサフィックスとして使用します。

  2. Cloud Storage バケットを使用するように、ジョブの構成ファイルを更新します。

    sed -i "s/MY_BUCKET/$BUCKET/" \
        manifests/jobs/write-gcs/bucket-write.yaml
    
  3. tenant1 サービス アカウントにバケット内のオブジェクトへの読み取りと書き込みを行う権限を付与します。

    gsutil iam ch \
        serviceAccount:tenant1-gsa@$PROJECT_ID.iam.gserviceaccount.com:objectAdmin \
        gs://$BUCKET
    
  4. ジョブ構成を出力します。

    kubectl kustomize manifests/jobs/write-gcs/
    

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

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: tenant1-pi-job-gcs
    spec:
    ...
    

    新しいバケット名は引数として generate-pi コンテナに渡され、ジョブは適切な tenant1-ksa Kubernetes サービス アカウントを指定します。

  5. ジョブを送信します。

    kubectl apply -k manifests/jobs/write-gcs/
    

    前のセクションと同様に、ノードの自動プロビジョニングによって、新しいノードプールと、ジョブを実行する新しいノードが作成されます。

  6. ジョブの Pod を監視します。

    kubectl get pods -n tenant1-ns -w
    

    この場合は、ノードプールではなく Pod を監視します。Pod がさまざまなステータスに移行します。数分後、ステータスが Completed に変わります。このステータスは、ジョブが正常に完了したことを示します。

  7. 監視を停止するには、Control+C を押します。

  8. ファイルが Cloud Storage バケットに書き込まれていることを確認します。

    gsutil ls -l gs://$BUCKET
    

    1 つのファイルが表示されます。

  9. クリーンアップするには、ジョブを削除します。

    kubectl delete job tenant1-pi-job-gcs -n tenant1-ns
    

    このジョブは、次のセクションで再度送信します。

IAM 権限の取り消し

最後に、Google Cloud サービス アカウントから IAM 権限を取り消して、マッピングされた Kubernetes サービス アカウントが Cloud Storage バケットにアクセスできなくなったことを確認します。

  1. Cloud Storage バケットに書き込みを行う Google Cloud サービス アカウントの権限を取り消します。

    gsutil iam ch -d \
        serviceAccount:tenant1-gsa@$PROJECT_ID.iam.gserviceaccount.com:objectAdmin \
        gs://$BUCKET
    
  2. 前と同じジョブを送信します。

    kubectl apply -k manifests/jobs/write-gcs/
    
  3. ジョブの Pod のステータスをもう一度確認します。

    kubectl get pods -n tenant1-ns -w
    

    数分後、ステータスが Error に変わります。これは、ジョブが失敗したことを示します。ジョブが Google Cloud サービス アカウントにマッピングされる Kubernetes サービス アカウントとして実行され、Cloud Storage バケットへの書き込み権限がなくなったため、これは予想されるエラーです。

  4. Pod の監視を停止するには、Control+C を押します。

  5. バケット内のファイルを一覧表示します。

    gsutil ls -l gs://$BUCKET
    

    バケットには単一のファイルが表示されます。新しいファイルは書き込まれていません。

クリーンアップ

課金を停止する最も簡単な方法は、チュートリアル用に作成した Google Cloud プロジェクトを削除することです。

プロジェクトを削除する

  1. Google Cloud コンソールで、[リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

GKE クラスタの削除

プロジェクトを削除しない場合は、GKE クラスタを削除します。

gcloud container clusters delete multitenant

次のステップ