イメージ ストリーミングを使用してコンテナ イメージを pull する


このページでは、Google Kubernetes Engine(GKE)でイメージ ストリーミングを使用して、アプリケーションのニーズに応じてイメージデータをストリーミングし、コンテナ イメージを pull する方法を説明します。

GKE バージョン 1.25.5-gke.1000 以降を実行する新しい Autopilot クラスタは、イメージ ストリーミングを使用して自動的に対象イメージを pull します。このページの手順は Standard クラスタにのみ適用されます。

概要

イメージ ストリーミングはコンテナ イメージを取得する方法で、GKE はアプリケーションからのリクエストに応じて対象イメージからデータをストリーミングします。イメージ ストリーミングを使用すると、イメージ全体がダウンロードされるのを待たずにワークロードを初期化できます。これにより、初期化時間を大幅に短縮できます。pull 時間の短縮には、次のような利点があります。

  • 自動スケーリングの高速化
  • 大きなイメージを pull する際のレイテンシの短縮
  • Pod の起動の高速化

イメージ ストリーミングでは、GKE は、対象となるコンテナ イメージを使用するコンテナのルート ファイル システムとしてリモート コンテナ システムを使用します。ワークロードで必要になると、リモート ファイル システムからイメージデータをストリーミングします。イメージ ストリーミングを使用しない場合、GKE はコンテナ イメージ全体を各ノードにダウンロードし、ワークロードのルート ファイル システムとして使用します。

イメージデータをストリーミングしながら、バックグラウンドでコンテナ イメージ全体をローカル ディスクにダウンロードし、キャッシュに保存します。その後はキャッシュに保存されたイメージからデータ読み取りリクエストを送信します。

コンテナ イメージ内の特定のファイルを読み取る必要があるワークロードをデプロイすると、イメージ ストリーミング バックエンドはリクエストされたファイルのみを提供します。

要件

GKE Autopilot クラスタと GKE Standard クラスタでイメージ ストリーミングを使用するには、次の要件を満たす必要があります。

  • Container File System API を有効にする必要があります。

    Container File System API を有効にする

  • イメージ ストリーミングを自動的に有効にするには、新しい Autopilot クラスタで GKE バージョン 1.25.5-gke.1000 以降を実行する必要があります。手順については、新しい Autopilot クラスタのバージョンとリリース チャンネルを設定するをご覧ください。

  • 新規および既存の GKE Standard クラスタでは、バージョン 1.18.6-gke.4801 以降を実行する必要があります。

  • コンテナ化されたノードイメージを持ち、コンテナ用に最適化された OS を使用する必要があります。 Autopilot ノードは常にこのノードイメージを使用します。

  • コンテナ イメージは Artifact Registry に保存する必要があります。

  • クラスタで限定公開ノードを有効にしている場合、ノードがイメージ ストリーミング サービスにアクセスするには、サブネットで限定公開の Google アクセスを有効にする必要があります。

  • VPC Service Controls がコンテナ イメージを保護し、イメージ ストリーミングを使用する場合は、サービス境界に Image Streaming API(containerfilesystem.googleapis.com)も含める必要があります。

  • クラスタ内の GKE ノードがデフォルトのサービス アカウントを使用していない場合は、カスタム サービス アカウントにコンテナ イメージをホストするプロジェクトの Service Usage ユーザーroles/serviceusage.serviceUsageConsumer)IAM ロールが付与されていることを確認する必要があります。

