セカンダリ ブートディスクを使用してデータまたはコンテナ イメージをプリロードする


このページでは、Google Kubernetes Engine(GKE)でセカンダリ ブートディスクを使用して、新しいノードにデータまたはコンテナ イメージをプリロードし、ワークロードの起動レイテンシを改善する方法について説明します。これにより、ワークロードではコールド スタートの高速化と、プロビジョニングされたリソースの全体的な使用率の向上が実現します。

このページを読む前に、 Google Cloud、Kubernetes、コンテナ、YAML、containerd ランタイム、Google Cloud CLI について理解しておいてください。

概要

Standard クラスタの GKE バージョン 1.28.3-gke.1067000 以降と Autopilot クラスタの GKE バージョン 1.30.1-gke.1329000 以降では、セカンダリ ブートディスクを使用してノードプールを構成できます。GKE には、ノードをプロビジョニングして、ML モデルやコンテナ イメージなどのデータをプリロードするように指示できます。プリロードされたコンテナ イメージやセカンダリ ディスクのデータを使用すると、ワークロードに次のようなメリットがあります。

  • 大規模なコンテナ イメージの pull やデータのダウンロード時のレイテンシの短縮
  • 自動スケーリングの高速化
  • メンテナンス イベントやシステムエラーなどの中断からの迅速な復元

以降のセクションでは、GKE Autopilot クラスタと Standard クラスタでセカンダリ ブートディスクを構成する方法について説明します。

セカンダリ ブートディスクの仕組み

セカンダリ ブートディスクにプリロードされたコンテナ イメージまたはデータを使用することで、ワークロードの起動を高速化できます。セカンダリ ブートディスクには次の特性があります。

  • セカンダリ ブートディスクは、分散ブロック ストレージを基盤とする Persistent Disk です。
  • Persistent Disk は、事前に作成したディスク イメージからインスタンス化されます。
  • スケーラビリティ上の理由から、各ノードにはディスクイメージから独自の Persistent Disk インスタンスが作成されます。これらの Persistent Disk インスタンスは、ノードが削除されると削除されます。
  • ディスク イメージがゾーンですでに使用されている場合、同じディスク イメージから作成される後続のディスクの作成時間は短くなります。
  • セカンダリ ブートディスクのタイプは、ノードのブートディスクと同じです。
  • セカンダリ ブートディスクのサイズは、ディスク イメージのサイズによって決まります。

ノードプールにセカンダリ ブートディスクを追加しても、ノードのプロビジョニング時間は増加しません。GKE は、ノードのプロビジョニング プロセスと並行して、ディスク イメージからセカンダリ ブートディスクをプロビジョニングします。

ベスト プラクティス:

プリロードされたコンテナ イメージをサポートするため、GKE は、セカンダリ ブートディスクからコンテナ イメージを読み取るプラグインを使用して containerd ランタイムを拡張します。コンテナ イメージはベースレイヤで再利用されます。

大きなベースレイヤはセカンダリ ブートディスクにプリロードし、小さな上位レイヤをコンテナ レジストリから pull できます。

始める前に

作業を始める前に、次のことを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components update を実行して最新のバージョンを取得する。

要件

セカンダリ ブートディスクの使用には、次の要件が適用されます。

  1. クラスタが GKE Standard で、GKE バージョン 1.28.3-gke.1067000 または GKE Autopilot でバージョン 1.30.1-gke.1329000 を実行している。
  2. ディスク イメージを変更するときは、新しいノードプールを作成する必要があります。既存のノードのディスク イメージの更新はサポートされていません。
  3. セカンダリ ブートディスク機能を使用するようにイメージ ストリーミングを構成します。
  4. containerd ノードイメージで Container-Optimized OS を使用します。Autopilot ノードはデフォルトでこのノードイメージを使用します。
  5. ビルド時にデータが準備されたディスク イメージを準備するか、プリロードされたコンテナ イメージを使用してディスク イメージを準備します。クラスタがディスク イメージにアクセスしてノードに読み込まれるようにします。

    ベスト プラクティス:

    CI / CD パイプラインでディスク イメージを自動化します。

制限事項

