イメージ pull のトラブルシューティング


このページでは、Google Kubernetes Engine(GKE)のイメージ pull プロセスに関する問題を解決する方法について説明します。イメージ ストリーミングを使用している場合は、イメージ ストリーミングのトラブルシューティングをご覧ください。このページでは、標準のイメージ pull について説明します。

このページは、アプリが正常にデプロイされるようにしたいアプリ デベロッパー、イメージの pull 失敗の根本原因を把握し、プラットフォーム構成を確認したいプラットフォーム管理者とオペレーターを対象としています。コンテンツで参照する一般的なロールとタスク例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。 Google Cloud

イメージの pull プロセスは、Kubernetes(GKE を含む)がレジストリからコンテナ イメージを取得する方法です。イメージの pull に失敗すると、アプリの動作が遅くなったり、アプリがまったく動作しなくなったりすることがあります。

アプリが機能しない原因がイメージの pull であるかどうかを判断するには、このページで関連するエラー メッセージを探して理解し、イメージの pull の失敗を診断します。次に、イメージの pull が失敗する一般的な原因について学びます。

  • 認証設定: クラスタに、コンテナ イメージ レジストリにアクセスするために必要な権限がありません。
  • ネットワーク接続: DNS の問題、ファイアウォール ルール、ネットワーク分離を使用するクラスタでのインターネット アクセスの欠如が原因で、クラスタがレジストリに接続できない。
  • レジストリでイメージが見つかりません: 指定されたイメージ名またはタグが正しくないか、イメージが削除されているか、レジストリを使用できません。
  • パフォーマンスの制限: イメージサイズが大きい、ディスク I/O が遅い、ネットワークが輻輳している場合、pull が遅くなるかタイムアウトが発生する可能性があります。
  • 互換性のないイメージ アーキテクチャ: イメージは、GKE ノードプールとは異なる CPU アーキテクチャ用にビルドされています。
  • 互換性のないスキーマ バージョン: v1 Docker スキーマで containerd 2.0 以降を使用している可能性があります。これはサポートされていません。

特定のイベント メッセージが表示されている場合は、このページでそのメッセージを見つけて、記載されているトラブルシューティングの手順に沿って対応してください。メッセージが表示されていない場合は、次のセクションを順番に確認してください。問題が解決しない場合は、Cloud カスタマーケアにお問い合わせください

イメージ pull について

トラブルシューティングを開始する前に、イメージのライフサイクルとイメージをホストできる場所について理解しておくと役に立ちます。

イメージのライフサイクル

Pod を作成すると、kubelet は Pod 定義を受け取ります。この定義には、イメージの仕様が含まれています。kubelet は、このイメージに基づいてコンテナを実行するためにこのイメージを必要とします。イメージを pull する前に、kubelet はコンテナ ランタイムをチェックして、イメージが存在するかどうかを確認します。kubelet は、Pod のイメージ pull ポリシーも確認します。イメージがコンテナ ランタイムのキャッシュにない場合、またはイメージの pull ポリシーで必要とされる場合は、kubelet はコンテナ ランタイム(containerd)に、指定されたイメージをレジストリから pull するよう指示します。イメージの pull に失敗すると、Pod 内のコンテナが起動できなくなります。

イメージの pull が正常に完了すると、コンテナ ランタイムはイメージを解凍して、コンテナの読み取り専用のベース ファイル システムを作成します。コンテナ ランタイムはこのイメージを保存し、実行中のコンテナが参照している限り、イメージは存在し続けます。実行中のコンテナがイメージを参照していない場合、イメージはガベージ コレクションの対象になり、最終的には kubelet によって削除されます。

画像ホスティング オプション

画像をホストするには、次のいずれかの方法を使用することをおすすめします。

  • Artifact Registry: Artifact Registry は、Google のフルマネージド パッケージ マネージャーです。Artifact Registry は他の Google Cloudサービスと緊密に統合され、きめ細かいアクセス制御を提供します。詳細については、Artifact Registry ドキュメントのコンテナ イメージの操作をご覧ください。

  • 自己ホスト型レジストリ: 自己ホスト型レジストリでは、より細かい制御が可能ですが、レジストリの管理も必要です。Artifact Registry で満たせない特定のコンプライアンス要件またはセキュリティ要件がある場合は、このオプションを検討してください。