制限事項

  • 1.23.5-gke.1900 より前の GKE バージョンでは、Secret を使用してコンテナ イメージを pull することはできません。
  • V2 イメージ マニフェスト、スキーマ バージョン 1 を使用するコンテナ イメージは対象外です。
  • 顧客管理の暗号鍵(CMEK)で暗号化されたコンテナ イメージは、GKE バージョン 1.25.3-gke.1000 以降のイメージ ストリーミングの対象になります。以前のバージョンの GKE では、データをストリーミングせずにこれらのイメージをダウンロードします。引き続き CMEK を使用して、イメージ ストリーミングを使用するクラスタ内の永続ディスクカスタム ブートディスクを保護できます。
  • 重複するレイヤを含むコンテナ イメージはサポートされていません。GKE は、これらのイメージをストリーミングせずにダウンロードします。コンテナ イメージに空のレイヤまたは重複するレイヤがないか確認します。
  • Artifact Registry リポジトリは、GKE ノードと同じリージョンか、ノードを実行しているリージョンに対応するマルチリージョンに存在する必要があります。例:
    • ノードが us-east1 にある場合、GKE と Artifact Registry の両方が米国内のデータセンター ロケーションで実行されているため、us-east1 リージョンまたは us マルチリージョンのリポジトリでイメージ ストリーミングを使用できます。
    • ノードが northamerica-northeast1 リージョンにある場合、ノードはカナダで実行されます。この場合、イメージ ストリーミングを利用できるのは、同じリージョンのリポジトリだけです。
  • 初期化中にワークロードがイメージ内の複数のファイルを読み取る場合、リモート ファイルの読み取りによってレイテンシが増加し、初期化時間が長くなることがあります。
  • 適格なイメージを初めて pull する場合は、イメージ ストリーミングの利点に気づかない可能性があります。ただし、イメージ ストリーミングでイメージがキャッシュに保存された後は、イメージの pull でイメージ ストリーミングの利点を実感できます。
  • GKE Standard クラスタは、クラスタレベルの構成を使用して、ノードの自動プロビジョニングで作成された新しいノードプールでイメージ ストリーミングを有効にするかどうかを決定します。ただし、クラスタレベルでイメージ ストリーミングが無効になっている場合、ワークロードの分離を使用して、イメージ ストリーミングを有効にしたノードプールを作成することはできません。
  • CAP_NET_RAW などの Linux ファイル機能は、GKE バージョン 1.22.6-gke.300 以降のイメージ ストリーミングでサポートされています。以前の GKE バージョンでは、イメージ ファイルがストリーミングされるとき、またはイメージがローカル ディスクに保存されているときに、これらの機能は使用できません。中断を回避するために、1.22.6-gke.300 より前の GKE バージョンでは、これらの機能を使用するコンテナにイメージ ストリーミングを使用しないでください。コンテナが Linux ファイル機能に依存している場合、イメージ ストリーミングを有効にして実行すると、権限拒否エラーで起動が失敗する可能性があります。

始める前に

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

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

クラスタでイメージ ストリーミングを有効にする

新規または既存の Standard クラスタでイメージ ストリーミングを有効にするには、gcloud CLI の --enable-image-streaming フラグを使用するか、Google Cloud コンソールを使用します。デフォルトでは、クラスタ内のノードプールはクラスタレベルでイメージ ストリーミングの設定を継承します。この動作を変更するには、クラスタ内のノードプールでイメージ ストリーミングを有効または無効にします。

GKE バージョン 1.25.5-gke.1000 以降を実行するすべての新しい Autopilot クラスタは、イメージ ストリーミングを使用して対象イメージを pull します。手順については、新しい Autopilot クラスタのバージョンとリリース チャンネルを設定するをご覧ください。次の手順は、GKE Standard クラスタにのみ適用されます。

新しいクラスタの場合

新しいクラスタでイメージ ストリーミングを有効にするには、gcloud CLI か Google Cloud コンソールを使用します。

gcloud

イメージ ストリーミングを有効にして新しいクラスタを作成するには、次のコマンドを実行します。

gcloud container clusters create CLUSTER_NAME \
    --zone=COMPUTE_ZONE \
    --image-type="COS_CONTAINERD" \
    --enable-image-streaming

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

  • CLUSTER_NAME: 新しいクラスタの名前。
  • COMPUTE_ZONE: 新しいクラスタの Compute Engine ゾーン。リージョン クラスタの場合は、代わりに --region=COMPUTE_REGION フラグを使用します。ゾーンまたはリージョンが同じリージョンにあるか、イメージを含む Artifact Registry リポジトリのマルチリージョンにあることを確認します。