セカンダリ ブートディスクには次の制限があります。

  • 既存ノードのセカンダリ ブートディスクを更新することはできません。新しいディスク イメージを接続するには、新しいノードプールを作成します。
  • セカンダリ ブートディスクを使用して GKE Autopilot クラスタにデータをプリロードすることはできません。

料金

セカンダリ ブートディスクを使用してノードプールを作成すると、GKE はノードプール内の各ノードに Persistent Disk をアタッチします。Persistent Disk は、Compute Engine ディスクの料金に基づいて課金されます。

セカンダリ ブートディスク イメージを準備する

セカンダリ ブートディスク イメージを準備するときに、コンテナ イメージをプリロードする場合は [イメージ] タブを選択し、データをプリロードする場合は [データ] タブを選択して、次の手順を完了します。

イメージ

GKE には、仮想マシン(VM)を作成してディスク上のコンテナ イメージを pull し、そのディスクからディスク イメージを作成する gke-disk-image-builder というツールが用意されています。

複数のプリロードされたコンテナ イメージを含むディスク イメージを作成するには、次の操作を行います。

  1. gke-disk-image-builder の実行ログを保存する Cloud Storage バケットを作成します。
  2. gke-disk-image-builder を使用してディスク イメージを作成します。
go run ./cli \
    --project-name=PROJECT_ID \
    --image-name=DISK_IMAGE_NAME \
    --zone=LOCATION \
    --gcs-path=gs://LOG_BUCKET_NAME \
    --disk-size-gb=10 \
    --container-image=docker.io/library/python:latest \
    --container-image=docker.io/library/nginx:latest

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

  • PROJECT_ID: Google Cloud プロジェクトの名前。
  • DISK_IMAGE_NAME: ディスクのイメージの名前。例: nginx-python-image
  • LOCATION: クラスタのロケーション
  • LOG_BUCKET_NAME: 実行ログを保存する Cloud Storage バケットの名前。例: gke-secondary-disk-image-logs/

gke-disk-image-builder を使用してディスク イメージを作成すると、Google Cloud によってプロセスを完了するために複数のリソース(VM インスタンス、一時ディスク、永続ディスクなど)が作成されます。実行後、イメージ ビルダーは、作成したディスク イメージを除くすべてのリソースをクリーンアップします。

データ

次の手順で、データソースとしてカスタム ディスク イメージを作成します。

  1. 空のディスクで VM を作成する
  2. SSH で VM に接続する
    1. 空のディスクをマウントする
    2. 空のディスクにデータをダウンロードする
  3. ディスクからカスタム イメージを作成する

セカンダリ ブートディスクを構成する

セカンダリ ブートディスクは、GKE Autopilot クラスタまたは GKE Standard クラスタで構成できます。

ベスト プラクティス:

フルマネージドの Kubernetes エクスペリエンスを実現するには、Autopilot クラスタを使用します。ワークロードに最適な GKE の運用モードを選択するには、GKE の運用モードを選択するをご覧ください。

GKE Autopilot を使用する

このセクションでは、ディスク イメージの許可リストを作成し、既存の GKE Autopilot クラスタでディスク イメージを許可します。次に、セカンダリ ブートディスクを使用するように Pod ノードセレクタを変更します。

プロジェクトでディスク イメージを許可する

このセクションでは、GKE がGoogle Cloud プロジェクトのディスク イメージからセカンダリ ブートディスクを含むノードを作成できるように GCPResourceAllowlist を作成します。

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

    apiVersion: "node.gke.io/v1"
    kind: GCPResourceAllowlist
    metadata:
      name: gke-secondary-boot-disk-allowlist
    spec:
      allowedResourcePatterns:
      - "projects/PROJECT_ID/global/images/.*"
    

    PROJECT_ID は、ディスク イメージをホストするプロジェクト ID に置き換えます。

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

    kubectl apply -f allowlist-disk.yaml
    

    GKE は、プロジェクト内のすべてのディスク イメージからセカンダリ ブートディスクを含むノードを作成します。

セカンダリ ブートディスクを使用するように Pod ノードセレクタを更新する