イメージの pull エラーを診断する

イメージの pull エラーを診断するには、次のセクションで説明する詳細な調査を行います。

  1. Pod のステータスとイベントを表示する。
  2. ステータスの意味を理解する。
  3. イベント メッセージを使用して、イメージの pull 失敗の原因を特定します。
  4. ログ エクスプローラのログを表示する。

Pod のステータスとイベントを表示する

イメージの pull が失敗したことを確認できるように、GKE は Pod の次のステータスを記録します。

  • ImagePullBackOff
  • ErrImagePull
  • ImageInspectError
  • InvalidImageName
  • RegistryUnavailable
  • SignatureValidationFailed

ImagePullBackOffErrImagePull は、これらのステータスの中で最も一般的なものです。

これらのステータスに加えて、Kubernetes イベントはイメージ pull の失敗の原因を特定するのに役立ちます。

イメージの pull が失敗しているかどうかを確認するには、ステータス メッセージを確認してから、次のいずれかのオプションを選択してイベント メッセージを読み取ります。

Console

次の手順を行います。

  1. Google Cloud コンソールの [ワークロード] ページに移動します。

    [ワークロード] に移動

  2. 調査するワークロードを選択します。確認する必要があるワークロードがわからない場合は、[ステータス] 列を確認します。この列には、問題が発生しているワークロードが表示されます。

  3. ワークロードの [詳細] ページで、[マネージド Pod] セクションを見つけて、イメージの pull 失敗を示すステータスの Pod の名前をクリックします。

  4. Pod の [詳細] ページで、[イベント] タブをクリックします。

  5. 表内の情報を確認します。[メッセージ] 列には、Kubernetes イベントが一覧表示されます。このイベントには、失敗したイメージの pull に関する詳細情報が表示されます。[理由] 列には、Pod のステータスが表示されます。

kubectl

次の手順を行います。

  1. Pod のステータスを表示します。

    kubectl get pods -n NAMESPACE
    

    NAMESPACE は、Pod が実行される Namespace に置き換えます。

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

    NAME         READY   STATUS       RESTARTS      AGE
    POD_NAME_1   2/2     Running      0             7d5h
    POD_NAME_2   0/1     ErrImagePull 0             7d5h
    

    Status 列には、イメージの pull に失敗した Pod が表示されます。

  2. イメージの pull に失敗した Pod のイベントを表示します。

    kubectl describe POD_NAME -n NAMESPACE
    

    POD_NAME は、前の手順で特定した Pod の名前に置き換えます。

    Events セクションには、失敗したイメージの pull 中に発生した事象の詳細が表示されます。

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

    ...
    Events:
      Type    Reason    Age               From           Message
      ----    ------    ----              ----           -------
      Warning  Failed   5m (x4 over 7m)   kubelet, NODE  Failed to pull image "IMAGE_ADDRESS": rpc error: code = Unknown desc = Error response from daemon: repository IMAGE_ADDRESS not found
      Warning  Failed   5m (x4 over 7m)   kubelet, NODE  Error: ErrImagePull
      Normal   BackOff  5m (x6 over 7m)   kubelet, NODE  Back-off pulling image "IMAGE_ADDRESS"
      Warning  Failed   2m (x20 over 7m)  kubelet, NODE  Error: ImagePullBackOff
    

    この出力で、IMAGE_ADDRESS はイメージの完全なアドレスです。例: us-west1-docker.pkg.dev/my-project/my-repo/test:staging

ステータスの意味を理解する

各ステータスの意味について詳しくは、以下の説明をご覧ください。

  • ImagePullBackOff: kubelet がイメージの pull に失敗しましたが、最大 5 分間の遅延(またはバックオフ)で再試行を続けます。
  • ErrImagePull: イメージの pull プロセス中に発生した一般的な復元不可能なエラー。
  • ImageInspectError: コンテナ ランタイムでコンテナ イメージを検査しようとしたときに問題が発生しました。
  • InvalidImageName: Pod 定義で指定されたコンテナ イメージの名前が無効です。
  • RegistryUnavailable: レジストリにアクセスできません。通常、これはネットワーク接続の問題です。
  • SignatureValidationFailed: コンテナ イメージのデジタル署名を確認できませんでした。

イベント メッセージを使用して、イメージの pull 失敗の原因を特定する

