Pod スナップショットの準備をする

Google Kubernetes Engine(GKE)Pod スナップショットを使用すると、実行中の Pod の状態を保存して復元し、ワークロードの起動レイテンシを改善できます。ワークロードのスナップショットをキャプチャする前に、クラスタとストレージ環境を準備する必要があります。

このドキュメントでは、クラスタで Pod スナップショットを有効にして構成する方法と、スナップショットを保存するように Cloud Storage を設定する方法について説明します。Pod スナップショットの仕組みの詳細については、GKE Pod スナップショットについてをご覧ください。

プラットフォーム管理者、オペレーター、アプリケーション デベロッパーは、このドキュメントを使用して、クラスタの構成、ストレージ バケットの作成、Pod スナップショットのアクセス権の設定を行うことができます。 Google Cloud のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。

始める前に

作業を始める前に、次のタスクが完了していることを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API を有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化します。gcloud CLI をインストール済みの場合は、gcloud components update コマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。

Pod スナップショットを有効にする

Pod スナップショットは、新規または既存のクラスタで有効にできます。Pod スナップショットには、GKE Sandbox と Workload Identity Federation for GKE が必要です。Autopilot クラスタでは、両方の機能がデフォルトで有効になります。Standard クラスタの場合、クラスタで Workload Identity Federation for GKE を有効にし、GKE Sandbox で実行するようにノードプールを構成する必要があります。

クラスタで Pod スナップショットを有効にするには、使用する GKE オペレーション モードの手順に沿って操作します。

Autopilot

  • 新しいクラスタで Pod スナップショットを有効にするには、次のコマンドを実行します。

      gcloud container clusters create-auto CLUSTER_NAME \
          --enable-pod-snapshots \
          --location=CONTROL_PLANE_LOCATION \
          --cluster-version=CLUSTER_VERSION
    

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

    • CLUSTER_NAME: クラスタの名前。
    • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。
    • CLUSTER_VERSION: 新しいクラスタのバージョン。1.35.3-gke.1234000 以降にする必要があります。
  • 既存のクラスタで Pod スナップショットを有効にするには、次の操作を行います。

    1. クラスタをバージョン 1.35.3-gke.1234000 以降にアップグレードします。

        gcloud container clusters upgrade CLUSTER_NAME \
            --cluster-version=CLUSTER_VERSION \
            --location=CONTROL_PLANE_LOCATION
      

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

      • CLUSTER_NAME: クラスタの名前。
      • CLUSTER_VERSION: クラスタのアップグレード先のバージョン。1.35.3-gke.1234000 以降にする必要があります。
      • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。
    2. クラスタで Pod スナップショットを有効にします。

        gcloud container clusters update CLUSTER_NAME \
            --enable-pod-snapshots \
            --location=CONTROL_PLANE_LOCATION
      

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

      • CLUSTER_NAME: クラスタの名前。
      • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。

デフォルトの whole-pod スコープを使用する Pod スナップショットは、E2 マシンタイプをサポートしていませんが、ファイル システム スナップショット(rootfs-only)はサポートしています。Autopilot クラスタでは、GKE はデフォルトで E2 ノードに Pod をスケジュールすることがあります。whole-pod スコープを使用する場合は、ComputeClass カスタム リソースを使用して、ワークロードが互換性のあるハードウェアで実行されるようにします。

ComputeClass カスタム リソースを作成して使用する手順は次のとおりです。

  1. 次のマニフェストを non-e2-class.yaml として保存します。

      apiVersion: cloud.google.com/v1
      kind: ComputeClass
      metadata:
        name: non-e2-class
      spec:
        priorities:
        - machineFamily: n2
        - machineFamily: c3
        activeMigration:
          optimizeRulePriority: false
        whenUnsatisfiable: DoNotScaleUp
    
  2. 次のようにマニフェストを適用します。

      kubectl apply -f non-e2-class.yaml
    
  3. Pod 仕様で、cloud.google.com/compute-class ノードセレクタを使用して ComputeClass カスタム リソースを参照します。

      spec:
        nodeSelector:
          cloud.google.com/compute-class: non-e2-class
        # Multiple lines are omitted here
    