このセクションでは、GKE がセカンダリ ブートディスクを使用してノードを作成するように Pod 仕様を変更します。

  1. Pod テンプレートに nodeSelector を追加します。

    nodeSelector:
        cloud.google.com.node-restriction.kubernetes.io/gke-secondary-boot-disk-DISK_IMAGE_NAME: CONTAINER_IMAGE_CACHE.PROJECT_ID
    

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

    • DISK_IMAGE_NAME: ディスク イメージの名前。
    • PROJECT_ID: ディスク イメージをホストするプロジェクト ID。
  2. kubectl apply コマンドを使用して、Pod テンプレートを使用して Kubernetes 仕様を適用します。

  3. セカンダリ ブートディスク キャッシュが使用中であることを確認します。

    kubectl get events --all-namespaces
    

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

    75s         Normal      SecondaryDiskCachin
    node/gke-pd-cache-demo-default-pool-75e78709-zjfm   Image
    gcr.io/k8s-staging-jobsejt/pytorch-mnist:latest is backed by secondary disk cache
    
  4. セカンダリ ブートディスク キャッシュが使用中であることを確認する信頼性の高い方法は次のとおりです。

    次のログ名を使用して、対象のノードのログをクエリします。

    logName="projects/PROJECT_ID/logs/gcfs-snapshotter"
    

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

    Image gcr.io/k8s-staging-jobsejt/pytorch-mnist:latest is backed by secondary boot disk caching by 100.0%... のようなログは、セカンダリ ブートディスク キャッシュが使用されたことを示します。

  5. イメージ pull のレイテンシを確認します。

    kubectl describe pod POD_NAME
    

    POD_NAME は、Pod の名前で置き換えます。

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

    …
      Normal  Pulled     15m   kubelet            Successfully pulled image "docker.io/library/nginx:latest" in 0.879149587s
    …
    

キャッシュに保存されたコンテナ イメージに想定されるイメージ pull のレイテンシは、イメージサイズに関係なく大幅に短縮されます。

GKE Standard を使用する

GKE Standard クラスタとノードプールを作成するには、次の手順を完了します。セカンダリ ブートディスクにコンテナ イメージをプリロードするのか、データをプリロードするかに応じて、[イメージ] タブまたは [データ] タブを選択します。

画像

セカンダリ ブートディスクを構成するには、Google Cloud CLI または Terraform を使用します。

gcloud

  1. イメージ ストリーミングを有効にして GKE Standard クラスタを作成します。

    gcloud container clusters create CLUSTER_NAME \
        --location=LOCATION \
        --cluster-version=VERSION \
        --enable-image-streaming
    

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

    • CLUSTER_NAME: クラスタの名前。
    • LOCATION: クラスタのロケーション。
    • VERSION: 使用する GKE のバージョン。GKE のバージョンは 1.28.3-gke.1067000 以降にする必要があります。
  2. 同じプロジェクトにセカンダリ ブートディスクを含むノードプールを作成します。

    gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location LOCATION \
    --enable-image-streaming \
    --secondary-boot-disk=disk-image=global/images/DISK_IMAGE_NAME,mode=CONTAINER_IMAGE_CACHE
    

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

    • NODE_POOL_NAME: ノードプールの名前。
    • CLUSTER_NAME: 既存のクラスタの名前。
    • LOCATION: クラスタのコンピューティング ゾーン(カンマ区切り)。
    • DISK_IMAGE_NAME: ディスク イメージの名前。

    別のプロジェクトのディスク イメージからセカンダリ ブートディスクを含むノードプールを作成するには、別のプロジェクトでセカンダリ ブートディスクを使用するの手順を完了します。

  3. Pod テンプレートに nodeSelector を追加します。

    nodeSelector:
        cloud.google.com/gke-nodepool: NODE_POOL_NAME
    
  4. セカンダリ ブートディスク キャッシュが使用中であることを確認します。

    kubectl get events --all-namespaces
    

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

    75s       Normal      SecondaryDiskCachin
    node/gke-pd-cache-demo-default-pool-75e78709-zjfm Image
    gcr.io/k8s-staging-jobsejt/pytorch-mnist:latest is backed by secondary disk cache
    
  5. セカンダリ ブートディスク キャッシュが使用中であることを確認する信頼性の高い方法は次のとおりです。

    次のログ名を使用して、対象のノードのログをクエリします。

    logName="projects/PROJECT_ID/logs/gcfs-snapshotter"
    

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

    Image gcr.io/k8s-staging-jobsejt/pytorch-mnist:latest is backed by secondary boot disk caching by 100.0%... のようなログは、セカンダリ ブートディスク キャッシュが使用されたことを示します。

  6. 次のコマンドを実行して、イメージ pull レイテンシを確認します。

    kubectl describe pod POD_NAME
    

    POD_NAME は、Pod の名前で置き換えます。

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

    …
      Normal  Pulled     15m   kubelet            Successfully pulled image "docker.io/library/nginx:latest" in 0.879149587s
    …
    