次の表に、イメージの pull の失敗に関連するイベント メッセージと、これらのメッセージのいずれかが表示された場合に行う必要があるトラブルシューティングの手順を示します。

画像の pull エラーに関連するメッセージには、多くの場合、次のような接頭辞が付いています。

Failed to pull image "IMAGE_ADDRESS": rpc error: code = CODE = failed to pull and unpack image "IMAGE_ADDRESS": failed to resolve reference "IMAGE_ADDRESS":

このメッセージには次の値が含まれます。

  • IMAGE_ADDRESS: イメージの完全なアドレス。例: us-west1-docker.pkg.dev/my-project/my-repo/test:staging
  • CODE: ログ メッセージに関連付けられたエラーコード。たとえば、NotFoundUnknown です。

イメージの pull が失敗する原因によっては、関連するイベント メッセージがない場合があります。次の表に記載されているイベント メッセージが表示されない場合でも、画像の取得に関する問題が解決しない場合は、このページの残りの部分をお読みになることをおすすめします。

イベント メッセージ 詳細なトラブルシューティング
認証
  • Failed to authorize: failed to fetch oauth token: unexpected status: 403 Forbidden
  • Pulling from host HOST_NAME failed with status code: 403 Forbidden
  • Unexpected status code [manifests 1.0]: 401 Unauthorized

ネットワーク接続
  • Failed to do request: Head "IMAGE_ADDRESS": dial tcp: lookup gcr.io on REGISTRY_IP_ADDRESS: server misbehaving
  • Failed to start Download and install k8s binaries and configurations
  • Failed to do request: Head "IMAGE_ADDRESS": dial tcp REGISTRY_IP_ADDRESS: i/o timeout
イメージが見つかりません
  • "IMAGE_ADDRESS": not found
  • Failed to copy: httpReadSeeker: failed open: could not fetch content descriptor sha256:SHA_HASH (application/vnd.docker.container.image.v1+json) from remote: not found
画像のタイムアウト
  • Unknown desc = context canceled
互換性のないスキーマ
  • Failed to get converter for "IMAGE_ADDRESS": Pulling Schema 1 images have been deprecated and disabled by default since containerd v2.0. As a workaround you may set an environment variable `CONTAINERD_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE=1`, but this will be completely removed in containerd v2.1.

ログ エクスプローラのログを表示する

過去のイメージ pull イベントを調べたり、イメージ pull の失敗を他のコンポーネント アクティビティと関連付けたりするには、ログ エクスプローラでログを表示します。

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

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

  2. クエリペインに次のクエリを入力します。

    log_id("events")
    resource.type="k8s_pod"
    resource.labels.cluster_name="CLUSTER_NAME"
    jsonPayload.message=~"Failed to pull image"
    

    CLUSTER_NAME は、イメージの pull エラーのある Pod が実行されているクラスタの名前に置き換えます。

  3. [クエリを実行] をクリックして結果を確認します。

認証設定を調査する

以降のセクションでは、GKE 環境にリポジトリからイメージを pull するための適切な認証設定があることを確認します。

認証の問題がイメージの pull の問題の原因となっているかどうかを確認するには、次のセクションで説明する調査を行います。

  1. イメージへのアクセス権を確認します。
  2. imagePullSecret の構成と Deployment 仕様を確認します。
  3. 非公開 Artifact Registry リポジトリに対するノードのアクセス スコープを確認する
  4. Artifact Registry にアクセスするための VPC Service Controls の設定を確認します。

画像へのアクセスを確認する

403 Forbidden イメージの pull エラーが発生した場合は、必要なコンポーネントがコンテナ イメージにアクセスできることを確認します。

必要なアクセス権を付与するために必要なロールを確認して適用する方法は、イメージを保存するリポジトリの種類によって異なります。アクセス権を確認して付与するには、次のいずれかのオプションを選択します。

Artifact Registry