Console

  1. Google Cloud コンソールで [Google Kubernetes Engine] ページに移動します。

    Google Kubernetes Engine に移動

  2. [ 作成] をクリックします。

  3. [GKE Standard] セクションで [構成] をクリックします。

  4. ナビゲーション パネルの [クラスタ] の下の [機能] をクリックします。

  5. [その他] セクションで、[イメージ ストリーミングを有効にする] チェックボックスをオンにします。

  6. 必要に応じてインスタンスを構成し、[作成] をクリックします。

既存クラスタの場合

gcloud CLI または Google Cloud コンソールを使用して、要件を満たす既存のクラスタでイメージ ストリーミングを有効にできます。

gcloud

イメージ ストリーミングを使用するように既存のクラスタを更新するには、gcloud CLI を使用して次のコマンドを実行します。

gcloud container clusters update CLUSTER_NAME \
    --enable-image-streaming

Console

  1. Google Cloud コンソールで [Google Kubernetes Engine] ページに移動します。

    Google Kubernetes Engine に移動

  2. 変更するクラスタの名前をクリックします。

  3. [クラスタ] ページの [機能] セクションで、[イメージ ストリーミング] の横にある をクリックします。

  4. [イメージ ストリーミングの編集] ダイアログ ボックスで、[イメージ ストリーミングを有効にする] チェックボックスをオンにします。

  5. [保存] をクリックします。

クラスタを変更すると、GKE はデフォルトで既存のノードプールのイメージ ストリーミングを自動的に有効にします。個々のノードプールでイメージ ストリーミングを明示的に有効または無効にした場合、それらのノードプールはクラスタレベルの設定に対する変更を継承しません。

イメージ ストリーミングの設定を変更する場合、クラスタレベルで更新するとメンテナンスの可用性が考慮されますが、ノードプール レベルでは考慮されません。

この変更を行うにはノードを再作成する必要があります。これにより、実行中のワークロードが中断する可能性があります。この特定の変更について詳しくは、ノードのアップグレード戦略を使用してノードを再作成し、メンテナンス ポリシーに準拠する手動変更の表で対応する行を確認してください。ノードの更新の詳細については、ノードの更新による中断の計画をご覧ください。

クラスタでイメージ ストリーミングが有効になっていることを確認する

クラスタレベルでイメージ ストリーミングが有効になっているかどうかを確認するには、gcloud CLI または Google Cloud コンソールを使用します。

gcloud

次のコマンドを実行します。

gcloud container clusters describe CLUSTER_NAME \
    --flatten "nodePoolDefaults.nodeConfigDefaults"

出力が次のようになっている場合、設定は有効になっています。

gcfsConfig:
  enabled: true
...

出力が次のようになっている場合、設定は無効になっています。

gcfsConfig: {}
...

Console

  1. Google Cloud コンソールで [Google Kubernetes Engine] ページに移動します。

    Google Kubernetes Engine に移動

  2. 確認するクラスタの名前をクリックします。

  3. [クラスタ] ページの [機能] セクションにある [イメージ ストリーミング] の横に、設定が有効になっているかどうかが表示されます。

ノードプールでイメージ ストリーミングを有効にする

デフォルトでは、ノードプールはクラスタレベルでイメージ ストリーミングの設定を継承します。特定のノードプールでイメージ ストリーミングを有効または無効にするには、gcloud CLI を使用します。

新しいノードプールの場合

イメージ ストリーミングを有効にして新しいノードプールを作成するには、次のコマンドを実行します。

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --zone=COMPUTE_ZONE \
    --image-type="COS_CONTAINERD" \
    --enable-image-streaming

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

  • NODE_POOL_NAME: 新しいノードプールの名前。
  • CLUSTER_NAME: ノードプールのクラスタの名前。
  • COMPUTE_ZONE: クラスタの Compute Engine ゾーン。リージョン クラスタの場合は、代わりに --region=COMPUTE_REGION フラグを使用します。

既存のノードプールの場合

要件を満たす既存のノードプールでイメージ ストリーミングを有効にできます。

イメージ ストリーミングを使用するように既存のノードプールを更新するには、次のコマンドを実行します。

gcloud container node-pools update POOL_NAME \
    --cluster=CLUSTER_NAME \
    --enable-image-streaming