キャッシュに保存されたコンテナ イメージの想定されるイメージ pull レイテンシは、イメージサイズに関係なく数秒以内にする必要があります。

Terraform

  1. Terraform を使用してデフォルト ノードプールを持つクラスタを作成するには、次の例をご覧ください。

    resource "google_container_cluster" "default" {
      name               = "default"
      location           = "us-central1-a"
      initial_node_count = 1
    
      # secondary_boot_disks require GKE 1.28.3-gke.106700 or later, which should
      # be true for all release channels apart from EXTENDED.
      # If required, Use `release_channel = "EXTENDED"` and set `min_master_version`.
    }
  2. 同じプロジェクトにセカンダリ ブートディスクを含むノードプールを作成します。

    resource "google_container_node_pool" "secondary-boot-disk-container" {
      name               = "secondary-boot-disk-container"
      location           = "us-central1-a"
      cluster            = google_container_cluster.default.name
      initial_node_count = 1
    
      node_config {
        machine_type = "e2-medium"
        image_type   = "COS_CONTAINERD"
        gcfs_config {
          enabled = true
        }
        secondary_boot_disks {
          disk_image = ""
          mode       = "CONTAINER_IMAGE_CACHE"
        }
      }
    }

    Terraform の使用方法の詳細については、GKE での Terraform のサポートをご覧ください。

  3. Pod テンプレートに nodeSelector を追加します。

    nodeSelector:
        cloud.google.com/gke-nodepool: NODE_POOL_NAME
    
  4. セカンダリ ブートディスク キャッシュが使用中であることを確認します。

    kubectl get events --all-namespaces
    

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

    75s       Normal      SecondaryDiskCachin
    node/gke-pd-cache-demo-default-pool-75e78709-zjfm Image
    gcr.io/k8s-staging-jobsejt/pytorch-mnist:latest is backed by secondary disk cache
    
  5. 次のコマンドを実行して、イメージ pull レイテンシを確認します。

    kubectl describe pod POD_NAME
    

    POD_NAME は、Pod の名前で置き換えます。

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

    …
      Normal  Pulled     15m   kubelet            Successfully pulled image "docker.io/library/nginx:latest" in 0.879149587s
    …
    

キャッシュに保存されたコンテナ イメージの想定されるイメージ pull レイテンシは、イメージサイズに関係なく数秒以内にする必要があります。

Terraform の使用方法の詳細については、GKE での Terraform のサポートをご覧ください。

データ

セカンダリ ブートディスクとプリロード データを構成するには、Google Cloud CLI または Terraform を使用します。

