Не удается извлечь образы из Реестр контейнеров Azure в кластер Служба Azure Kubernetes

Примечание.

Эта статья оказалась полезной? Ваш вклад важен для нас. Используйте кнопку Отзыв на этой странице, чтобы сообщить нам, насколько хорошо эта статья работает для вас или как мы можем ее улучшить.

При использовании microsoft Реестр контейнеров Azure вместе с Служба Azure Kubernetes (AKS) необходимо установить механизм проверки подлинности. Вы можете настроить интеграцию AKS с Реестром контейнеров с помощью нескольких простых команд Azure CLI или Azure PowerShell. Эта интеграция назначает роль AcrPull для удостоверения kubelet, связанного с кластером AKS, для извлечения образов из реестра контейнеров.

В некоторых случаях попытка извлечь образы из реестра контейнеров в кластер AKS завершается ошибкой. В этой статье содержатся рекомендации по устранению наиболее распространенных ошибок, возникающих при извлечении образов из реестра контейнеров в кластер AKS.

Перед началом работы

В этой статье предполагается, что у вас есть существующий кластер AKS и реестр контейнеров. Ознакомьтесь со следующими краткими руководствами.

  • Если вам нужен кластер AKS, разверните его с помощью Azure CLI или портал Azure.

  • Если вам нужен Реестр контейнеров Azure (ACR), создайте его с помощью Azure CLI или портал Azure.

Кроме того, необходимо установить и настроить Azure CLI версии 2.0.59 или более поздней. Выполните команду az version , чтобы определить версию. Если вам нужно установить или обновить, см. статью Установка Azure CLI.

Симптомы и первоначальное устранение неполадок

Состояние объекта pod Kubernetes — ImagePullBackOff или 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 требуется удостоверение. Это может быть управляемое удостоверение или субъект-служба. Если кластер AKS использует управляемое удостоверение, удостоверение kubelet используется для проверки подлинности с помощью ACR. Если кластер AKS использует в качестве удостоверения субъект-службу, для проверки подлинности с помощью ACR используется сам субъект-служба. Независимо от того, что такое удостоверение, необходима правильная авторизация, используемая для извлечения образа из реестра контейнеров. В противном случае может появиться следующая ошибка "401 Unauthorized" (401 Unauthorized):