imagePullSecret を使用する場合、Secret にリンクされているサービス アカウントには、リポジトリに対する読み取り権限が必要です。それ以外の場合は、ノードプールのサービス アカウントに権限が必要です。

  1. IAM のドキュメントの手順に沿って、サービス アカウントに割り当てられたロールを表示します。
  2. サービス アカウントに Artifact Registry 読み取りroles/artifactregistry.reader)IAM ロールがない場合は、ロールを付与します。

    gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \
        --location=REPOSITORY_LOCATION \
        --member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
        --role="roles/artifactregistry.reader"
    

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

    • REPOSITORY_NAME: Artifact Registry リポジトリの名前。
    • REPOSITORY_LOCATION: Artifact Registry リポジトリのリージョン
    • SERVICE_ACCOUNT_EMAIL: 必要なサービス アカウントのメールアドレス。アドレスがわからない場合は、gcloud iam service-accounts list コマンドを使用して、プロジェクト内のすべてのサービス アカウントのメールアドレスを一覧表示します。

Container Registry

imagePullSecret を使用する場合、Secret にリンクされているサービス アカウントには、リポジトリに対する読み取り権限が必要です。それ以外の場合は、ノードプールのサービス アカウントに権限が必要です。

  1. IAM のドキュメントの手順に沿って、サービス アカウントに割り当てられたロールを表示します。
  2. サービス アカウントに ストレージ オブジェクト閲覧者roles/storage.objectViewer)IAM ロールがない場合は、サービス アカウントがバケットから読み取れるようにロールを付与します。

    gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
        --member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
        --role=roles/storage.objectViewer
    

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

    • SERVICE_ACCOUNT_EMAIL: 必要なサービス アカウントのメールアドレス。gcloud iam service-accounts list コマンドを使用して、プロジェクト内のすべてのサービス アカウントを一覧表示できます。
    • BUCKET_NAME: イメージを含む Cloud Storage バケットの名前。gcloud storage ls コマンドを使用すると、プロジェクト内のすべてのバケットを一覧表示できます。

レジストリ管理者が、Container Registry ではなく gcr.io ドメインのイメージを保存するように Artifact Registry で gcr.io リポジトリを設定している場合は、Container Registry ではなく、Artifact Registry に対する読み取りアクセス権をユーザーに付与する必要があります。

セルフホスト型レジストリ

セルフホスト レジストリの構成方法によっては、イメージにアクセスするために鍵、証明書、またはその両方が必要になる場合があります。

鍵を使用する場合は、imagePullSecret を使用します。imagePullSecret は、セルフホスト レジストリへのアクセスに必要な認証情報をクラスタに安全に提供する方法です。imagePullSecret の構成方法の例については、Kubernetes ドキュメントの Pull an Image from a Private Registry をご覧ください。

レジストリへの HTTPS 接続を保護するには、リモート サーバーへの接続の完全性を確認する証明書も必要になる場合があります。Secret Manager を使用して独自の自己署名証明機関を管理することをおすすめします。詳細については、プライベート CA 証明書を使用して限定公開レジストリにアクセスするをご覧ください。

imagePullSecret の構成と Deployment 仕様を確認する

imagePullSecret を使用する場合は、イメージの pull 用の認証情報を保持する Secret を作成し、すべての Deployment で定義した Secret を指定していることを確認します。詳細については、Kubernetes ドキュメントの Pod で imagePullSecrets を指定するをご覧ください。

非公開 Artifact Registry リポジトリに対するノードのアクセス スコープを確認する

コンテナ イメージを限定公開の Artifact Registry リポジトリに保存している場合、ノードに正しいアクセス スコープがない可能性があります。この場合、401 Unauthorized イメージの pull エラーが発生することがあります。