gcloud

  1. イメージ ストリーミングを有効にして GKE Standard クラスタを作成します。

    gcloud container clusters create CLUSTER_NAME \
        --location=LOCATION \
        --cluster-version=VERSION \
        --enable-image-streaming
    

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

    • CLUSTER_NAME: クラスタの名前。
    • LOCATION: クラスタのロケーション。
    • VERSION: 使用する GKE のバージョン。GKE バージョンは、1.28.3-gke.1067000 以降である必要があります。
  2. --secondary-boot-disk フラグを使用して、セカンダリ ブートディスクを含むノードプールを作成します。

    gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location LOCATION \
    --enable-image-streaming \
    --secondary-boot-disk=disk-image=global/images/DISK_IMAGE_NAME
    

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

    • NODE_POOL_NAME: ノードプールの名前。
    • CLUSTER_NAME: 既存のクラスタの名前。
    • LOCATION: クラスタのコンピューティング ゾーン(カンマ区切り)。
    • DISK_IMAGE_NAME: ディスク イメージの名前。

    別のプロジェクトのディスク イメージからセカンダリ ブートディスクを含むノードプールを作成するには、別のプロジェクトでセカンダリ ブートディスクを使用するの手順を完了します。

    プリロードされたデータを含むセカンダリ ディスクが各ノードに存在するノードプールが作成されます。GKE は、セカンダリ ブートディスクをノードにアタッチしてマウントします。

  3. データにアクセスするには、hostPath ボリューム マウントを使用して、セカンダリ ブートディスク イメージを Pod コンテナにマウントします。/usr/local/data_path_sbd には、データを配置するコンテナ内のパスに設定します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-name
    spec:
      containers:
      ...
      volumeMounts:
      - mountPath: /usr/local/data_path_sbd
        name: data-path-sbd
    ...
    volumes:
      - name: data-path-sbd
        hostPath:
            path: /mnt/disks/gke-secondary-disks/gke-DISK_IMAGE_NAME-disk
    

    DISK_IMAGE_NAME は、ディスク イメージの名前に置き換えます。

Terraform

  1. Terraform を使用してデフォルト ノードプールを持つクラスタを作成するには、次の例をご覧ください。

    resource "google_container_cluster" "default" {
      name               = "default"
      location           = "us-central1-a"
      initial_node_count = 1
    
      # secondary_boot_disks require GKE 1.28.3-gke.106700 or later, which should
      # be true for all release channels apart from EXTENDED.
      # If required, Use `release_channel = "EXTENDED"` and set `min_master_version`.
    }
  2. 同じプロジェクトにセカンダリ ブートディスクを含むノードプールを作成します。

    resource "google_container_node_pool" "secondary-boot-disk-data" {
      name               = "secondary-boot-disk-data"
      location           = "us-central1-a"
      cluster            = google_container_cluster.default.name
      initial_node_count = 1
    
      node_config {
        machine_type = "e2-medium"
        image_type   = "COS_CONTAINERD"
        gcfs_config {
          enabled = true
        }
        secondary_boot_disks {
          disk_image = ""
        }
      }
    }

    Terraform の使用方法の詳細については、GKE での Terraform のサポートをご覧ください。

  3. データにアクセスするには、hostPath ボリューム マウントを使用して、セカンダリ ブートディスク イメージを Pod コンテナにマウントします。/usr/local/data_path_sbd には、データを配置するコンテナ内のパスに設定します。

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-name
    spec:
      containers:
      ...
      volumeMounts:
      - mountPath: /usr/local/data_path_sbd
        name: data-path-sbd
    ...
    volumes:
      - name: data-path-sbd
        hostPath:
            path: /mnt/disks/gke-secondary-disks/gke-DISK_IMAGE_NAME-disk
    

    DISK_IMAGE_NAME は、ディスク イメージの名前に置き換えます。

セカンダリ ブートディスクを使用したクラスタの自動スケーリング

ノードプールを作成し、セカンダリ ブートディスクでクラスタの自動スケーリングを構成するには、Google Cloud CLI を使用します。

  gcloud container node-pools create NODE_POOL_NAME \
      --cluster=CLUSTER_NAME \
      --location LOCATION \
      --enable-image-streaming \
      --secondary-boot-disk=disk-image=global/images/DISK_IMAGE_NAME,mode=CONTAINER_IMAGE_CACHE \
      --enable-autoscaling \
      --num-nodes NUM_NODES \
      --min-nodes MIN_NODES \
      --max-nodes MAX_NODES

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

  • NODE_POOL_NAME: ノードプールの名前。
  • CLUSTER_NAME: 既存のクラスタの名前。
  • LOCATION: クラスタのコンピューティング ゾーン(カンマ区切り)。
  • DISK_IMAGE_NAME: ディスク イメージの名前。
  • MIN_NODES: 指定したノードプールで自動的にスケーリングするゾーンの最小ノード数。GKE バージョン 1.24 以降でノードプール全体の最小ノード数を指定するには、--total-min-nodes を使用します。フラグ --total-min-nodes--total-max-nodes は、フラグ --min-nodes--max-nodes と相互に排他的です。
  • MAX_NODES: 指定したノードプールで自動的にスケーリングするゾーンの最大ノード数。GKE バージョン 1.24 以降でノードプール全体のノードの最大数を指定するには、--total-max-nodes を使用します。フラグ --total-min-nodes--total-max-nodes は、フラグ --min-nodes--max-nodes と相互に排他的です。

