Проверка подлинности с помощью Реестр контейнеров Azure (ACR) из службы Azure Kubernetes (AKS)

При использовании Реестр контейнеров Azure (ACR) со службой Azure Kubernetes (AKS) необходимо установить механизм проверки подлинности. Вы можете настроить необходимые разрешения между ACR и AKS с помощью Azure CLI, Azure PowerShell или портала Azure. В этой статье приведены примеры настройки проверки подлинности между этими службами Azure с помощью Azure CLI или Azure PowerShell.

Интеграция AKS с ACR назначает роль AcrPull управляемому удостоверению Microsoft Entra ID, связанному с пулом агентов в кластере AKS. Дополнительные сведения об управляемых удостоверениях AKS см. в разделе Сводка об управляемых удостоверениях.

Важный

При присоединении ACR возникает проблема с задержкой в группах Microsoft Entra. Если роль AcrPull предоставляется группе Microsoft Entra, а удостоверение kubelet добавляется в группу, чтобы завершить настройку управления доступом на основе ролей Azure (Azure RBAC), может возникнуть задержка до того, как группа RBAC вступает в силу. Если вы выполняете автоматизацию, требующую завершения настройки RBAC Azure, рекомендуем использовать Принесите свое собственное удостоверение kubelet как обходное решение. Вы можете предварительно создать пользовательское удостоверение, добавить его в группу Microsoft Entra, а затем использовать в качестве удостоверения kubelet для создания кластера AKS. Этот метод гарантирует, что учетная запись добавляется в группу Microsoft Entra перед созданием токена аутентификации kubelet, что позволяет избежать проблемы с задержкой.

Примечание

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

Caution

Интеграция AKS-ACR через не поддерживается для реестров ACR с поддержкой ABAC, где для режима разрешений на назначение ролей задано значение "RBAC Registry + ABAC Repository Permissions". Реестры ACR с поддержкой ABAC требуют роль вместо роли для предоставления разрешений на извлечение образов. Для реестров ACR с поддержкой ABAC не следует использовать az aks --attach-acr, а вручную назначить назначение роли Container Registry Repository Reader с помощью портала Azure, az role assignment CLI или Azure Resource Manager. Дополнительные сведения о реестрах ACR с поддержкой ABAC см. в разделе Azure управление доступом на основе атрибутов.

В этом пошаговом руководстве вы настроите кластер Azure Kubernetes Service (AKS) для безопасного извлечения образов из Реестр контейнеров Azure (ACR). В Azure CLI используйте --attach-acr. В Terraform назначьте AcrPull роль управляемому идентификатору AKS kubelet. Это руководство следует тому же потоку, что и рабочий процесс Azure CLI при использовании Terraform для подготовки инфраструктуры.

Перед тем как начать

  • Если вы используете Azure CLI, рекомендуется, чтобы вы работали с Azure CLI версии 2.7.0 или более поздней. Чтобы найти версию, выполните az --version команду. Если необходимо установить или обновить, см. раздел Install Azure CLI.
  • Если вы используете Azure PowerShell, для применения этой статьи требуется, чтобы вы использовали Azure PowerShell версии не ниже 5.9.0. Чтобы найти версию, выполните команду Get-InstalledModule -Name Az. Если необходимо установить или обновить, см. раздел Install Azure PowerShell.
  • Примеры и синтаксис для использования Terraform для настройки ACR можно найти в справочнике Terraform.
  • Установлен Terraform (>= 1.6).
  • Azure CLI установлено и выполнен вход в вашу подписку.
  • Разрешения на назначение ролей (владелец или администратор доступа пользователей).

В этой статье описана настройка кластера Azure Kubernetes Service (AKS) для безопасного извлечения образов из Реестр контейнеров Azure (ACR). В Azure CLI используйте --attach-acr. В Terraform назначьте роль AcrPull управляемой идентичности kubelet в AKS.

Эта статья следует тому же процессу, что и рабочий процесс Azure CLI, при использовании Terraform для развертывания инфраструктуры. Чтобы убедиться, что вы вошли в правильную подписку, используйте следующие команды Azure CLI:

az login
az account show

Создание нового ACR

Если у вас еще нет ACR, создайте его с помощью az acr create команды.

Имя реестра должно быть глобально уникальным в Azure и содержать 5–50 буквенно-цифровых символов, за исключением символов дефиса (-). Это имя является частью полного имени реестра в DNS.

export RANDOM_STRING=$(printf '%05d%05d' "$RANDOM" "$RANDOM")
export MYACR="mycontainerregistry$RANDOM_STRING"
export ACR_RESOURCE_GROUP="myContainerRegistryResourceGroup"
export LOCATION="westcentralus"