イメージ ストリーミングの設定を変更する場合、クラスタレベルで更新するとメンテナンスの可用性が考慮されますが、ノードプール レベルでは考慮されません。

この変更を行うにはノードを再作成する必要があります。これにより、実行中のワークロードが中断する可能性があります。この特定の変更について詳しくは、メンテナンス ポリシーを尊重せずにノードのアップグレード戦略を使用してノードを再作成する手動変更の表で対応する行をご覧ください。ノードの更新の詳細については、ノードの更新による中断の計画をご覧ください。

ノードプールでイメージ ストリーミングが有効になっていることを確認する

ノードプールでイメージ ストリーミングが有効になっていることを確認します。

gcloud container node-pools describe POOL_NAME \
    --cluster=CLUSTER_NAME \

出力が次のようになっている場合、設定は有効になっています。

gcfsConfig:
  enabled: true
...

出力が次のようになっている場合、設定は無効になっています。

gcfsConfig: {}
...

イメージ ストリーミングを使用してワークロードをスケジュールする

クラスタでイメージ ストリーミングを有効にすると、構成の追加を必要とせず、GKE は Artifact Registry から有効なコンテナ イメージを pull するときに自動的にイメージ ストリーミングを使用します。

イメージ ストリーミングが有効になっているノードプールのノードには cloud.google.com/gke-image-streaming: "true" ラベルが追加されます。GKE Standard では、特定のノードプールでイメージ ストリーミングを有効または無効にして、イメージ ストリーミングを使用するノードと使用しないノードが混在する場合は、Deployment でノードセレクタを使用して、イメージ ストリーミングを使用するノードで GKE がワークロードをスケジュールするかどうかを制御できます。

次の例では、イメージ ストリーミングが有効になっているクラスタで、大きなコンテナ イメージを使用する Deployment をスケジュールします。後で、イメージ ストリーミングを有効にせずにイメージを pull する場合とパフォーマンスを比較します。

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

    gcloud container clusters create CLUSTER_NAME \
        --zone=COMPUTE_ZONE \
        --enable-image-streaming \
        --image-type="COS_CONTAINERD"
    
  2. クラスタの認証情報を取得します。

    gcloud container clusters get-credentials CLUSTER_NAME \
        --zone=COMPUTE_ZONE
    
  3. 次のマニフェストを frontend-deployment.yaml として保存します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: frontend
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: guestbook
          tier: frontend
      template:
        metadata:
          labels:
            app: guestbook
            tier: frontend
        spec:
          containers:
          - name: php-redis
            image: us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5
            env:
            - name: GET_HOSTS_FROM
              value: "dns"
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 80
    

    gb-frontend コンテナ イメージのサイズは 327 MB です。

  4. マニフェストをクラスタに適用します。

    kubectl apply -f frontend-deployment.yaml
    
  5. GKE が Deployment を作成したことを確認します。

    kubectl get pods -l app=guestbook
    

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

    NAMESPACE    NAME                          READY    STATUS       RESTARTS    AGE
    default      frontend-64bcc69c4b-pgzgm     1/1      Completed    0           3s
    
  6. Kubernetes のイベントログを取得して、イメージの pull イベントを確認します。

    kubectl get events --all-namespaces
    

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

    NAMESPACE  LAST SEEN  TYPE    REASON          OBJECT                                                 MESSAGE
    default    11m        Normal  Pulling         pod/frontend-64bcc69c4b-pgzgm                          Pulling image "us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5"
    default    11m        Normal  Pulled          pod/frontend-64bcc69c4b-pgzgm                          Successfully pulled image "us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5" in 1.536908032s
    default    11m        Normal  ImageStreaming  node/gke-riptide-cluster-default-pool-f1552ec4-0pjv    Image us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5 is backed by image streaming.
    ...
    

    この出力で:

    • Pulled イベントは、イメージ ストリーミングによるイメージの pull にかかった時間を示しています。
    • ImageStreaming イベントは、ノードがイメージ ストリーミングを使用してコンテナ イメージを提供していることを示しています。

標準的なイメージの pull とパフォーマンスを比較する

