Azure Container Registryからクラスターへのイメージのプルに失敗Azure Kubernetes Service

注:

この記事はお役に立ちましたか? お客様の入力は、当社にとって重要です。 このページの [フィードバック ] ボタンを使用して、この記事がどれだけうまく機能したか、または改善する方法をお知らせください。

Azure Kubernetes Service (AKS) と共に Microsoft Azure Container Registryを使用している場合は、認証メカニズムを確立する必要があります。 いくつかの簡単な Azure CLI または Azure PowerShell コマンドを使用して、AKS から Container Registry への統合を設定できます。 この統合により、AKS クラスターに関連付けられている kubelet ID に対して AcrPull ロール が割り当てられ、コンテナー レジストリからイメージがプルされます。

場合によっては、コンテナー レジストリから AKS クラスターにイメージをプルしようとすると失敗します。 この記事では、コンテナー レジストリから AKS クラスターにイメージをプルするときに発生する最も一般的なエラーのトラブルシューティングに関するガイダンスを提供します。

はじめに

この記事では、既存の AKS クラスターと既存のコンテナー レジストリがあることを前提としています。 次のクイック スタートを参照してください。

  • AKS クラスターが必要な場合は、Azure CLI またはAzure portalを使用してデプロイします。

  • Azure Container Registry (ACR) が必要な場合は、Azure CLI または Azure portalを使用して作成します。

また、Azure CLI バージョン 2.0.59 以降のバージョンをインストールして構成する必要もあります。 az version を実行してバージョンを確認します。 インストールまたはアップグレードする必要がある場合は、「 Azure CLI のインストール」を参照してください。

症状と初期トラブルシューティング

Kubernetes ポッドの STATUSImagePullBackOff または ErrImagePull です。 詳細なエラー情報を取得するには、次のコマンドを実行し、出力からイベントをチェックします。

kubectl describe pod <podname> -n <namespace>

トラブルシューティングを開始するには、 コンテナー レジストリの正常性 を確認し、コンテナー レジストリに AKS クラスターからアクセスできるかどうかを確認することをお勧めします。

コンテナー レジストリの正常性をチェックするには、次のコマンドを実行します。

az acr check-health --name <myregistry> --ignore-errors --yes

問題が検出された場合は、エラー コードと説明が提供されます。 エラーと考えられる解決策の詳細については、「正常性チェックエラー リファレンス」を参照してください

注:

Helm 関連または公証人関連のエラーが発生した場合、問題がコンテナー レジストリまたは AKS に影響を与えるという意味ではありません。 これは、Helm または Notary がインストールされていないこと、または Azure CLI がインストールされている現在のバージョンの Helm または Notary と互換性がないことを示します。

コンテナー レジストリに AKS クラスターからアクセスできるかどうかを検証するには、次の az aks チェック-acr コマンドを実行します。

az aks check-acr --resource-group <MyResourceGroup> --name <MyManagedCluster> --acr <myacr>.azurecr.io

次のセクションは、コマンドの出力の イベント に表示される最も一般的なエラーのトラブルシューティングに kubectl describe pod 役立ちます。

原因 1: 401 未承認エラー

AKS クラスターには ID が必要です。 この ID には、マネージド ID またはサービス プリンシパルを指定できます。 AKS クラスターでマネージド ID を使用する場合は、ACR での認証に kubelet ID が使用されます。 AKS クラスターがサービス プリンシパルを ID として使用している場合、サービス プリンシパル自体は ACR での認証に使用されます。 ID が何であっても、コンテナー レジストリからイメージをプルするために使用される適切な承認が必要です。 そうしないと、次の "401 Unauthorized" エラーが発生する可能性があります。