az group create \
  --name $ACR_RESOURCE_GROUP \
  --location $LOCATION

az acr create \
  --name $MYACR \
  --resource-group $ACR_RESOURCE_GROUP \
  --sku basic

Переменная RANDOM_STRING хранит случайную 10-разрядную строку. Значение MYACR объединяется со RANDOM_STRING значением для создания уникального имени.

Если у вас еще нет ACR, создайте его с помощью командлета New-AzContainerRegistry .

Имя реестра должно быть глобально уникальным в Azure и содержать 5–50 буквенно-цифровых символов, за исключением символов дефиса (-). Это имя является частью полного имени реестра в DNS.

$RandomString = (Get-Random -Minimum 1000000000 -Maximum 10000000000).ToString()
$MyAcr = "mycontainerregistry$RandomString"
$AcrResourceGroup = "myContainerRegistryResourceGroup"
$Location = "westcentralus"

New-AzResourceGroup -Name $AcrResourceGroup -Location $Location

$NewAcr = @{
 Name = $MyAcr
 ResourceGroupName = $AcrResourceGroup
 Location = $Location
 Sku = "Basic"
}

New-AzContainerRegistry @NewAcr

Переменная $RandomString хранит случайную 10-разрядную строку. Значение $MyAcr объединяется со $RandomString значением для создания уникального имени.

Создайте файл main.tf для конфигурации и начните с определения поставщиков Terraform и создания уникального суффикса для глобальных уникальных имен ресурсов. Глобально уникальное имя гарантирует, что имя Реестр контейнеров Azure не конфликтует с существующими реестрами.

terraform {
 required_version = ">= 1.6.0"
 required_providers {
   azurerm = {
     source  = "hashicorp/azurerm"
     version = "~> 4.0"
   }
   random = {
     source  = "hashicorp/random"
     version = "~> 3.6"
   }
 }
}
provider "azurerm" {
 features {}
}
resource "random_string" "suffix" {
 length  = 6
 upper   = false
 special = false
}

Создание кластера AKS и интеграция с существующим ACR

Создайте новый кластер AKS и интегрируйте с существующим ACR с помощью az aks create команды с параметром --attach-acr . Эта команда позволяет авторизовать существующий ACR в подписке и настроить соответствующую AcrPull роль для управляемого удостоверения.

export CLUSTER_NAME="myAKSCluster"
export CLUSTER_RESOURCE_GROUP="myClusterResourceGroup"

az group create \
  --name $CLUSTER_RESOURCE_GROUP \
  --location $LOCATION

az aks create \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --generate-ssh-keys \
  --attach-acr $MYACR

Использование ACR в другой подписке или подключение с помощью идентификатора ресурса

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

ACR_RESOURCE_ID=$(az acr show \
  --name $MYACR \
  --resource-group $ACR_RESOURCE_GROUP \
  --query id --output tsv)

az aks create \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --generate-ssh-keys \
  --attach-acr $ACR_RESOURCE_ID

Создайте новый кластер AKS и интегрируйте его с существующим ACR с помощью командлета New-AzAksCluster и параметра -AcrNameToAttach. Эта команда позволяет авторизовать существующий ACR в подписке и настроить соответствующую AcrPull роль для управляемого удостоверения.

$ClusterName = "myAKSCluster"
$ClusterResourceGroup = "myClusterResourceGroup"

New-AzResourceGroup -Name $ClusterResourceGroup -Location $Location

$NewCluster = @{
 Name = $ClusterName
 ResourceGroupName = $ClusterResourceGroup
 GenerateSshKey = $true
 AcrNameToAttach = $MyAcr
}

New-AzAksCluster @NewCluster

Использование ACR в другой подписке или присоединение с помощью идентификатора ресурса

Azure PowerShell поддерживает только присоединение ACR к AKS с помощью параметра -AcrNameToAttach и не поддерживает присоединение к ACR с помощью идентификатора resource ID.

Затем создайте группу ресурсов и Реестр контейнеров Azure. В этом реестре хранятся образы контейнеров, которые кластер AKS извлекает позже.

locals {
 location           = "westcentralus"
 acr_name           = "myacr${random_string.suffix.result}"
 acr_resource_group = "myContainerRegistryResourceGroup"
}
resource "azurerm_resource_group" "acr_rg" {
 name     = local.acr_resource_group
 location = local.location
}
resource "azurerm_container_registry" "acr" {
 name                = local.acr_name
 resource_group_name = azurerm_resource_group.acr_rg.name
 location            = azurerm_resource_group.acr_rg.location
 sku                 = "Basic"
 admin_enabled       = false
}

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