アクセス スコープを確認して、必要に応じてアクセスを許可する手順は次のとおりです。

  1. Pod を実行しているノードを特定します。

    kubectl describe pod POD_NAME | grep "Node:"
    

    POD_NAME は、イメージの pull に失敗した Pod の名前に置き換えます。

  2. 前の手順で特定したノードに正しいストレージ スコープがあることを確認します。

    gcloud compute instances describe NODE_NAME \
        --zone="COMPUTE_ZONE \
        --format="flattened(serviceAccounts[].scopes)"
    

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

    • NODE_NAME: 前の手順で特定したノードの名前。
    • COMPUTE_ZONE: ノードが属する Compute Engine ゾーン

    出力には、次のいずれかのアクセス スコープが含まれている必要があります。

    • serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/devstorage.read_only
    • serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/cloud-platform

    これらのスコープのいずれかがノードに含まれていない場合、イメージの pull は失敗します。

  3. ノードが属するノードプールを十分なスコープで再作成します。既存のノードを変更できないため、正しいスコープでノードを再作成する必要があります。

    gke-default スコープでノードプールを作成することをおすすめします。このスコープには、次のスコープへのアクセス権が付与されます。

    • https://www.googleapis.com/auth/devstorage.read_only
    • https://www.googleapis.com/auth/logging.write
    • https://www.googleapis.com/auth/monitoring
    • https://www.googleapis.com/auth/service.management.readonly
    • https://www.googleapis.com/auth/servicecontrol
    • https://www.googleapis.com/auth/trace.append

    gke-default スコープが適切でない場合は、ノードプールに devstorage.read_only スコープを付与します。これにより、読み取りデータへのアクセスのみが許可されます。

    gke-default

    gke-default スコープを持つノードプールを作成します。

    gcloud container node-pools create NODE_POOL_NAME \
        --cluster=CLUSTER_NAME \
        --zone=COMPUTE_ZONE \
        --scopes="gke-default"
    

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

    • NODE_POOL_NAME: 新しいノードプールの名前。
    • CLUSTER_NAME: 既存のクラスタの名前。
    • COMPUTE_ZONE: 新しいノードプールが属する Compute Engine ゾーン。

    devstorage.read_only

    devstorage.read_only スコープを持つノードプールを作成します。

    gcloud container node-pools create NODE_POOL_NAME \
        --cluster=CLUSTER_NAME \
        --zone=COMPUTE_ZONE \
        --scopes="https://www.googleapis.com/auth/devstorage.read_only"
    

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

    • NODE_POOL_NAME: 新しいノードプールの名前。
    • CLUSTER_NAME: 既存のクラスタの名前。
    • COMPUTE_ZONE: 新しいノードプールが属する Compute Engine ゾーン。

Artifact Registry にアクセスするための VPC Service Controls の設定を確認する

VPC Service Controls を使用している場合は、サービス境界で Artifact Registry へのアクセスが許可されていることを確認します。詳細については、Artifact Registry のドキュメントでサービス境界でリポジトリを保護するをご覧ください。

ネットワーク接続を調査する

イメージの pull 中にネットワーク接続が失われると、プロセスが完了しないことがあります。

ネットワーク接続の問題がイメージの pull の問題の原因になっているかどうかを確認するには、次のセクションで説明する調査を行います。

  1. DNS 解決を調査する。
  2. ファイアウォールの構成を調査します。
  3. 外部レジストリ エンドポイントのインターネット接続を調査します。
  4. Google API への接続がタイムアウトしているかどうかを調査します。

DNS 解決を調査する

server misbehaving イメージの pull エラーが表示された場合は、DNS 解決がイメージの pull の失敗の原因である可能性があります。

DNS 解決に関する問題を調査するには、次のソリューションを試してください。

  1. メタデータ サーバーのトラブルシューティングを行います。ノードのメタデータ サーバーは、すべての DNS クエリを解決します。このサーバーに関連する問題が発生すると、名前解決が中断され、リポジトリへの接続が妨げられ、イメージの pull が失敗する可能性があります。
  2. DNS 解決に Cloud DNS を使用する場合は、Cloud DNS マネージド限定公開ゾーン、転送ゾーン、ピアリング ゾーン、レスポンス ポリシーが正しく構成されていることを確認します。これらの領域で構成ミスがあると、DNS 解決が中断する可能性があります。Cloud DNS の詳細については、GKE 向け Cloud DNS の使用をご覧ください。GKE で Cloud DNS のトラブルシューティングを行う方法については、GKE で Cloud DNS のトラブルシューティングを行うをご覧ください。
  3. DNS 解決に kube-dns を使用している場合は、正しく機能していることを確認します。kube-dns のトラブルシューティングについては、GKE で kube-dns のトラブルシューティングを行うをご覧ください。
  4. クラスタのノードに外部 IP アドレスがない場合は(ネットワーク分離を使用している場合、これは一般的です)、クラスタで使用されるサブネットで限定公開の Google アクセスを有効にして、ネットワーク要件を満たしていることを確認します。Cloud NAT を使用している場合、Google Cloud は限定公開の Google アクセスを自動的に有効にします。

ファイアウォール構成を調査する

ファイアウォールの問題が原因でイメージの pull が失敗すると、次のエラー メッセージが表示されることがあります。

Failed to start Download and install k8s binaries and configurations

ファイアウォールの問題を診断する