このオプションの例では、イメージ ストリーミングを無効にして新しいクラスタを作成し、frontend Deployment をデプロイして、イメージ ストリーミングのパフォーマンスを比較します。

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

    gcloud container clusters create CLUSTER2_NAME\
        --zone=COMPUTE_ZONE \
        --image-type="COS_CONTAINERD"
    
  2. クラスタの認証情報を取得します。

    gcloud container clusters get-credentials CLUSTER2_NAME \
        --zone=COMPUTE_ZONE
    
  3. 上記の例の frontend Deployment をデプロイします。

    kubectl apply -f frontend-deployment.yaml
    
  4. Kubernetes イベントログを取得します。

    kubectl get events --all-namespaces
    

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

     NAMESPACE  LAST SEEN  TYPE    REASON     OBJECT                             MESSAGE
     default    87s        Normal  Pulled     pod/frontend-64bcc69c4b-qwmfp      Successfully pulled image "us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5" in 23.929723476s
    

    GKE がイメージ全体を pull するまでにかかった時間に注目してください。この出力例では、24 秒ほどかかっています。イメージ ストリーミングを有効にすると、GKE はワークロードの開始に必要なイメージデータを pull するのに 1.5 秒しかかかりません。

クリーンアップ

料金が発生しないようにするには、上記の例で作成したクラスタを削除します。

gcloud container clusters delete CLUSTER_NAME CLUSTER2_NAME

イメージ ストリーミングを無効にする

GKE Autopilot を使用する場合、個々のクラスタでイメージ ストリーミングを無効にすることはできません。Container File System API を無効にすると、プロジェクト全体でイメージ ストリーミングが無効になります。

GKE Standard クラスタを使用する場合は、以降のセクションで説明するように、個々のクラスタまたは特定のノードプールでイメージ ストリーミングを無効にできます。

GKE Standard クラスタでイメージ ストリーミングを無効にする

既存の GKE Standard クラスタでは、gcloud CLI または Google Cloud コンソールを使用してイメージ ストリーミングを無効にできます。

gcloud

既存のクラスタでイメージ ストリーミングを無効にするには、次のコマンドを実行します。

gcloud container clusters update CLUSTER_NAME \
    --no-enable-image-streaming

Console

  1. Google Cloud コンソールで [Google Kubernetes Engine] ページに移動します。

    Google Kubernetes Engine に移動

  2. 変更するクラスタの名前をクリックします。

  3. [クラスタ] ページの [機能] で、[イメージ ストリーミング] の横にある をクリックします。

  4. [イメージ ストリーミングの編集] ダイアログ ボックスで、[イメージ ストリーミングを有効にする] チェックボックスをオフにします。

  5. [変更を保存] をクリックします。

イメージ ストリーミングの設定を変更する場合、クラスタレベルで更新するとメンテナンスの可用性が考慮されますが、ノードプール レベルでは考慮されません。

この変更を行うにはノードを再作成する必要があります。これにより、実行中のワークロードが中断する可能性があります。この特定の変更について詳しくは、ノードのアップグレード戦略を使用してノードを再作成し、メンテナンス ポリシーに準拠する手動変更の表で対応する行を確認してください。ノードの更新の詳細については、ノードの更新による中断の計画をご覧ください。

新しいノードプールの場合

新しいノードプールを作成するときにイメージ ストリーミングを無効にするには、次のようなコマンドで --no-enable-image-streaming フラグを指定します。

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --zone=COMPUTE_ZONE \
    --no-enable-image-streaming

既存のノードプールの場合

既存のノードプールでイメージ ストリーミングを無効にするには、次のコマンドを実行します。

gcloud container node-pools update NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --no-enable-image-streaming

イメージ ストリーミングの設定を変更する場合、クラスタレベルで更新するとメンテナンスの可用性が考慮されますが、ノードプール レベルでは考慮されません。

この変更を行うにはノードを再作成する必要があります。これにより、実行中のワークロードが中断する可能性があります。この特定の変更について詳しくは、メンテナンス ポリシーを尊重せずにノードのアップグレード戦略を使用してノードを再作成する手動変更の表で対応する行をご覧ください。ノードの更新の詳細については、ノードの更新による中断の計画をご覧ください。

イメージ ストリーミングのメモリ予約