イメージ "<acrname.azurecr.io/>< repository:tag>": [rpc error: code = Unknown desc = pull and unpack image "<acrname.azurecr.io/> repository:tag>": failed to reference "<acrname.azurecr.io/<<> repository:tag>": failed to authorize: failed to fetch oauth token: unexpected status: 401 Unauthorizedd

次の制約に従って、このエラーを解決するのに役立ついくつかの解決策があります。

解決策 1: ID 用に AcrPull ロールの割り当てが作成されていることを確認する

AKS と Container Registry の統合により、AKS クラスターの kubelet ID のコンテナー レジストリ レベルで AcrPull ロールの割り当てが作成されます。 ロールの割り当てが作成されていることを確認します。

AcrPull ロールの割り当てが作成されるかどうかをチェックするには、次のいずれかの方法を使用します。

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

    az role assignment list --scope /subscriptions/<subscriptionID>/resourceGroups/<resourcegroupname>/providers/Microsoft.ContainerRegistry/registries/<acrname> -o table
    
  • [Azure Container Registryアクセス 制御 (IAM)ロールの割り当て] > を選択して、Azure portal>をチェックインします。 詳細については、「Azure portalを使用して Azure ロールの割り当てを一覧表示する」を参照してください。

AcrPull ロールに加えて、 一部の組み込みロールカスタム ロール には、"Microsoft.ContainerRegistry/registries/pull/read" アクションを含めることもできます。 いずれかのロールがある場合は、それらのロールを確認します。

AcrPull ロールの割り当てが作成されていない場合は、次のコマンドを使用して AKS クラスターの Container Registry 統合を構成 して作成します。

az aks update -n <myAKSCluster> -g <myResourceGroup> --attach-acr <acr-resource-id>

解決策 2: サービス プリンシパルの有効期限が切れていないことを確認する

AKS クラスターに関連付けられているサービス プリンシパルのシークレットの有効期限が切れていないことを確認します。 サービス プリンシパルの有効期限をチェックするには、次のコマンドを実行します。

SP_ID=$(az aks show --resource-group <myResourceGroup> --name <myAKSCluster> \
    --query servicePrincipalProfile.clientId -o tsv)

az ad sp credential list --id "$SP_ID" --query "[].endDate" -o tsv

詳細については、「 サービス プリンシパルの有効期限を確認する」を参照してください。

シークレットの有効期限が切れている場合は、 AKS クラスターの資格情報を更新します

解決策 3: AcrPull ロールが正しいサービス プリンシパルに割り当てられていることを確認する

場合によっては、コンテナー レジストリ ロールの割り当ては引き続き古いサービス プリンシパルを参照します。 たとえば、AKS クラスターのサービス プリンシパルが新しいクラスターに置き換えられるとします。 コンテナー レジストリ ロールの割り当てが正しいサービス プリンシパルを参照していることを確認するには、次の手順に従います。

  1. AKS クラスターで使用されるサービス プリンシパルをチェックするには、次のコマンドを実行します。

    az aks show --resource-group <myResourceGroup> \
        --name <myAKSCluster> \
        --query servicePrincipalProfile.clientId \
        --output tsv
    
  2. コンテナー レジストリ ロールの割り当てによって参照されるサービス プリンシパルをチェックするには、次のコマンドを実行します。

    az role assignment list --scope /subscriptions/<subscriptionID>/resourceGroups/<resourcegroupname>/providers/Microsoft.ContainerRegistry/registries/<acrname> -o table
    
  3. 2 つのサービス プリンシパルを比較します。 一致しない場合は、AKS クラスターとコンテナー レジストリをもう一度統合します。

解決策 4: AKS VMSS で kubelet ID が参照されていることを確認する

マネージド ID が ACR での認証に使用される場合、マネージド ID は kubelet ID と呼ばれます。 既定では、kubelet ID は AKS VMSS レベルで割り当てられます。 kubelet ID が AKS VMSS から削除された場合、AKS ノードは ACR からイメージをプルできません。

AKS クラスターの kubelet ID を見つけるには、次のコマンドを実行します。

az aks show --resource-group <MyResourceGroup> --name <MyManagedCluster> --query identityProfile.kubeletidentity

次に、ノード リソース グループから VMSS を開き、Azure portalで割り当てられている ID ユーザーを選択するか、次のコマンドを実行して、AKS VMSS の ID を>一覧表示できます。

az vmss identity show --resource-group <NodeResourceGroup> --name <AksVmssName>

AKS クラスターの kubelet ID が AKS VMSS に割り当てられない場合は、それを割り当て直してください。

注:

IaaS API または Azure portalを使用して AKS VMSS を変更することはサポートされていません。AKS 操作では AKS VMSS から kubelet ID を削除できません。 これは、チーム メンバーによって実行された手動削除など、予期しない削除が行われることを意味します。 このような削除や変更を防ぐために、 NRGLockdown 機能の使用を検討できます。

AKS VMSS への変更はサポートされていないため、AKS レベルでは反映されません。 kubelet ID を AKS VMSS に再割り当てするには、調整操作が必要です。 このためには、次のコマンドを実行します。

az aks update --resource-group <MyResourceGroup> --name <MyManagedCluster>

解決策 5: サービス プリンシパルが正しく、シークレットが有効であることを確認する

イメージ プル シークレットを使用してイメージをプルし、サービス プリンシパルの値を使用して Kubernetes シークレットが作成された場合は、関連付けられているサービス プリンシパルが正しく、シークレットがまだ有効であることを確認してください。 次の手順を実行します。

  1. 次の kubectl getbase64 コマンドを実行して、Kubernetes シークレットの値を確認します。

    kubectl get secret <secret-name> --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
    
  2. 次の az ad sp credential list コマンドを実行して、有効期限を確認します。 ユーザー名はサービス プリンシパルの値です。

    az ad sp credential list --id "<username>" --query "[].endDate" --output tsv
    
  3. 必要に応じて、次の az ad sp credential reset コマンドを実行して、そのサービス プリンシパルのシークレットをリセットします。

    az ad sp credential reset --name "$SP_ID" --query password --output tsv
    
  4. それに応じて Kubernetes シークレットを更新または再作成します。

解決策 6: Kubernetes シークレットにコンテナー レジストリ管理者アカウントの正しい値があることを確認する

イメージ プル シークレットを使用してイメージをプルし、コンテナー レジストリ管理者アカウントの値を使用して Kubernetes シークレットが作成された場合は、Kubernetes シークレットの値がコンテナー レジストリ管理者アカウントの値と同じであることを確認します。 次の手順を実行します。

  1. 次の kubectl getbase64 コマンドを実行して、Kubernetes シークレットの値を確認します。

    kubectl get secret <secret-name> --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
    
  2. Azure portalで、コンテナー レジストリを検索して選択します。

  3. コンテナー レジストリの一覧で、コンテナー レジストリを選択します。

  4. コンテナー レジストリのナビゲーション ウィンドウで、[ アクセス キー] を選択します。

  5. コンテナー レジストリの [アクセス キー ] ページで、コンテナー レジストリの値を Kubernetes シークレットの値と比較します。

  6. 値が一致しない場合は、それに応じて Kubernetes シークレットを更新または再作成します。

注:

パスワード の再生成 操作が発生した場合は、コンテナー レジストリの [ アクティビティ ログ ] ページに "コンテナー レジストリログイン資格情報の再生成" という名前の操作が表示されます。 アクティビティ ログには、90 日間の保持期間があります

原因 2: イメージが見つかりませんエラー

イメージ "<acrname.azurecr.io/<> repository:tag>" をプルできませんでした:[rpc error: code = NotFound desc = acrname.azurecr.io/ repository:tag>": 参照 "<<acrname.azurecr.io/><> repository:tag>": <acrname.azurecr.io/>< repository:tag>: not found<

解決策: イメージ名が正しいことを確認する

このエラーが表示された場合は、イメージ名が完全に正しいことを確認してください。 レジストリ名、レジストリ ログイン サーバー、リポジトリ名、タグをチェックする必要があります。 一般的な間違いは、ログイン サーバーが "azurecr.io" ではなく "azureacr.io" として指定されていることです。

イメージ名が完全に正しくない場合は、コンテナー レジストリで匿名プル アクセスが有効になっているかどうかに関係なく、AKS は常に匿名プルを試行するため、401 未承認エラーが発生する可能性があります。

原因 3: 403 禁止エラー

イメージ "<acrname.azurecr.io/>< repository:tag>": rpc エラー: code = Unknown desc = pull and unpack image "<acrname.azurecr.io/ repository:tag>": 参照 "<acrname.azurecr.io/<><> repository:tag>": 承認に失敗しました: 匿名トークンをフェッチできませんでした: 予期しない状態: 403 Forbidden

コンテナー レジストリのプライベート エンドポイントと AKS クラスターのネットワーク インターフェイスが異なる仮想ネットワーク内にある場合は、AKS クラスターの仮想ネットワークの仮想ネットワーク リンクがコンテナー レジストリのプライベート DNS ゾーンに設定されていることを確認します。 (このリンクの名前は既定で "privatelink.azurecr.io" です)。仮想ネットワーク リンクがコンテナー レジストリのプライベート DNS ゾーンにない場合は、次のいずれかの方法で追加します。

解決策 2: コンテナー レジストリの許可された IP アドレス範囲に AKS Load Balancerのパブリック IP アドレスを追加する

AKS クラスターが (プライベート リンクまたはエンドポイントを介してではなく) コンテナー レジストリにパブリックに接続し、コンテナー レジストリのパブリック ネットワーク アクセスが選択したネットワークに制限されている場合は、AKS Load Balancerのパブリック IP アドレスをコンテナー レジストリの許可された IP アドレス範囲に追加します。

  1. パブリック ネットワーク アクセスが選択したネットワークに制限されていることを確認します。

    Azure portalで、コンテナー レジストリに移動します。 [ 設定] で、[ネットワーク] を選択 します。 [ パブリック アクセス ] タブで、[ パブリック ネットワーク アクセス ] が [ 選択されたネットワーク] または [無効] に設定されます。

  2. 次のいずれかの方法を使用して、AKS Load Balancerのパブリック IP アドレスを取得します。

    • Azure portalで、AKS クラスターに移動します。 [設定] で、[プロパティ] を選択し、インフラストラクチャ リソース グループ内のいずれかの仮想マシン スケール セットを選択し、AKS Load Balancerのパブリック IP アドレスをチェックします。

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

      az network public-ip show --resource-group <infrastructure-resource-group> --name <public-IP-name> --query ipAddress -o tsv
      
  3. 次のいずれかの方法を使用して、AKS Load Balancerのパブリック IP アドレスからのアクセスを許可します。

    • コマンドを次のように実行 az acr network-rule add します。

      az acr network-rule add --name acrname --ip-address <AKS-load-balancer-public-IP-address>
      

      詳細については、「 レジストリにネットワーク 規則を追加する」を参照してください。

    • Azure portalで、コンテナー レジストリに移動します。 [ 設定] で、[ネットワーク] を選択 します。 [パブリック アクセス] タブの [ファイアウォール] で、AKS Load Balancerのパブリック IP アドレスを [アドレス範囲] に追加し、[保存] を選択します。 詳細については、「 選択したパブリック ネットワークからのアクセス - ポータル」を参照してください。

      注:

      [パブリック ネットワーク アクセス] が [無効] に設定されている場合は、最初に [選択したネットワーク] に切り替えます。

      アドレス範囲に AKS Load Balancerのパブリック IP アドレスを追加する方法に関するスクリーンショット

原因 4: 443 タイムアウト エラー

イメージ "<acrname.azurecr.io/>< repository:tag>" をプルできませんでした:rpc エラー: code = Unknown desc = イメージ "<acrname.azurecr.io/>< repository:tag>": 参照 "<acrname>. azurecr.io/< repository:tag>": 要求を実行できませんでした: Head "https://< acrname.azurecr.io/v2/<> repository>/manifests/v1": dial tcp <acrprivateipaddress>:443: i/o timeout

注:

"443 タイムアウト" エラーは、Azure Private Linkを使用してコンテナー レジストリにプライベートに接続する場合にのみ発生します。

解決策 1: 仮想ネットワーク ピアリングが使用されていることを確認する

コンテナー レジストリのプライベート エンドポイントと AKS クラスターのネットワーク インターフェイスが異なる仮想ネットワーク内にある場合は、両方の 仮想ネットワークに仮想ネットワーク ピアリング が使用されていることを確認します。 仮想ネットワーク ピアリングをチェックするには、Azure CLI コマンドaz network vnet peering list --resource-group <MyResourceGroup> --vnet-name <MyVirtualNetwork> --output tableを実行するか、[設定] パネルの [VNET>ピアリング] を選択してAzure portalで実行します。 指定した仮想ネットワークのすべてのピアリングの一覧表示の詳細については、「 az network vnet peering list」を参照してください。

両方の仮想ネットワークで仮想ネットワーク ピアリングが使用されている場合は、状態が "接続済み" であることを確認します。 状態が [切断] の場合は、両方の仮想ネットワークからピアリングを削除し、再作成します。 状態が "接続済み" の場合は、トラブルシューティング ガイドを参照してください。 ピアリングの状態は "接続済み" です

さらにトラブルシューティングを行うには、AKS ノードまたは ポッドのいずれかに接続し、Telnet または Netcat ユーティリティを使用して、TCP レベルでコンテナー レジストリとの接続をテストします。 コマンドで IP アドレスを nslookup <acrname>.azurecr.io 確認し、コマンドを telnet <ip-address-of-the-container-registry> 443 実行します。

AKS ノードへの接続の詳細については、「メンテナンスまたはトラブルシューティングのために SSH を使用して Azure Kubernetes Service (AKS) クラスター ノードに接続する」を参照してください。

解決策 2: Azure Firewall サービスを使用する

コンテナー レジストリのプライベート エンドポイントと AKS クラスターのネットワーク インターフェイスが、仮想ネットワーク ピアリングに加えて異なる仮想ネットワーク内にある場合は、Azure Firewall Service を使用して Azure でハブスポーク ネットワーク トポロジを設定できます。 ファイアウォール規則を設定するときは、ネットワーク規則を使用して、コンテナー レジストリのプライベート エンドポイント IP アドレスへの 送信接続 を明示的に許可する必要があります。

原因 5: マニフェスト内のプラットフォームに一致しない

ホスト オペレーティング システム (ノード OS) は、ポッドまたはコンテナーに使用されるイメージと互換性がありません。 たとえば、Windows ノードで Linux コンテナーを実行するようにポッドをスケジュールする場合、または Linux ノード上の Windows コンテナーを実行するようにポッドをスケジュールすると、次のエラーが発生します。

イメージ "<acrname.azurecr.io/>< repository:tag>" をプルできませんでした。
[
  rpc エラー:
  code = NotFound
  desc = イメージ "<acrname.azurecr.io/>< repository:tag>": マニフェスト内のプラットフォームに一致しない: 見つかりません。
]

このエラーは、イメージがホスト OS と互換性がない限り、任意のソースからプルされたイメージに対して発生する可能性があります。 このエラーは、コンテナー レジストリからプルされたイメージに限定されません。

解決策: ポッドまたはデプロイで nodeSelector フィールドを正しく構成する

ポッドまたはデプロイの構成設定で正しい nodeSelector フィールドを指定します。 このフィールドの kubernetes.io/os 設定の正しい値を使用すると、ポッドが正しい種類のノードでスケジュールされます。 次の表は、YAML で設定を設定する方法を kubernetes.io/os 示しています。

コンテナーの種類 YAML 設定
Linux コンテナー "kubernetes.io/os": linux
Windows コンテナー "kubernetes.io/os": windows

たとえば、次の YAML コードでは、Linux ノードでスケジュールする必要があるポッドについて説明します。

apiVersion: v1
kind: Pod
metadata:
  name: aspnetapp
  labels:
    app: aspnetapp
spec:
  containers:
  - image: "mcr.microsoft.com/dotnet/core/samples:aspnetapp"
    name: aspnetapp-image
    ports:
    - containerPort: 80
      protocol: TCP
  nodeSelector:
    "kubernetes.io/os": linux

詳細

この記事のトラブルシューティング ガイダンスが問題の解決に役立たない場合は、次の点を考慮する必要があります。

  • ネットワーク セキュリティ グループを確認し、サブネットに関連付けられているルート テーブル (これらの項目がある場合) を確認します。

  • ファイアウォールなどの仮想アプライアンスがサブネット間のトラフィックを制御する場合は、ファイアウォールとファイアウォールのアクセス規則をチェックします。

サードパーティの情報に関する免責事項

この資料に記載されているサードパーティ製品は、マイクロソフトと関連のない他社の製品です。 明示的か黙示的かにかかわらず、これらの製品のパフォーマンスや信頼性についてマイクロソフトはいかなる責任も負わないものとします。

お問い合わせはこちらから

質問がある場合やヘルプが必要な場合は、サポート要求を作成するか、Azure コミュニティ サポートにお問い合わせください。 Azure フィードバック コミュニティに製品フィードバックを送信することもできます。