Standard クラスタを使用しているときに、ファイアウォールの問題がイメージの pull の問題の原因となっているかどうかを確認するには、次の操作を行います。

  1. SSH を使用して、問題が発生しているノードに接続します。

    gcloud compute ssh NODE_NAME --zone=ZONE_NAME
    

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

  2. kube-node-installation.service サービスと kube-node-configuration.service サービスの最新のログを、kube-node-installation_status.txtkube-node-configuration_status.txt という名前のテキスト ファイルに送信します。

    systemctl status kube-node-installation.service > kube-node-installation_status.txt
    systemctl status kube-node-configuration.service > kube-node-configuration_status.txt
    

    これらのログにイメージの pull が失敗したときの情報が含まれていない場合は、ログの完全なコピーを生成します。

    sudo journalctl -u kube-node-installation.service > kube-node-installation_logs.txt
    sudo journalctl -u kube-node-configuration.service > kube-node-configuration_logs.txt
    
  3. kube-node-installation_status.txt ファイルと kube-node-configuration_status.txt ファイルの内容を確認します。出力に i/o timeout が表示された場合は、ファイアウォールに問題がある可能性があります。

ファイアウォールの構成に関する問題を解決する

ファイアウォールに関する問題を解決するには、次の解決策を試してください。

  1. ネットワーク トラフィックをブロックしているファイアウォール ルールを特定して解決します。たとえば、イメージを保存するレジストリへのトラフィックをブロックするルールを設定できます。

    1. VPC フローログにアクセスします。

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

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

      2. クエリペインに次のクエリを入力します。

        resource.type="gce_subnetwork"
        logName="projects/PROJECT_ID/logs/[compute.googleapis.com%2Fvpc_flows](http://compute.googleapis.com%2Fvpc_flows)"
        resource.labels.subnetwork_name="SUBNET_NAME",
        

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

        • PROJECT_ID: Google Cloud プロジェクトの ID。
        • SUBNET_NAME: サブネットワークの名前。

        詳細については、VPC ドキュメントのクエリを使用してフローログにアクセスするをご覧ください。

    2. 必要なトラフィックをブロックしているファイアウォール ルールが見つかった場合は、更新します。

  2. クラスタのノードに外部 IP アドレスがない場合は(ネットワーク分離を使用している場合、これは一般的です)、クラスタで使用されるサブネットで限定公開の Google アクセスを有効にして、ネットワーク要件を満たしていることを確認します。Cloud NAT を使用している場合、Google Cloud は限定公開の Google アクセスを自動的に有効にします。

外部レジストリ エンドポイントのインターネット接続を調査する

ネットワーク構成でトラフィックが外部レジストリ エンドポイントを経由する場合、そのエンドポイントにインターネット接続がない可能性があります。エンドポイントにアクセス権がない場合、イメージの pull が失敗し、i/o timeout イメージ pull エラーが表示されることがあります。

外部レジストリ エンドポイントからレジストリへのネットワーク接続を確認するには、ping または traceroute を使用します。

ping REGISTRY_ENDPOINT

または

traceroute REGISTRY_ENDPOINT

REGISTRY_ENDPOINT は、レジストリ エンドポイントに置き換えます。この値は、ホスト名または IP アドレスにできます。

接続にエラーがある場合は、VPC ルートを確認します。

  1. Google Cloud コンソールで、[ルート] に移動します。

    [ルート] に移動

  2. [優先度] 列を確認し、優先度が最も高いルートがレジストリにアクセスできるソースに転送されていることを確認します。値が小さいルートの方が優先されます。

Google API への接続がタイムアウトしているかどうかを調査する

ネットワーク分離を使用すると、Google API とサービスへの接続がタイムアウトし、i/o timeout イメージの pull エラーが発生することがあります。

このエラーは、ノードがレジストリからイメージを pull しようとしたときに、次のいずれかの API に到達できなかったために発生します。

  • containerregistry.googleapis.com
  • artifactregistry.googleapis.com