Standard

  • 新しいクラスタで Pod スナップショットを有効にするには、次のコマンドを実行します。

      gcloud container clusters create CLUSTER_NAME \
          --enable-pod-snapshots \
          --cluster-version=CLUSTER_VERSION \
          --workload-pool=PROJECT_ID.svc.id.goog \
          --workload-metadata=GKE_METADATA \
          --location=CONTROL_PLANE_LOCATION
    

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

    • CLUSTER_NAME: クラスタの名前。
    • CLUSTER_VERSION: 新しいクラスタのバージョン。1.35.3-gke.1234000 以降にする必要があります。
    • PROJECT_ID: プロジェクト ID。
    • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。
  • 既存のクラスタで Pod スナップショットを有効にするには、次の操作を行います。

    1. クラスタをバージョン 1.35.3-gke.1234000 以降にアップグレードします。

        gcloud container clusters upgrade CLUSTER_NAME \
            --node-pool=NODE_POOL_NAME \
            --cluster-version=CLUSTER_VERSION \
            --location=CONTROL_PLANE_LOCATION
      

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

      • CLUSTER_NAME: クラスタの名前。
      • NODE_POOL_NAME: ノードプールの名前。
      • CLUSTER_VERSION: クラスタのアップグレード先のバージョン。1.35.3-gke.1234000 以降にする必要があります。
      • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。
    2. クラスタで Pod スナップショットを有効にします。

        gcloud beta container clusters update CLUSTER_NAME \
            --enable-pod-snapshots \
            --location=CONTROL_PLANE_LOCATION
      

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

      • CLUSTER_NAME: クラスタの名前。
      • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。

Standard クラスタの GKE Sandbox で Pod を実行するには、GKE Sandbox が有効になっているノードプールを作成または更新する必要があります。ノードプールを更新するには、--sandbox type=gvisor フラグを使用します。GKE Sandbox を有効にしてノードプールを作成するには、次のコマンドを実行します。

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --node-version=NODE_VERSION \
    --machine-type=MACHINE_TYPE \
    --location=CONTROL_PLANE_LOCATION \
    --image-type=cos_containerd \
    --sandbox type=gvisor

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

  • NODE_POOL_NAME: 新しいノードプールの名前。
  • CLUSTER_NAME: クラスタの名前。
  • NODE_VERSION: ノードプールに使用するバージョン。
  • MACHINE_TYPE: ノードに使用するマシンのタイプ。
  • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。

GKE Sandbox の詳細については、GKE Sandbox によるワークロード分離の強化をご覧ください。

スナップショットを保存する

GKE は、Pod スナップショットを Cloud Storage バケットに保存します。各スナップショットには、アプリケーション メモリと、必要に応じて Pod の GPU 状態が含まれます。Cloud Storage に対する認証を行うために、Pod スナップショットは Pod の ServiceAccount オブジェクトを使用します。これには Workload Identity Federation for GKE が必要です。

Pod スナップショットには、次のバケット構成が必要です。

  • 階層型名前空間: 読み取りと書き込みの秒間クエリ数を増やすには、階層型名前空間を有効にする必要があります。階層型名前空間では、均一なバケットレベルのアクセスも有効にする必要があります。
  • 削除(復元可能): Pod スナップショットは並列複合アップロードを使用するため、削除(復元可能)などのデータ保護機能を無効にします。これらの機能を有効のままにしておくと、一時オブジェクトの削除(復元可能)によりストレージの請求額が大幅に増加する可能性があります。
  • ロケーション: スナップショットが異なるリージョン間で転送されるとパフォーマンスに影響する可能性があるため、Cloud Storage バケットのロケーションは GKE クラスタと同じにする必要があります。

必要な構成でバケットを作成するには、次のコマンドを実行します。

gcloud storage buckets create gs://BUCKET_NAME \
    --uniform-bucket-level-access \
    --enable-hierarchical-namespace \
    --soft-delete-duration=0d \
    --location=LOCATION

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

  • BUCKET_NAME: バケットの名前。
  • LOCATION: バケットのロケーション。

バケットの作成オプションの完全なリストについては、buckets create コマンドのドキュメントのフラグをご覧ください。

Cloud Storage バケットへのアクセス権をワークロードに付与する

デフォルトでは、GKE には Cloud Storage へのアクセス権がありません。Pod スナップショットの読み取りと書き込みを行うには、ワークロード Pod が使用する Kubernetes ServiceAccount オブジェクトに対応する権限を含む IAM ロールを付与するか、有効期間の短いトークンを使用してマルチテナンシーを有効にする必要があります。

特定の Kubernetes ServiceAccount オブジェクトにロールを付与する