GKE は、ノードシステム コンポーネントの実行用に予約されているメモリに加えて、イメージ ストリーミングのメモリリソースを予約します。 イメージ ストリーミング用に追加の CPU リソースは予約しません。GKE Standard クラスタでは、この予約により、Pod でリクエストできるメモリリソースが変更されます。GKE Autopilot では、GKE がシステム割り当てを管理するため、ワークロードのスケジューリングには影響しません。

GKE がノード コンポーネント用に行うメモリ予約の詳細については、Standard クラスタのアーキテクチャをご覧ください。

イメージ ストリーミングを使用するノードでは、GKE は新しい予約用に次の追加メモリを予約します。

  • メモリが 1 GiB 未満のマシンの場合は追加メモリなし
  • 最初の 4 GiB のメモリの 1%
  • 次の 4 GiB のメモリの 0.8%(最大 8 GiB)
  • 次の 8 GiB のメモリの 0.4%(最大 16 GB)
  • 次の 112 GiB のメモリの 0.24%(最大 128 GiB)
  • 128 GiB を超えるメモリの 0.08%

トラブルシューティング

GKE がイメージ ストリーミング ファイルシステムを使用しない

GKE イベントログにイメージ ストリーミング イベントがない場合は、イメージがリモート ファイル システムでバックアップされていません。GKE が以前にイメージをノードで pull していた場合、以降の pull でイメージ ストリーミングではなく、イメージのローカル キャッシュが使用されるため、これは想定された動作です。この状態を確認するには、Pod の Pulled イベントの Message フィールドで Container image IMAGE_NAME already present on machine を探します。

ノードの最初のイメージ pull でイメージ ストリーミング イベントがない場合は、イメージ ストリーミングの要件を満たしていることを確認してください。要件を満たしている場合は、イメージ ストリーミング サービス(gcfsd)のログを確認することで問題を診断できます。

  1. Google Cloud コンソールの [ログ エクスプローラ] ページに移動します。

    [ログ エクスプローラ] に移動

  2. [クエリ] フィールドに次のクエリを規定します。

    logName="projects/PROJECT_ID/logs/gcfsd"
    resource.labels.cluster_name="CLUSTER_NAME"
    

    以下を置き換えます。

    • PROJECT_ID: プロジェクトの名前。
    • CLUSTER_NAME: クラスタの名前。
  3. [クエリを実行] をクリックします。

ログ エクスプローラを使用して gcfsd ログを確認することもできます。

  1. Google Cloud コンソールのログ エクスプローラに移動します。

    [ログ エクスプローラ] に移動

  2. [クエリ] フィールドに次のクエリを規定します。

    logName="projects/PROJECT_ID/logs/gcfsd"
    

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

PermissionDenied

gcfsd ログに次のようなエラー メッセージが表示される場合、ノードに正しい API スコープがありません。GKE は、イメージ ストリーミングを使用せずに、ワークロード用のコンテナ イメージを pull します。

level=fatal msg="Failed to create a Container File System client: rpc error:
code = PermissionDenied desc = failed to probe endpoint: rpc error: code = PermissionDenied
desc = Request had insufficient authentication scopes."

この問題は、ノードに正しいスコープを設定してイメージ ストリーミングを使用できるようにすることで解決できます。次のコマンドのように、devstorage.read_only スコープをクラスタまたはノードプールに追加します。

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --zone=COMPUTE_ZONE \
    --image-type="COS_CONTAINERD" \
    --enable-image-streaming \
    --scope="https://www.googleapis.com/auth/devstorage.read_only"

FailedPrecondition

code = FailedPrecondition というエラー メッセージが表示された場合は、イメージがイメージ ストリーミング リモート ファイル システムにインポートされていません。

このエラーは、既存のノードプールでイメージ ストリーミングを使用しようとしたときに発生することがあります。ノードプール内のノードにコンテナ イメージがすでに存在する場合、GKE はイメージ ストリーミングを使用してローカル イメージを取得するのではなく、ローカルにあるイメージを使用します。

この問題を解決するには、次のことを行います。

  • 数分待ってから、ワークロードを再度デプロイします。
  • 新しいノードまたはノードプールを追加し、そのノードでワークロードをスケジュールします。