必要な API に接続できるようにするには、次のソリューションを試してください。

  1. 限定公開の Google アクセスを有効にします。外部 IP アドレスのないノードが Google API とサービスの外部 IP アドレスにアクセスするには、限定公開の Google アクセスが必要です。
  2. サポートされているドメインを使用します。
  3. ファイアウォール ポリシーを確認します。

    1. Google Cloud コンソールで、[ファイアウォール ポリシー] に移動します。

      [ファイアウォール ポリシー] に移動

    2. ポート 443 から 199.36.153.4/30199.36.153.8/30、または Google API とサービスで選択したドメインで使用される IP アドレス範囲への下り(外向き)TCP トラフィックをブロックするルールがあるかどうかを確認します。IP アドレス範囲 199.36.153.4/30199.36.153.8/30 は、限定公開の Google アクセスと制限付きの Google アクセスにそれぞれ使用されます。ポート 443 からこれらの範囲への TCP トラフィックは、Google API とサービスへのアクセス用です。

      このようなルールが見つかった場合は、下り(外向き)ファイアウォール ルールを作成して、そのようなトラフィックを許可します。

  4. Artifact Registry を使用する場合は、ネットワーク分離で Artifact Registry を使用する要件を環境が満たしていることを確認してください。

  5. 仮想 IP アドレス(VIP)(199.36.153.4/30 または 199.36.153.8/30)に VPC ルートが構成されていることを確認します。

    1. Google Cloud コンソールで、VPC ネットワークに移動します。

      [VPC ネットワーク] に移動

    2. [名前] 列で [default] をクリックします。

    3. VPC ネットワークの詳細ページで、[ルート] タブをクリックします。

    4. ルートテーブルを確認します。

      VPC ネットワークにデフォルト ルート(宛先 0.0.0.0/0 または ::0/0)が含まれ、そのルートのネクストホップがデフォルトのインターネット ゲートウェイ(ネットワークのデフォルト)である場合は、そのルートを VIP が Google API とサービスにアクセスするために使用します。

      デフォルト ルートを、ネクストホップがデフォルトのインターネット ゲートウェイではないカスタムルートに置き換えた場合は、カスタム ルーティングを使用して、Google API とサービスのルーティング要件を満たします。

kubelet がイメージを見つけられない理由を調査する

kubelet がイメージを見つけられない場合、image not found エラーが表示され、イメージの pull に失敗することがあります。

kubelet がイメージを見つけられるようにするには、次の解決策を試してください。

  1. Pod のマニフェストを調べて、イメージ名とイメージタグのスペルが正しいことを確認します。スペルミスや書式エラーがあると、イメージの pull が失敗します。
  2. イメージを保存したレジストリにイメージがまだ存在することを確認します。イメージにレジストリ フルパスがある場合は、使用している Docker レジストリにそのパスが存在することを確認します。イメージ名のみを指定した場合は、Docker Hub レジストリを確認してください。
  3. クラスタがネットワーク分離を使用している場合は、次の解決策を試します。
    1. 限定公開の Google アクセスを有効にする
    2. サービス境界が正しく構成されていることを確認します。

イメージ pull のタイムアウトやイメージ pull の遅延が発生する理由を調査する

GKE ワークロードに非常に大きなイメージを使用すると、イメージの pull がタイムアウトし、context cancelled エラーが発生する可能性があります。画像にはサイズの上限はありませんが、context cancelled エラーは多くの場合、画像のサイズが原因であることを示します。

また、画像の取得が失敗せず、通常よりもはるかに時間がかかることもあります。通常のイメージの pull 時間のベースラインを確認するには、Successfully pulled image ログエントリを確認します。たとえば、次のログ メッセージは、イメージの pull に 30.313387996 秒かかったことを示しています。

Successfully pulled image "IMAGE_ADDRESS" in 30.313387996s.