特定の Kubernetes ServiceAccount オブジェクトにロールを付与する手順は次のとおりです。

  1. kubectl コマンドを使用してクラスタと通信するには、クラスタの認証情報を取得します。

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

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

    • CLUSTER_NAME: クラスタの名前。
    • CONTROL_PLANE_LOCATION: クラスタのコントロール プレーンのロケーション。
  2. Pod ごとに、次の操作を行います。

    1. ServiceAccount オブジェクトを作成します。

      kubectl create serviceaccount SERVICEACCOUNT_NAME \
          --namespace=NAMESPACE
      

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

      • SERVICEACCOUNT_NAME: ServiceAccount オブジェクトの名前。
      • NAMESPACE: Pod の名前空間。
    2. ServiceAccount オブジェクトにバケットへのアクセス権を付与します。セキュリティ要件に応じて、次のいずれかのオプションを選択します。

      • 標準権限: 読み取り、書き込み、削除の完全なアクセス権を付与します。
      • 1 回限りの書き込み権限: 確定したスナップショット ファイルの上書きや削除を防止しますが、並列複合アップロードの一時オブジェクトを削除する権限を付与します。

      権限を付与するには、選択したオプションのコマンドを実行します。

      標準権限

      gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
          --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \
          --role="roles/storage.bucketViewer"
      
      gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
          --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \
          --role="roles/storage.objectUser"
      

      1 回限りの書き込み権限

      gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
          --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \
          --role="roles/storage.bucketViewer"
      
      gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
          --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \
          --role="roles/storage.objectCreator"
      
      gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
          --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \
          --role="roles/storage.objectViewer"
      
      gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
          --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \
          --role="roles/storage.objectUser" \
          --condition='expression=resource.type == "storage.googleapis.com/Object" && (resource.name.extract("/pages.img_{part}") != "" || resource.name.extract("/fs_checkpoint_pages.img_{part}") != ""),title=allow_pcu_temp_part_cleanup,description=Allow deleting temporary parallel composite upload part objects only'
      

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

      • BUCKET_NAME: バケットの名前。
      • PROJECT_NUMBER: プロジェクトの番号。
      • PROJECT_ID: プロジェクト ID。
      • NAMESPACE: Pod の名前空間。
      • SERVICEACCOUNT_NAME: ServiceAccount オブジェクトの名前。

有効期間の短いトークンを使用してマルチテナンシーを有効にする

個々の ServiceAccount オブジェクトに権限を付与する代わりに、有効期間が短く、スコープが制限されたトークンを使用してマルチテナンシーを有効にできます。このアプローチにより、手動の IAM バインディングに関連する伝播遅延を回避できます。各 ServiceAccount オブジェクトに権限を付与する代わりに、スナップショット ストレージ バケットに対するストレージ管理者ロール(roles/storage.admin)を GKE ノード サービス アカウントに 1 回付与します。ノードのサービス アカウントは、特定のパスに対して有効期間の短いトークンをオンデマンドで作成します。

Pod スナップショットでトークンを有効にするには、GKE バージョン 1.35.3-gke.1737000 以降が必要です。

マルチテナンシーを有効にする手順は次のとおりです。

  1. ノード サービス アカウントにバケットの使用権限を付与するには、次のコマンドを実行します。

    gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
        --member="serviceAccount:service-PROJECT_NUMBER@gcp-sa-gkenode.iam.gserviceaccount.com" \
        --role="roles/storage.admin"
    

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

    • BUCKET_NAME: バケットの名前。
    • PROJECT_NUMBER: プロジェクトの番号。
  2. スナップショットのストレージを構成する場合は、tokenSource フィールドの値を federatedP4SA に設定します。

Pod スナップショット コントローラに Cloud Storage バケットへのアクセス権を付与する

Pod スナップショット コントローラが Cloud Storage バケット内のスナップショットを削除できるようにするには、プロジェクトの GKE サービス エージェントに Storage オブジェクト ユーザーロール(roles/storage.objectUser)を付与する必要があります。ロールを付与するには、次のコマンドを実行します。

gcloud projects add-iam-policy-binding PROJECT_ID \
    --member="serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com" \
    --role="roles/storage.objectUser" \
    --condition="expression=resource.name.startsWith(\"projects/_/buckets/BUCKET_NAME\"),title=restrict_to_bucket,description=Restricts access to one bucket only"

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

  • PROJECT_ID: プロジェクト ID。
  • PROJECT_NUMBER: プロジェクトの番号。
  • BUCKET_NAME: バケットの名前。

省略可: Cloud Storage バケットのマネージド フォルダを作成する