locals {
 aks_name           = "myAKSCluster"
 aks_resource_group = "myClusterResourceGroup"
}
resource "azurerm_resource_group" "aks_rg" {
 name     = local.aks_resource_group
 location = local.location
}
resource "azurerm_kubernetes_cluster" "aks" {
 name                = local.aks_name
 location            = azurerm_resource_group.aks_rg.location
 resource_group_name = azurerm_resource_group.aks_rg.name
 dns_prefix          = local.aks_name
 identity {
   type = "SystemAssigned"
 }
 default_node_pool {
   name       = "systempool"
   node_count = 2
   vm_size    = "Standard_DS2_v2"
 }
}

На этом этапе кластер AKS существует, но у него еще нет доступа к реестру контейнеров. В Azure CLI используйте параметр --attach-acr. В Terraform вы явно назначаете роль AcrPull.

resource "azurerm_role_assignment" "aks_acr_pull" {
 scope                = azurerm_container_registry.acr.id
 role_definition_name = "AcrPull"
 principal_id         = azurerm_kubernetes_cluster.aks.kubelet_identity[0].object_id
}

Настройка интеграции ACR для существующего кластера AKS

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

Предыдущие примеры в статье создали Реестр контейнеров Azure и кластер Служба Azure Kubernetes, подключенный к ACR. Ниже приведены примеры подключения или отключения реестра контейнеров из кластера и использования кластера ACR и AKS, созданного в этой статье. Значения переменных можно заменить собственными значениями кластера ACR и AKS.

Присоединение ACR к существующему кластеру AKS

Интегрируйте существующий ACR с существующим кластером AKS с помощью команды az aks update с параметром --attach-acr.

# Attach using acr-name
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --attach-acr $MYACR


# Attach using acr-resource-id
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --attach-acr $ACR_RESOURCE_ID

Команда az aks update --attach-acr использует разрешения пользователя, выполняющего команду, для создания назначения роли ACR. Эта роль назначается управляемому удостоверению kubelet . Дополнительные сведения об управляемых удостоверениях AKS см. в разделе Сводка об управляемых удостоверениях.

Интегрируйте существующий ACR с существующим кластером AKS с помощью команды Set-AzAksCluster и параметра -AcrNameToAttach.

$AttachCluster = @{
 Name = $ClusterName
 ResourceGroupName = $ClusterResourceGroup
 AcrNameToAttach = $MyAcr
}

Set-AzAksCluster @AttachCluster

Командлет Set-AzAksCluster -AcrNameToAttach использует разрешения пользователя, выполняющего команду, для создания назначения роли ACR. Эта роль назначается управляемому удостоверению kubelet . Дополнительные сведения об управляемых удостоверениях AKS см. в разделе Сводка об управляемых удостоверениях.

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

data "azurerm_kubernetes_cluster" "existing_aks" {
 name                = "myAKSCluster"
 resource_group_name = "myClusterResourceGroup"
}
data "azurerm_container_registry" "existing_acr" {
 name                = "mycontainerregistry"
 resource_group_name = "myContainerRegistryResourceGroup"
}
resource "azurerm_role_assignment" "existing_aks_acr_pull" {
 scope                = data.azurerm_container_registry.existing_acr.id
 role_definition_name = "AcrPull"
 principal_id         = data.azurerm_kubernetes_cluster.existing_aks.kubelet_identity[0].object_id
}

Отсоединение ACR от кластера AKS

Удалите интеграцию между ACR и кластером AKS с помощью az aks update команды с параметром --detach-acr .

# Detach using acr-name
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --detach-acr $MYACR

# Detach using acr-resource-id
az aks update \
  --name $CLUSTER_NAME \
  --resource-group $CLUSTER_RESOURCE_GROUP \
  --detach-acr $ACR_RESOURCE_ID

Удалите интеграцию между ACR и кластером AKS с помощью Set-AzAksCluster команды с параметром -AcrNameToDetach .

$DetachCluster = @{
 Name = $ClusterName
 ResourceGroupName = $ClusterResourceGroup
 AcrNameToDetach = $MyAcr
}

Set-AzAksCluster @DetachCluster

Чтобы удалить доступ, удалите роль, которая предоставляет кластеру разрешение на загрузку образов.

# Remove this resource to revoke access
# resource "azurerm_role_assignment" "existing_aks_acr_pull" {
#   scope                = data.azurerm_container_registry.existing_acr.id
#   role_definition_name = "AcrPull"
#   principal_id         = data.azurerm_kubernetes_cluster.existing_aks.kubelet_identity[0].object_id
# }