タイムアウトとイメージの pull の遅延には、多くの共通の原因があります。これらの問題を解決するには、次のソリューションを試してください。

  1. サービス停止がないか確認します。この問題が特定の期間にのみ発生する場合は、 Google Cloud サービス停止が発生していないか確認します。
  2. ディスクのパフォーマンスを確認します。ディスク I/O が遅いと、イメージの pull 時間が長くなる可能性があります。パフォーマンスを向上させるには、SSD を使用する永続ディスク(pd-ssd)へのアップグレードまたは大容量ディスクの使用を検討してください。詳細については、ディスク パフォーマンスに関する問題のトラブルシューティングをご覧ください。
  3. 画像サイズを小さくします。たとえば、一部のデータをコンテナ イメージから Persistent Volume に移動できます。
  4. イメージ キャッシュを利用して、Pod の起動時間を短縮します。GKE はノードにイメージをキャッシュに保存します。イメージの pull 中、コンテナ ランタイムは、キャッシュにまだ存在しないレイヤのみをダウンロードします。このキャッシング メカニズムの有効性を最大化し、イメージの pull 時間を最小限に抑えるには、イメージの頻繁に変更される部分(アプリケーション コードなど)をファイルの末尾に配置するように Dockerfile を構成し、小さいベースイメージを使用します。
  5. イメージ ストリーミングを有効にします。この機能により、Pod の起動とイメージのダウンロードを高速化できます。詳細については、イメージ ストリーミングを使用してコンテナ イメージを pull するをご覧ください。
  6. デフォルトのサービス アカウントに必要な権限があることを確認します。デフォルトのサービス アカウントに割り当てられているロールを変更すると、イメージの pull など、ワークロードが中断される可能性があります。その他の推奨事項については、重要な権限がないノード サービス アカウントを持つクラスタを特定するをご覧ください。
  7. プロキシ構成を確認します。GKE クラスタと Google 以外の管理対象リポジトリの間にプロキシが存在する場合、レイテンシが発生する可能性があります。
  8. サードパーティ製ソフトウェアを確認します。一部のサードパーティ ソフトウェアは、イメージの取得を妨げる可能性があります。最近インストールしたツールが競合の原因となっているかどうかを調査します。

イメージ マニフェストで正しいアーキテクチャが使用されていることを確認する

pull しようとしているイメージが、ノードプールで使用されているコンピュータ アーキテクチャとは異なるアーキテクチャ用にビルドされている場合、イメージの pull は失敗します。

イメージ マニフェストが正しいアーキテクチャを使用しているかどうかを確認する手順は次のとおりです。

  1. イメージが使用するアーキテクチャを確認するには、イメージのマニフェストを表示します。たとえば、Docker イメージを表示するには、次のコマンドを実行します。

    docker manifest inspect --verbose IMAGE_NAME
    

    IMAGE_NAME は、表示するイメージの名前に置き換えます。

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

    ...
    "Platform": {
              "architecture": "amd64",
              "os": "linux"
      }
    ...
    

    この例では、サポートされているアーキテクチャは amd64 です。

  2. ノードプールで使用されているマシンタイプを確認します。

    gcloud container node-pools list --cluster CLUSTER_NAME --location LOCATION
    

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

    • CLUSTER_NAME: イメージの pull エラーのある Pod が実行されているクラスタの名前。
    • LOCATION: ノードが作成された Compute Engine ゾーンまたはリージョン。たとえば、us-central1-aus-central1 です。

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

    NAME: example-node-pool
    MACHINE_TYPE: e2-standard-2
    DISK_SIZE_GB: 100
    NODE_VERSION: 1.30.8-gke.1162000
    

    この例では、マシンタイプは e2-standard-2 です。

  3. architecture フィールドと MACHINE_TYPE フィールドの値を比較し、両方の値が互換性があることを確認します。たとえば、イメージのアーキテクチャが amd64 の場合、マシンタイプとして e2-standard-2 を使用するノードプールと互換性があります。ただし、ノードプールが t2a-standard-1(Arm ベースのマシンタイプ)を使用している場合、このマシンタイプは失敗します。

  4. イメージのアーキテクチャがノードプールのマシンタイプと互換性がない場合は、必要なアーキテクチャをターゲットにしてイメージを再ビルドします。

イメージ スキーマ バージョンの互換性を確認する

v1 Docker スキーマ イメージで containerd 2.0 を使用すると、containerd 2.0 で GKE 1.33 の Docker スキーマ 1 イメージの pull のサポートが削除されたため、イメージの pull が失敗します。この問題がイメージの pull の失敗の原因である場合、次のエラー メッセージが表示されることがあります。

Failed to get converter for "IMAGE_ADDRESS": Pulling Schema 1 images have been deprecated and disabled by default since containerd v2.0. As a workaround you may set an environment variable `CONTAINERD_ENABLE_DEPRECATED_PULL_SCHEMA_1_IMAGE=1`, but this will be completely removed in containerd v2.1.

この問題を解決するには、Docker Schema 1 イメージから移行するの手順に沿って、これらのイメージを特定して移行します。

次のステップ

さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。