Azure Container Registry から Azure Kubernetes Service クラスターへのイメージのプルに失敗する
Note
この記事は役に立ちましたか? あなたの入力は私たちにとって重要です。 このページの Feedback ボタンを使用して、この記事がどれだけうまく機能したか、または改善方法をお知らせください。
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 ポッドの STATUS は ImagePullBackOff または ErrImagePull です。 詳細なエラー情報を取得するには、次のコマンドを実行し、出力から Events を確認します。
kubectl describe pod <podname> -n <namespace>
コンテナー レジストリの正常性を確認しコンテナー レジストリに AKS クラスターからアクセスできるかどうかを確認して、トラブルシューティングを開始することをお勧めします。
コンテナー レジストリの正常性を確認するには、次のコマンドを実行します。
az acr check-health --name <myregistry> --ignore-errors --yes
問題が検出されると、エラー コードと説明が示されます。 エラーと考えられる解決策の詳細については、 エラー の確認に関するリファレンスを参照してください。
Note
Helm 関連または Notary 関連のエラーが発生した場合、問題が Container Registry または AKS に影響を与えるという意味ではありません。 これは、Helm または Notary がインストールされていないこと、または Azure CLI が現在インストールされているバージョンの Helm または Notary と互換性がないことを示します。
コンテナー レジストリに AKS クラスターからアクセスできるかどうかを検証するには、次の az aks check-acr コマンドを実行します。
az aks check-acr --resource-group <MyResourceGroup> --name <MyManagedCluster> --acr <myacr>.azurecr.io
次のセクションは、kubectl describe pod
コマンドの出力でEventsに表示される最も一般的なエラーのトラブルシューティングに役立ちます。
原因 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 = failed to pull and unpack image "<acrname>.azurecr.io/<repository:tag>": 参照 "<acrname>.azurecr.io/<repository:tag>": 承認に失敗しました: oauth トークンのフェッチに失敗しました: 未検証状態: 401 未承認
いくつかの解決策は、次の制約に従って、このエラーを解決するのに役立ちます。
ソリューション 2、 3、 5 は、サービス プリンシパルを使用する AKS クラスターにのみ適用されます。
ソリューション 1、 2、 3、および 4 は、AKS の ID に対してコンテナー レジストリ レベルでロールの割り当てを する Azure の方法に適用できます。
ソリューション 5 と 6 は、Kubernetes シークレットを プルする Kubernetes メソッドに適用。
解決策 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 portal で、 Azure Container Registry>Access control (IAM)>Role の割り当てを選択してチェックインします。 詳細については、「 Azure portal を使用して Azure ロールの割り当てを一覧するを参照してください。
AcrPull ロールに加えて、一部の 組み込みロール および custom ロール には "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 app credential list --id "SP_ID" --query "[].endDateTime" --output tsv
詳細については、「 サービス プリンシパルの有効期限を確認するを参照してください。
シークレットの有効期限が切れている場合は、 AKS クラスターの資格情報を更新します。
解決策 3: AcrPull ロールが正しいサービス プリンシパルに割り当てられていることを確認する
場合によっては、コンテナー レジストリ ロールの割り当てによって、古いサービス プリンシパルが引き続き参照されます。 たとえば、AKS クラスターのサービス プリンシパルが新しいサービス プリンシパルに置き換えられるとします。 コンテナー レジストリ ロールの割り当てが正しいサービス プリンシパルを参照していることを確認するには、次の手順に従います。
AKS クラスターで使用されているサービス プリンシパルを確認するには、次のコマンドを実行します。
az aks show --resource-group <myResourceGroup> \ --name <myAKSCluster> \ --query servicePrincipalProfile.clientId \ --output tsv
コンテナー レジストリ ロールの割り当てによって参照されるサービス プリンシパルを確認するには、次のコマンドを実行します。
az role assignment list --scope /subscriptions/<subscriptionID>/resourceGroups/<resourcegroupname>/providers/Microsoft.ContainerRegistry/registries/<acrname> -o table
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 で Identity>User assigned を選択するか、次のコマンドを実行して、AKS VMSS の ID を一覧表示できます。
az vmss identity show --resource-group <NodeResourceGroup> --name <AksVmssName>
AKS クラスターの kubelet ID が AKS VMSS に割り当てられていない場合は、それを割り当て直します。
Note
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 シークレットがサービス プリンシパルの値を使用して作成された場合は、関連付けられているサービス プリンシパルが正しく、シークレットがまだ有効であることを確認してください。 次のステップを実行します。
次の kubectl get および base64 コマンドを実行して、Kubernetes シークレットの値を確認します。
kubectl get secret <secret-name> --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
次の az ad sp credential list コマンドを実行して、有効期限を確認します。 ユーザー名はサービス プリンシパルの値です。
az ad sp credential list --id "<username>" --query "[].endDate" --output tsv
必要に応じて、次の az ad sp credential reset コマンドを実行して、そのサービス プリンシパルのシークレットをリセットします。
az ad sp credential reset --name "$SP_ID" --query password --output tsv
それに応じて、Kubernetes シークレットを更新または再作成します。
解決策 6: Kubernetes シークレットにコンテナー レジストリ管理者アカウントの正しい値があることを確認する
イメージ プル シークレットを使用してイメージをプルし、その Kubernetes シークレットが container レジストリ管理者アカウントの値を使用して作成された場合 Kubernetes シークレットの値がコンテナー レジストリ管理者アカウントの値と同じであることを確認します。 次のステップを実行します。
次の kubectl get および base64 コマンドを実行して、Kubernetes シークレットの値を確認します。
kubectl get secret <secret-name> --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
Azure ポータルでcontainer レジストリ検索して選択。
コンテナー レジストリの一覧で、コンテナー レジストリを選択します。
コンテナー レジストリのナビゲーション ウィンドウで、 Access キーを選択します。
コンテナー レジストリの Access キー ページで、コンテナー レジストリの値と Kubernetes シークレットの値を比較します。
値が一致しない場合は、それに応じて Kubernetes シークレットを更新または再作成します。
Note
Regenerateパスワード操作が発生した場合、コンテナー レジストリの Activity ログ ページに "コンテナー レジストリ ログイン資格情報の再生成" という名前の操作が表示されます。 Activity ログには、90 日間の保持期間があります。
原因 2: イメージが見つかりませんエラー
イメージ "<acrname>.azurecr.io/<repository:tag>" をプルできませんでした: [rpc error: code = NotFound desc = failed to pull and unpack image "<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 error: code = Unknown desc = failed to pull and unpack image "<acrname>.azurecr.io/<repository::tag>": 参照 "<acrname>.azurecr.io/<repository:tag>": 承認に失敗しました: 匿名トークンのフェッチに失敗しました: 未解決の状態: 403 Forbidden
解決策 1: AKS 仮想ネットワーク リンクがコンテナー レジストリのプライベート DNS ゾーンに設定されていることを確認する
コンテナー レジストリのプライベート エンドポイントと AKS クラスターのネットワーク インターフェイスが異なる仮想ネットワークにある場合は、AKS クラスターの仮想ネットワークの仮想ネットワーク リンクがコンテナー レジストリのプライベート DNS ゾーンに設定されていることを確認します。 (このリンクの名前は既定で "privatelink.azurecr.io" です)。仮想ネットワーク リンクがコンテナー レジストリのプライベート DNS ゾーンにない場合は、次のいずれかの方法で追加します。
Azure portal でプライベート DNS ゾーン "privatelink.azurecr.io" を選択し、Settings パネルの下にある 仮想ネットワーク リンク>[追加] を選択し、AKS クラスターの名前と仮想ネットワークを選択します。 [OK] を選択します。
Note
"自動登録を有効にする"機能を選択することは省略可能です。
解決策 2: コンテナー レジストリの許可された IP アドレス範囲に AKS Load Balancer のパブリック IP アドレスを追加する
AKS クラスターが (プライベート リンクまたはエンドポイントを介してではなく) コンテナー レジストリにパブリックに接続し、コンテナー レジストリのパブリック ネットワーク アクセスが選択したネットワークに制限されている場合は、AKS Load Balancer のパブリック IP アドレスをコンテナー レジストリの許可された IP アドレス範囲に追加します。
パブリック ネットワーク アクセスが選択したネットワークに制限されていることを確認します。
Azure portal で、コンテナー レジストリに移動します。 [設定] で [ネットワーク] を選択します。 [パブリック アクセス] タブ で、[パブリック ネットワーク アクセス選択されたネットワークまたは Disabled に設定します。
次のいずれかの方法を使用して、AKS Load Balancer のパブリック IP アドレスを取得します。
Azure portal で、AKS クラスターに移動します。 Settingsで Properties を選択し、インフラストラクチャ リソース グループ内のいずれかの仮想マシン スケール セットを選択し、AKS Load Balancer のパブリック IP アドレスを確認します。
次のコマンドを実行します。
az network public-ip show --resource-group <infrastructure-resource-group> --name <public-IP-name> --query ipAddress -o tsv
次のいずれかの方法を使用して、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 アドレスを Address 範囲に追加し保存を選択します。 詳細については、「 選択したパブリック ネットワークからのアクセス - ポータル」を参照してください。
Note
パブリック ネットワーク アクセスが Disabled に設定されている場合は、最初に Selected ネットワークに切り替えます。
原因 4: "i/o タイムアウト エラー"
イメージ "<acrname>.azurecr.io/<repository:tag>": rpc error: code = Unknown desc = failed to pull and unpack image "<acrname>.azurecr.io/<repository:tag>": failed to resolve reference "<acrname >.azurecr.io/<repository:tag>": 要求を実行できませんでした: head "https://<acrname>.azurecr.io/v2/<repository>/manifests/v1": tcp <acrprivateipaddress>:443: i/o timeout
Note
"i/o タイムアウト" エラーは、Azure Private Link を使用してコンテナー レジストリにプライベートに接続 場合にのみ発生します。
解決策 1: 仮想ネットワーク ピアリングが使用されていることを確認する
コンテナー レジストリのプライベート エンドポイントと AKS クラスターのネットワーク インターフェイスが異なる仮想ネットワークにある場合は、 仮想ネットワーク ピアリング が両方の仮想ネットワークに使用されていることを確認します。 仮想ネットワーク ピアリングは、Azure CLI コマンド az network vnet peering list --resource-group <MyResourceGroup> --vnet-name <MyVirtualNetwork> --output table
を実行するか、Settings パネルの下にある VNET>Peerings を選択して Azure portal で確認できます。 指定した仮想ネットワークのすべてのピアリングの一覧表示の詳細については、「 az ネットワーク vnet ピアリングの一覧を参照してください。
両方の仮想ネットワークに仮想ネットワーク ピアリングが使用されている場合は、状態が "接続済み" であることを確認します。 状態が Disconnected の場合は、両方の仮想ネットワークからピアリングを削除してから、再作成します。 状態が "接続済み" の場合は、トラブルシューティング ガイドを参照してください。 ピアリングの状態は "接続済み" 。
さらにトラブルシューティングを行うには、AKS ノードまたは ポッドのいずれかに接続し Telnet または Netcat ユーティリティを使用して、TCP レベルでコンテナー レジストリとの接続をテストします。 nslookup <acrname>.azurecr.io
コマンドで IP アドレスを確認し、telnet <ip-address-of-the-container-registry> 443
コマンドを実行します。
AKS ノードへの接続の詳細については、「 Azure Kubernetes Service (AKS) クラスター ノードへの SSH を使用した接続」を参照して、メンテナンスやトラブルシューティングを行います。
解決策 2: Azure Firewall サービスを使用する
コンテナー レジストリのプライベート エンドポイントと AKS クラスターのネットワーク インターフェイスが異なる仮想ネットワーク内にある場合は、仮想ネットワーク ピアリングに加えて、Azure Firewall サービスを使用して、Azure で Hub-spoke ネットワーク トポロジを設定できます。 ファイアウォール規則を設定するときは、ネットワーク規則を使用して、コンテナー レジストリのプライベート エンドポイント 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 フィードバック コミュニティに製品フィードバックを送信することもできます。