Инициализация и развертывание конфигурации

После завершения настройки инициализируйте Terraform и просмотрите план выполнения перед применением.

terraform fmt
terraform init
terraform validate
terraform plan
terraform apply

На этом этапе кластер AKS настроен для извлечения образов из ACR.

Теперь вы можете:

  • Импорт изображений в ACR.
  • Развертывание рабочих нагрузок в AKS.
  • Проверьте развертывание pod.

Работа с ACR и AKS

Импортируйте образ в ACR, а затем разверните этот образ в кластере AKS.

Импорт изображения в ACR

Импортируйте изображение из Docker Hub в ACR с помощью команды az acr import.

az acr import \
  --name $MYACR \
  --source docker.io/library/nginx:latest \
  --image nginx:v1

Выполните следующие команды, чтобы убедиться, что образ импортирован.

az acr repository show --name $MYACR --repository nginx
az acr repository show-tags --name $MYACR --repository nginx

Импортируйте изображение из Docker Hub в ACR с помощью командлета Import-AzContainerRegistryImage.

$ImportImage = @{
 RegistryName = $MyAcr
 ResourceGroupName = $AcrResourceGroup
 SourceRegistryUri = 'docker.io'
 SourceImage = 'library/nginx:latest'
 TargetTag = 'nginx:v1'
}

Import-AzContainerRegistryImage @ImportImage

Выполните следующие команды, чтобы убедиться, что образ импортирован.

Get-AzContainerRegistryRepository -RegistryName $MyAcr

Get-AzContainerRegistryTag -RegistryName $MyAcr -Repository nginx

Создание файла развертывания

Создайте развертывание Kubernetes, которое ссылается на образ, импортированный в ACR. Если развертывание выполнено успешно, и образ извлекается правильно, кластер AKS правильно интегрирован с ACR.

Создайте файл с именем acr-nginx.yaml , используя следующий пример YAML. В свойстве image, замените acr-name на имя вашего ACR. В Azure CLI выполните команду echo $MYACR, чтобы отобразить имя ACR. В Azure PowerShell запустите $MyAcr, чтобы отобразить имя ACR.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx0-deployment
  labels:
    app: nginx0-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx0
  template:
    metadata:
      labels:
        app: nginx0
    spec:
      containers:
      - name: nginx
        image: <acr-name>.azurecr.io/nginx:v1
        ports:
        - containerPort: 80

Получение учетных данных и запуск развертывания

  1. Убедитесь, что у вас есть правильные учетные данные AKS с помощью az aks get-credentials команды.

    az aks get-credentials \
      --resource-group $CLUSTER_RESOURCE_GROUP \
      --name $CLUSTER_NAME
    
  2. Запустите развертывание в кластере AKS с помощью команды kubectl apply.

    kubectl apply -f acr-nginx.yaml
    
  3. Контролируйте развертывание с помощью команды kubectl get pods.

    kubectl get pods
    

    Выходные данные должны отображать два запущенных модуля pod, как показано в следующем примере выходных данных:

    NAME                                 READY   STATUS    RESTARTS   AGE
    nginx0-deployment-669dfc4d4b-x74kr   1/1     Running   0          20s
    nginx0-deployment-669dfc4d4b-xdpd6   1/1     Running   0          20s
    
  1. Убедитесь, что у вас есть корректные учетные данные AKS с помощью cmdlet Import-AzAksCredential.

    Import-AzAksCredential -ResourceGroupName $ClusterResourceGroup -Name $ClusterName
    
  2. Запустите развертывание в кластере AKS с помощью команды kubectl apply.

    kubectl apply -f acr-nginx.yaml
    
  3. Контролируйте развертывание с помощью команды kubectl get pods.

    kubectl get pods
    

    Выходные данные должны отображать два запущенных модуля pod, как показано в следующем примере выходных данных:

    NAME                                 READY   STATUS    RESTARTS   AGE
    nginx0-deployment-669dfc4d4b-x74kr   1/1     Running   0          20s
    nginx0-deployment-669dfc4d4b-xdpd6   1/1     Running   0          20s
    

Устранение неисправностей

Очистите ресурсы

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

az group delete --name $ACR_RESOURCE_GROUP --yes --no-wait
az group delete --name $CLUSTER_RESOURCE_GROUP --yes --no-wait
Remove-AzResourceGroup -Name $AcrResourceGroup -Force
Remove-AzResourceGroup -Name $ClusterResourceGroup -Force