相互に信頼できない Pod からスナップショットの権限を分離するには、マネージド フォルダを作成します。これは、マルチテナントのユースケースで役立ちます。マネージド フォルダを設定する手順は次のとおりです。

  1. Pod スナップショットに必要な権限のみを含むカスタム IAM ロールを作成します。選択したオプションのコマンドを実行します。

    標準権限

    gcloud iam roles create podSnapshotGcsReadWriter \
        --project=PROJECT_ID \
        --permissions="storage.objects.get,storage.objects.list,storage.objects.create,storage.objects.delete,storage.folders.create"
    

    1 回限りの書き込み権限

    gcloud iam roles create podSnapshotGcsReadWriter \
        --project=PROJECT_ID \
        --permissions="storage.objects.get,storage.objects.list,storage.objects.create,storage.folders.create"
    

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

  2. ターゲット Namespace 内のすべての ServiceAccount オブジェクトに Storage バケット閲覧者ロール(roles/storage.bucketViewer)を付与します。このロールを使用すると、ServiceAccount オブジェクトはバケット メタデータを読み取りますが、バケット内のオブジェクトに対する読み取り権限や書き込み権限は付与されません。

    gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
        --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/namespace/NAMESPACE" \
        --role="roles/storage.bucketViewer"
    

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

    • BUCKET_NAME: バケットの名前。
    • PROJECT_NUMBER: プロジェクトの番号。
    • PROJECT_ID: プロジェクト ID。
    • NAMESPACE: Pod の名前空間。
  3. Pod スナップショットを保存する必要がある ServiceAccount オブジェクトごとに、次の操作を行います。

    1. ServiceAccount オブジェクトのマネージド フォルダを作成します。

      gcloud storage managed-folders create gs://BUCKET_NAME/FOLDER_PATH/
      

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

      • BUCKET_NAME: バケットの名前。
      • FOLDER_PATH: マネージド フォルダのパス(例: my-app-snapshots)。
    2. マネージド フォルダに対するカスタム podSnapshotGcsReadWriter ロールを ServiceAccount オブジェクトに付与します。権限を付与するには、選択したオプションのコマンドを実行します。

      標準権限

      gcloud storage managed-folders add-iam-policy-binding gs://BUCKET_NAME/FOLDER_PATH/ \
          --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \
          --role="projects/PROJECT_ID/roles/podSnapshotGcsReadWriter"
      

      1 回限りの書き込み権限

      gcloud storage managed-folders add-iam-policy-binding gs://BUCKET_NAME/FOLDER_PATH/ \
          --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \
          --role="projects/PROJECT_ID/roles/podSnapshotGcsReadWriter"
      
      gcloud storage managed-folders add-iam-policy-binding gs://BUCKET_NAME/FOLDER_PATH/ \
          --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \
          --role="roles/storage.objectUser" \
          --condition='expression=resource.type == "storage.googleapis.com/Object" && (resource.name.extract("/pages.img_{part}") != "" || resource.name.extract("/fs_checkpoint_pages.img_{part}") != ""),title=allow_pcu_temp_part_cleanup,description=Allow deleting temporary parallel composite upload part objects only'
      

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

      • BUCKET_NAME: バケットの名前。
      • FOLDER_PATH: マネージド フォルダのパス(例: my-app-snapshots)。
      • PROJECT_NUMBER: プロジェクトの番号。
      • PROJECT_ID: プロジェクト ID。
      • NAMESPACE: Pod の名前空間。
      • SERVICEACCOUNT_NAME: ServiceAccount オブジェクトの名前。

スナップショットのストレージを構成する

Pod スナップショットの保存場所を指定するには、PodSnapshotStorageConfig カスタム リソースを作成します。

  1. 次のマニフェストを example-pod-snapshot-storage-config.yaml として保存します。次の例では、Cloud Storage バケット BUCKET_NAME 内の FOLDER_PATH/ パスに Pod スナップショットを保存するように GKE を構成します。

    apiVersion: podsnapshot.gke.io/v1
    kind: PodSnapshotStorageConfig
    metadata:
      name: example-pod-snapshot-storage-config
    spec:
      snapshotStorageConfig:
        gcs:
          bucket: "BUCKET_NAME"
          path: "FOLDER_PATH"
          tokenSource: "TOKEN_SOURCE"
    

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

    • BUCKET_NAME: Cloud Storage バケットの名前。
    • FOLDER_PATH: Cloud Storage マネージド フォルダのパス。
    • TOKEN_SOURCE: アクセスの ID プロバイダ。マルチテナンシーには podKSA(デフォルト)または federatedP4SA を使用します。

  2. 次のようにマニフェストを適用します。

    kubectl apply -f example-pod-snapshot-storage-config.yaml
    

次のステップ

Pod スナップショットをトリガーする方法を学習する。