InvalidArgument

code=InvalidArgument というエラー メッセージが表示された場合は、ワークロードが使用しているコンテナ イメージがイメージ ストリーミングの対象ではありません。イメージが要件を満たしていることを確認します。イメージが Artifact Registry にない場合は、Artifact Registry への移行を試してください。

backend.FileContent failed

イメージ ストリーミングを有効にしてコンテナ ファイルを読み取ると、次のエラーが表示されることがあります。

level=error msg="backend.FileContent failed" error="rpc error: code = ResourceExhausted desc = Quota exceeded for quota metric 'Content requests per project per region' and limit 'Content requests per project per region per minute per region' of service 'containerfilesystem.googleapis.com' for consumer 'project_number:PROJECT_NUMBER'." layer_id="sha256:1234567890" module=gcfs_backend offset=0 path=etc/passwd size=4096

このエラーは、プロジェクトがリモート コンテナ ファイル システム サービスからファイルを読み取るために必要な割り当てを超えたことを示します。この問題を解決するには、次の割り当てを増やします

  • リージョンごとに 1 分あたり 1 プロジェクト、1 リージョンのコンテンツ リクエスト数
  • 1 リージョンあたり、1 プロジェクトあたりのコンテンツ リクエスト数

GKE によるデータのストリーミングなしでのイメージ ダウンロード

顧客管理の暗号鍵(CMEK)を使用したコンテナ イメージは、GKE バージョン 1.25.3-gke.1000 以降でのみイメージ ストリーミングの対象になります。重複するレイヤを含むコンテナ イメージは、イメージ ストリーミングの対象になりません。詳細については、制限事項をご覧ください。

空のレイヤまたは重複するレイヤの確認

コンテナ イメージに空のレイヤまたは重複するレイヤがあるかどうかを確認するには、次のコマンドを実行します。

docker inspect IMAGE_NAME

IMAGE_NAME をコンテナ イメージの名前に置き換えます。

コマンドの出力で、"Layers" のエントリを確認します。

いずれかのエントリが次の "sha256" 出力と完全に一致する場合、コンテナ イメージには空のレイヤがあり、イメージ ストリーミングの対象になりません。

"Layers": [
  ...
  "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4",
  ...
]

次の例のような重複するエントリがある場合、コンテナ イメージには重複するレイヤがあり、イメージ ストリーミングの対象になりません。

"Layers": [
  "sha256:28699c71935fe3ffa56533db44ad93e5a30322639f7be70d5d614e06a1ae6d9b",
  ...
  "sha256:28699c71935fe3ffa56533db44ad93e5a30322639f7be70d5d614e06a1ae6d9b",
  ...
]

シンボリック リンク ファイルで mv コマンドと renameat2 システムの呼び出しが失敗する

バージョン 1.25 以降を実行している GKE ノードでは、イメージ ストリーミングが有効になっていると、コンテナ イメージのシンボリック リンク ファイルで mv コマンドと renameat2 システムの呼び出しが行えず、「デバイスまたはアドレスがありません」というエラー メッセージが返される場合があります。この問題は、最近の Linux カーネルの回帰が原因で発生します。

これらのシステム呼び出しは一般的ではないため、大部分のイメージはこの問題の影響を受けません。通常、この問題は、アプリケーションの実行とファイル移動の準備ができているコンテナの初期化ステージで発生します。イメージをローカルでテストすることはできないため、テスト環境でイメージ ストリーミングを使用して、本番環境でイメージを使用する前に問題を見つけることをおすすめします。

この修正は、次の GKE パッチ バージョンで入手できます。

  • 1.25: 1.25.14-gke.1351000 以降
  • 1.26: 1.26.9-gke.1345000 以降
  • 1.27: 1.27.6-gke.100 以降
  • 1.28: 1.28.1-gke.1157000 以降

また、該当のワークロードでこの問題の影響を軽減するには、renameat2 システム呼び出しにつながるコードの置き換えを試してください。コードを変更できない場合は、ノードプールでイメージ ストリーミングを無効にすることで、問題を軽減する必要があります。