セカンダリ ブートディスクを使用したノードの自動プロビジョニング

GKE 1.30.1-gke.1329000 以降では、ワークロードのリソース需要を満たすためにノードプールを自動的に作成および削除するよう、ノードの自動プロビジョニングを構成できます。

  1. 次のように、GKE ノードの自動プロビジョニング用のセカンダリ ブートディスクにディスク イメージ許可リスト カスタム リソースを作成します。

    apiVersion: "node.gke.io/v1"
    kind: GCPResourceAllowlist
    metadata:
      name: gke-secondary-boot-disk-allowlist
    spec:
      allowedResourcePatterns:
      - "projects//global/images/.*"
    

    PROJECT_ID は、ディスク イメージをホストするプロジェクト ID に置き換えます。

  2. クラスタに許可リスト カスタム リソースをデプロイするには、次のコマンドを実行します。

    kubectl apply -f ALLOWLIST_FILE
    

    ALLOWLIST_FILE は、マニフェスト ファイル名に置き換えます。

  3. セカンダリ ブートディスクを使用するように Pod ノードセレクタを更新します。

    nodeSelector:
        cloud.google.com.node-restriction.kubernetes.io/gke-secondary-boot-disk-DISK_IMAGE_NAME:CONTAINER_IMAGE_CACHE.PROJECT_ID
    

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

    • DISK_IMAGE_NAME: ディスク イメージの名前。
    • PROJECT_ID: ディスク イメージをホストするプロジェクト ID。

別のプロジェクトでセカンダリ ブートディスクを使用する

セカンダリ ブートディスクを含むノードプールを作成する場合は、--secondary-boot-disk フラグを使用して、別のプロジェクトのディスク イメージを使用するように GKE に指示できます。

  1. 別のプロジェクトのディスク イメージから、セカンダリ ブートディスクを含むノードプールを作成するには、--secondary-boot-disk フラグを使用します。例:

    gcloud beta container node-pools create NODE_POOL_NAME \
        --cluster=CLUSTER_NAME \
        --location LOCATION \
        --enable-image-streaming \
        --secondary-boot-disk=disk-image=projects/IMAGE_PROJECT_ID/global/images/DISK_IMAGE_NAME,mode=CONTAINER_IMAGE_CACHE
    
    

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

    • DISK_IMAGE_NAME: ディスク イメージの名前。
    • IMAGE_PROJECT_ID: ディスク イメージが属するプロジェクトの名前。

    プリロードされたデータを含むセカンダリ ディスクが各ノードに存在するノードプールが作成されます。これにより、セカンダリ ブートディスクがノードにアタッチされ、マウントされます。

  2. クラスタ サービス アカウントに Compute イメージ ユーザーのロールを追加して、別のプロジェクトに属するディスク イメージへのアクセス権を付与します。

    • デフォルトのコンピューティング サービス アカウント: CLUSTER_PROJECT_NUMBER@cloudservices.gserviceaccount.com
    • GKE サービス アカウント: service-CLUSTER_PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
    gcloud projects add-iam-policy-binding IMAGE_PROJECT_ID \
        --member serviceAccount:CLUSTER_PROJECT_NUMBER@cloudservices.gserviceaccount.com \
        --role roles/compute.imageUser
    
    gcloud projects add-iam-policy-binding IMAGE_PROJECT_ID \
        --member serviceAccount:service-CLUSTER_PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com \
        --role roles/compute.imageUser
    

次のステップ