Не удалось извлечь изображение "<acrname.azurecr.io/>< repository:tag>": [ошибка rpc: code = Unknown desc = fail to pull and unpack image "<acrname.azurecr.io/>< repository:tag>": fail to resolve reference "<acrname.azurecr.io/<> repository:tag>": failed to authorize: Failed to getetch oauth token: unexpected status: 401 Unauthorized

Несколько решений помогут устранить эту ошибку с учетом следующих ограничений:

Решение 1. Убедитесь, что для удостоверения создано назначение ролей AcrPull

Интеграция между AKS и Реестром контейнеров создает назначение роли AcrPull на уровне реестра контейнеров для удостоверения kubelet кластера AKS. Убедитесь, что назначение роли создано.

Чтобы проверка, создается ли назначение роли AcrPull, используйте один из следующих методов:

  • Выполните следующую команду:

    az role assignment list --scope /subscriptions/<subscriptionID>/resourceGroups/<resourcegroupname>/providers/Microsoft.ContainerRegistry/registries/<acrname> -o table
    
  • Проверьте портал Azure, выбрав элемент управления Реестр контейнеров Azure>Доступ (IAM)>Назначения ролей. Дополнительные сведения см. в статье Перечисление назначений ролей Azure с помощью портал Azure.

Помимо роли AcrPull, некоторые встроенные роли и пользовательские роли также могут содержать действие "Microsoft.ContainerRegistry/registries/pull/read". Проверьте эти роли, если у вас есть какие-либо из них.

Если назначение роли AcrPull не создано, создайте его, настроив интеграцию реестра контейнеров для кластера AKS с помощью следующей команды:

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. Сравните два субъекта-службы. Если они не совпадают, снова интегрируйте кластер AKS с реестром контейнеров.

Решение 4. Убедитесь, что удостоверение kubelet ссылается в AKS VMSS

Если управляемое удостоверение используется для проверки подлинности с помощью ACR, управляемое удостоверение называется удостоверением kubelet. По умолчанию удостоверение kubelet назначается на уровне AKS VMSS. Если удостоверение kubelet удалено из AKS VMSS, узлы AKS не смогут извлекать образы из ACR.

Чтобы найти удостоверение kubelet кластера AKS, выполните следующую команду:

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

Затем вы можете получить список удостоверений AKS VMSS, открыв VMSS в группе ресурсов узла и выбрав Identity>User assigned in the портал Azure или выполнив следующую команду:

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

Если удостоверение kubelet кластера AKS не назначено ВИРТУАЛЬНОй машине AKS, назначьте его обратно.

Примечание.

Изменение AKS VMSS с помощью API IaaS или из портал Azure не поддерживается, и никакая операция AKS не может удалить удостоверение kubelet из AKS VMSS. Это означает, что что-то непредвиденное удалило его, например удаление вручную, выполненное участником команды. Чтобы предотвратить такое удаление или изменение, можно использовать функцию NRGLockdown.

Так как изменения в AKS VMSS не поддерживаются, они не распространяются на уровне AKS. Чтобы переназначить удостоверение kubelet в AKS VMSS, необходима операция сверки. Для этого выполните следующую команду.

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

Решение 5. Убедитесь, что субъект-служба указан правильно, а секрет действителен

Если вы извлекаете образ с помощью секрета извлечения образа и что секрет Kubernetes был создан с помощью значений субъекта-службы, убедитесь, что связанный субъект-служба указан правильно, а секрет по-прежнему действителен. Выполните следующие действия:

  1. Выполните следующую команду kubectl get и base64 , чтобы просмотреть значения секрета 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 get и base64 , чтобы просмотреть значения секрета Kubernetes:

    kubectl get secret <secret-name> --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode
    
  2. В портал Azure найдите и выберите Реестры контейнеров.

  3. В списке реестров контейнеров выберите свой реестр контейнеров.

  4. В области навигации для реестра контейнеров выберите Ключи доступа.

  5. На странице Ключи доступа для реестра контейнеров сравните значения реестра контейнеров со значениями в секрете Kubernetes.

  6. Если значения не совпадают, обновите или повторно создайте секрет Kubernetes соответствующим образом.

Примечание.

Если произошла операция повторного ввода пароля, на странице Журнал действий реестра контейнеров будет отображаться операция с именем "Повторное создание учетных данных для входа в реестр контейнеров". Журнал действий содержит 90-дневный срок хранения.

Причина 2. Ошибка "Изображение не найдено"

Не удалось извлечь изображение "<acrname.azurecr.io/<> repository:tag>": [ошибка rpc: code = NotFound desc = не удалось извлечь и распаковать изображение "<acrname.azurecr.io/>< repository:tag>": не удалось разрешить ссылку "<acrname.azurecr.io/>< repository:tag>": <acrname.azurecr.io/>< repository:tag>: не найдено

Решение. Убедитесь, что имя изображения правильно

Если вы видите эту ошибку, убедитесь, что имя образа полностью правильно. Необходимо проверка имя реестра, сервер входа в реестр, имя репозитория и тег. Распространенной ошибкой является то, что сервер входа указан как "azureacr.io" вместо "azurecr.io".

Если имя образа не является полностью правильным, также может возникнуть ошибка 401 Unauthorized, так как AKS всегда пытается выполнить анонимное извлечение независимо от того, включил ли реестр контейнеров анонимную доступ на вытягивание.

Причина 3: ошибка 403 Запрещено

Не удалось извлечь изображение "<acrname.azurecr.io/>< repository:tag>": ошибка rpc: code = Unknown desc = fail to pull and unpack image "<acrname.azurecr.io/>< repository:tag>": fail to resolve reference "<acrname.azurecr.io/<> repository:tag>": failed to authorize: failed to getetch anonymous token: unexpected status: 403 Forbidden

Если сетевой интерфейс частной конечной точки реестра контейнеров и кластер AKS находятся в разных виртуальных сетях, убедитесь, что виртуальная сетевая сеть для виртуальной сети кластера AKS указана в зоне Частная зона DNS реестра контейнеров. (Эта ссылка по умолчанию называется privatelink.azurecr.io.) Если виртуальная сеть отсутствует в зоне Частная зона DNS реестра контейнеров, добавьте его одним из следующих способов:

Решение 2. Добавление общедоступного IP-адреса AKS Load Balancer в допустимый диапазон IP-адресов реестра контейнеров

Если кластер AKS подключается к реестру контейнеров (НЕ через приватный канал или конечную точку), а доступ к общедоступной сети реестра контейнеров ограничен выбранными сетями, добавьте общедоступный IP-адрес AKS Load Balancer в допустимый диапазон IP-адресов реестра контейнеров:

  1. Убедитесь, что доступ к общедоступной сети ограничен выбранными сетями.

    В портал Azure перейдите к реестру контейнеров. В разделе Параметры выберите Сеть. На вкладке Общий доступдля параметра Доступ к общедоступной сети задано значение Выбранные сети или Отключено.

  2. Получите общедоступный IP-адрес Load Balancer AKS одним из следующих способов:

    • В портал Azure перейдите к кластеру AKS. В разделе Параметры выберите Свойства, выберите один из масштабируемых наборов виртуальных машин в группе ресурсов инфраструктуры и проверка общедоступный IP-адрес Load Balancer AKS.

    • Выполните следующую команду:

      az network public-ip show --resource-group <infrastructure-resource-group> --name <public-IP-name> --query ipAddress -o tsv
      
  3. Разрешите доступ с общедоступного IP-адреса LOAD BALANCER AKS одним из следующих способов:

    • Выполните az acr network-rule add команду следующим образом:

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

      Дополнительные сведения см. в разделе Добавление правила сети в реестр.

    • В портал Azure перейдите к реестру контейнеров. В разделе Параметры выберите Сеть. На вкладке Общедоступный доступ в разделе Брандмауэр добавьте общедоступный IP-адрес AKS Load Balancer в диапазон адресов и нажмите кнопку Сохранить. Дополнительные сведения см. в разделе Доступ из выбранной общедоступной сети — портал.

      Примечание.

      Если для доступа к общедоступной сетизадано значение Отключено, сначала переключите его на Выбранные сети .

      Снимок экрана: добавление общедоступного IP-адреса AKS Load Balancer в диапазон адресов

Причина 4: ошибка времени ожидания 443

Не удалось извлечь изображение "<acrname.azurecr.io/<> repository:tag>": ошибка rpc: code = Unknown desc = fail to pull and unpack image "<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.

Решение 1. Убедитесь, что используется пиринг между виртуальными сетями

Если сетевой интерфейс частной конечной точки реестра контейнеров и кластер AKS находятся в разных виртуальных сетях, убедитесь, что пиринг между виртуальными сетями используется для обеих виртуальных сетей. Пиринг виртуальных сетей можно проверка, выполнив команду az network vnet peering list --resource-group <MyResourceGroup> --vnet-name <MyVirtualNetwork> --output table Azure CLI или в портал Azure, выбравпиринг виртуальныхсетей> на панели Параметры. Дополнительные сведения о перечислении всех пирингов указанной виртуальной сети см. в статье az network vnet peering list.

Если пиринг виртуальных сетей используется для обеих виртуальных сетей, убедитесь, что состояние "Подключено". Если состояние Отключено, удалите пиринг из обеих виртуальных сетей, а затем создайте его повторно. Если состояние имеет значение "Подключено", см. руководство по устранению неполадок: Состояние пиринга — "Подключено".

Для дальнейшего устранения неполадок подключитесь к одному из узлов AKS или модулей pod, а затем проверьте подключение к реестру контейнеров на уровне TCP с помощью программы Telnet или Netcat. Проверьте IP-адрес с nslookup <acrname>.azurecr.io помощью команды , а затем выполните telnet <ip-address-of-the-container-registry> 443 команду .

Дополнительные сведения о подключении к узлам AKS см. в статье Подключение по протоколу SSH к узлам кластера Служба Azure Kubernetes (AKS) для обслуживания или устранения неполадок.

Решение 2. Использование службы Брандмауэр Azure

Если сетевой интерфейс частной конечной точки реестра контейнеров и кластер AKS находятся в разных виртуальных сетях, помимо пиринга между виртуальными сетями, вы можете использовать службу Брандмауэр Azure для настройки звездообразной топологии сети в Azure. При настройке правила брандмауэра необходимо использовать правила сети, чтобы явно разрешить исходящее подключение к IP-адресам частных конечных точек реестра контейнеров.

Причина 5. Нет совпадения для платформы в манифесте

Операционная система узла (ОС узла) несовместима с образом, используемым для модуля pod или контейнера. Например, при планировании модуля pod для запуска контейнера Linux на узле Windows или контейнера Windows на узле Linux возникает следующая ошибка:

Не удалось извлечь изображение "<acrname.azurecr.io/>< repository:tag>":
[
  Ошибка rpc:
  code = NotFound
  desc = не удалось извлечь и распаковать изображение "<acrname.azurecr.io/>< repository:tag>": нет совпадения для платформы в манифесте: не найдено,
]

Эта ошибка может возникнуть для образа, извлеченного из любого источника, при условии, что образ несовместим с ОС узла. Ошибка не ограничивается образами, извлекаемых из реестра контейнеров.

Решение. Правильная настройка поля nodeSelector в модуле pod или развертывании

Укажите правильное nodeSelector поле в параметрах конфигурации модуля pod или развертывания. Правильное значение параметра этого поля kubernetes.io/os гарантирует, что модуль pod будет планироваться на узле правильного типа. В следующей таблице показано, как задать kubernetes.io/os параметр в YAML:

Тип контейнера Параметр YAML
Контейнер Linux "kubernetes.io/os": linux
Контейнер Windows "kubernetes.io/os": windows

Например, следующий код YAML описывает модуль pod, который необходимо запланировать на узле 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.