Uwierzytelnianie za pomocą usługi Azure Container Registry (ACR) z usługi Azure Kubernetes Service (AKS)

W przypadku korzystania z Azure Container Registry (ACR) z usługą Azure Kubernetes Service (AKS), należy ustanowić mechanizm uwierzytelniania. Wymagane uprawnienia można skonfigurować między usługami ACR i AKS przy użyciu Azure CLI, Azure PowerShell lub portalu Azure. Ten artykuł zawiera przykłady konfigurowania uwierzytelniania między tymi usługami Azure przy użyciu Azure CLI lub Azure PowerShell.

Integracja usługi AKS z usługą ACR przypisuje rolę AcrPull tożsamości zarządzanej Microsoft Entra ID skojarzonej z pulą agentów w klastrze usługi AKS. Aby uzyskać więcej informacji na temat zarządzanych tożsamości AKS, zobacz Podsumowanie tożsamości zarządzanych.

Ważne

Wystąpił problem z opóźnieniami w przypadku grup Microsoft Entra podczas dołączania usługi ACR. Jeśli rola AcrPull zostanie przypisana grupie Microsoft Entra, a tożsamość kubelet zostanie dodana do grupy w celu ukończenia konfiguracji Azure kontroli dostępu opartej na rolach (Azure RBAC), może wystąpić opóźnienie, zanim grupa RBAC zostanie aktywna. Jeśli uruchamiasz automatyzację, która wymaga ukończenia konfiguracji RBAC Azure, zalecamy użycie Bring własnej tożsamości kubelet jako obejścia. Możesz wstępnie utworzyć tożsamość przypisaną przez użytkownika, dodać ją do grupy Microsoft Entra, a następnie użyć tej tożsamości jako tożsamości kubeletu do utworzenia klastra usługi AKS. Ta metoda zapewnia dodanie tożsamości do grupy Microsoft Entra przed wygenerowaniem tokenu przez narzędzie kubelet, co pozwala uniknąć problemu z opóźnieniami.

Uwaga

W tym artykule opisano automatyczne uwierzytelnianie między usługami AKS i ACR. Jeśli musisz ściągnąć obraz z prywatnego rejestru zewnętrznego, użyj tajnego klucza do ściągania obrazów .

Ostrzeżenie

Integracja AKS-ACR za pomocą az aks --attach-acr nie jest obsługiwana w przypadku rejestrów usługi ACR z włączoną kontrolą dostępu ABAC, w których tryb uprawnień przypisania roli jest ustawiony na "Uprawnienia rejestru RBAC + uprawnienia repozytorium ABAC". Rejestry usługi ACR z kontrolą dostępu opartej na atrybutach (ABAC) wymagają Container Registry Repository Reader roli zamiast AcrPull roli do udzielania uprawnień ściągnięcia obrazu. W przypadku rejestrów usługi ACR z włączoną funkcją ABAC nie należy używać az aks --attach-acr, ale zamiast tego ręcznie przypisz przypisanie roli Container Registry Repository Reader za pomocą portalu Azure, interfejsu wiersza polecenia az role assignment lub Azure Resource Manager. Aby uzyskać więcej informacji na temat rejestrów ACR z włączoną funkcją ABAC, zobacz kontrola dostępu oparta na atrybutach w usłudze Azure.

W tym przewodniku skonfigurujesz klaster Azure Kubernetes Service (AKS) w celu bezpiecznego ściągania obrazów z Azure Container Registry (ACR). W Azure CLI użyj --attach-acr. W programie Terraform przypisz AcrPull rolę do zarządzanej tożsamości kubeleta AKS. Ten przewodnik podąża za tym samym schematem co przepływ pracy Azure CLI, używając Terraform do wdrażania infrastruktury.

Zanim rozpoczniesz

  • Jeśli używasz Azure CLI, ten artykuł wymaga Azure CLI w wersji 2.7.0 lub nowszej. aby znaleźć wersję, uruchom az --version polecenie . Jeśli musisz zainstalować lub uaktualnić, zobacz Install Azure CLI.
  • Jeśli używasz Azure PowerShell, ten artykuł wymaga Azure PowerShell w wersji 5.9.0 lub nowszej. Aby znaleźć wersję, uruchom Get-InstalledModule -Name Az polecenie . Jeśli musisz zainstalować lub uaktualnić, zobacz Install Azure PowerShell.
  • Przykłady i składnia służąca do używania narzędzia Terraform do konfigurowania usługi ACR można znaleźć w dokumentacji programu Terraform.
  • Zainstalowany program Terraform (>= 1.6).
  • Azure CLI zainstalowane i zalogowane do subskrypcji.
  • Uprawnienia do przypisywania ról (właściciel lub administrator dostępu użytkowników).

W tym artykule skonfigurujesz klaster Azure Kubernetes Service (AKS) w celu bezpiecznego ściągania obrazów z Azure Container Registry (ACR). W Azure CLI użyj --attach-acr. W programie Terraform przypisz AcrPull rolę do zarządzanej tożsamości kubeleta AKS.

Ten artykuł podąża za tym samym schematem, co przepływ pracy w Azure CLI przy użyciu narzędzia Terraform do udostępniania infrastruktury. Aby sprawdzić, czy zalogowano się do właściwej subskrypcji, użyj następujących poleceń Azure CLI:

az login
az account show

Utwórz nowy ACR

Jeśli jeszcze nie masz ACR, utwórz ją przy użyciu polecenia az acr create.

Nazwa rejestru musi być globalnie unikatowa w Azure i zawierać od 5 do 50 znaków alfanumerycznych, z wyłączeniem znaków kreski (-). Ta nazwa jest częścią w pełni kwalifikowanej nazwy DNS rejestru.

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

Zmienna RANDOM_STRING przechowuje losowy 10-cyfrowy ciąg. Wartość MYACR jest połączona z wartością RANDOM_STRING w celu utworzenia unikatowej nazwy.

Jeśli jeszcze nie masz ACR, utwórz go przy użyciu polecenia cmdlet New-AzContainerRegistry.

Nazwa rejestru musi być globalnie unikatowa w Azure i zawierać od 5 do 50 znaków alfanumerycznych, z wyłączeniem znaków kreski (-). Ta nazwa jest częścią w pełni kwalifikowanej nazwy DNS rejestru.

$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

Zmienna $RandomString przechowuje losowy 10-cyfrowy ciąg. Wartość $MyAcr jest połączona z wartością $RandomString w celu utworzenia unikatowej nazwy.

Przykład narzędzia Terraform w następnej sekcji tworzy usługę ACR w ramach kompletnego wdrożenia usługi AKS i usługi ACR.

Tworzenie nowego klastra usługi AKS i integracja z istniejącym usługą ACR

Utwórz nowy klaster usługi AKS i zintegruj go z istniejącym usługą ACR przy użyciu az aks create polecenia z parametrem --attach-acr . To polecenie umożliwia autoryzowanie istniejącego rejestru ACR w Twojej subskrypcji i skonfigurowanie odpowiedniej AcrPull roli dla zarządzanej tożsamości.

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

Używanie usługi ACR w innej subskrypcji lub dołączanie przy użyciu identyfikatora zasobu

Jeśli używasz usługi ACR znajdującej się w innej subskrypcji niż klaster usługi AKS lub wolisz użyć identyfikatora zasobu usługi ACR zamiast nazwy usługi ACR, użyj następującej składni. W tym przykładzie jest tworzona zmienna ACR_RESOURCE_ID przy użyciu rejestru kontenerów utworzonego w poprzedniej sekcji.

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

Utwórz nowy klaster usługi AKS i zintegruj to z istniejącą usługą ACR, używając polecenia New-AzAksCluster cmdlet z parametrem -AcrNameToAttach. To polecenie umożliwia autoryzowanie istniejącego rejestru ACR w Twojej subskrypcji i skonfigurowanie odpowiedniej AcrPull roli dla zarządzanej tożsamości.

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

New-AzResourceGroup -Name $ClusterResourceGroup -Location $Location

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

New-AzAksCluster @NewCluster

Używanie usługi ACR w innej subskrypcji lub dołączanie przy użyciu identyfikatora zasobu

Azure PowerShell obsługuje dołączanie usługi ACR do usługi AKS wyłącznie przy użyciu parametru i nie obsługuje dołączania do usługi ACR za pomocą identyfikatora zasobu .

Utwórz plik main.tf i skopiuj do niego następującą przetestowaną przykładową konfigurację. Repozytorium Azure Terraform GitHub przechowuje przykład w repozytorium Azure Terraform GitHub. Przykład tworzy rejestr ACR i klaster AKS, przypisuje rolę AcrPull do tożsamości zarządzanej kubeletu, importuje obraz NGINX do rejestru i wdraża ten obraz w klastrze.

terraform {
  required_version = ">= 1.6.0"
  required_providers {
    azapi = {
      source  = "azure/azapi"
      version = "~> 2.0"
    }
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 4.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "~> 3.6"
    }
    kubernetes = {
      source  = "hashicorp/kubernetes"
      version = "~> 2.30"
    }
  }
}
provider "azurerm" {
  features {}
}
resource "random_string" "suffix" {
  length  = 6
  upper   = false
  special = false
}
locals {
  resource_group_name = "rg-aks-acr-demo"
  location            = "eastus"
  aks_name            = "aks-acr-demo"
  acr_name            = "acraksdemo${random_string.suffix.result}"
}
resource "azurerm_resource_group" "rg" {
  name     = local.resource_group_name
  location = local.location
}
resource "azurerm_container_registry" "acr" {
  name                = local.acr_name
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  sku                 = "Basic"
  admin_enabled       = false
}
resource "azurerm_kubernetes_cluster" "aks" {
  name                = local.aks_name
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  dns_prefix          = local.aks_name
  identity {
    type = "SystemAssigned"
  }
 default_node_pool {
 name       = "systempool"
 node_count = 2
 vm_size    = "Standard_D2s_v3"
 upgrade_settings {
   drain_timeout_in_minutes      = 0
   max_surge                     = "10%"
   node_soak_duration_in_minutes = 0
 }
}
}
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
}
resource "azapi_resource_action" "import_nginx_to_acr" {
  type        = "Microsoft.ContainerRegistry/registries@2023-07-01"
  resource_id = azurerm_container_registry.acr.id
  action      = "importImage"
  method      = "POST"
  body = {
    source = {
      registryUri = "docker.io"
      sourceImage = "library/nginx:latest"
    }
    targetTags = ["nginx:v1"]
    mode       = "Force"
  }
}
provider "kubernetes" {
  host                   = azurerm_kubernetes_cluster.aks.kube_config[0].host
  client_certificate     = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].client_certificate)
  client_key             = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].client_key)
  cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.aks.kube_config[0].cluster_ca_certificate)
}
resource "kubernetes_deployment_v1" "nginx" {
  depends_on = [
    azurerm_role_assignment.aks_acr_pull,
    azapi_resource_action.import_nginx_to_acr
  ]
  metadata {
    name = "nginx0-deployment"
    labels = {
      app = "nginx0-deployment"
    }
  }
  spec {
    replicas = 2
    selector {
      match_labels = {
        app = "nginx0"
      }
    }
    template {
      metadata {
        labels = {
          app = "nginx0"
        }
      }
      spec {
        container {
          name  = "nginx"
          image = "${azurerm_container_registry.acr.login_server}/nginx:v1"
          port {
            container_port = 80
          }
        }
      }
    }
  }
}
output "resource_group_name" {
  value = azurerm_resource_group.rg.name
}
output "aks_cluster_name" {
  value = azurerm_kubernetes_cluster.aks.name
}
output "acr_name" {
  value = azurerm_container_registry.acr.name
}
output "acr_login_server" {
  value = azurerm_container_registry.acr.login_server
}

Konfigurowanie integracji usługi ACR dla istniejącego klastra usługi AKS

Możesz dołączyć usługę ACR do istniejącego klastra usługi AKS lub odłączyć usługę ACR od klastra usługi AKS, jeśli nie chcesz już, aby klaster miał dostęp do rejestru.

W poprzednich przykładach w artykule utworzono Azure Container Registry i klaster Azure Kubernetes Service dołączony do usługi ACR. Poniżej przedstawiono przykłady dołączania lub odłączania rejestru kontenerów z klastra i używania klastra ACR i AKS utworzonego w tym artykule. Możesz zastąpić wartości zmiennych własnymi wartościami klastra ACR i AKS.

Podłącz usługę ACR do istniejącego klastra AKS

Zintegruj istniejący ACR z istniejącym klastrem AKS, używając polecenia az aks update z parametrem --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

Polecenie az aks update --attach-acr używa uprawnień użytkownika uruchamiającego polecenie w celu utworzenia przypisania roli dla usługi ACR. Ta rola jest przypisywana do tożsamości zarządzanej kubelet . Aby uzyskać więcej informacji na temat zarządzanych tożsamości AKS, zobacz Podsumowanie tożsamości zarządzanych.

Zintegruj istniejący ACR z istniejącym klastrem AKS, używając polecenia Set-AzAksCluster z parametrem -AcrNameToAttach.

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

Set-AzAksCluster @AttachCluster

Polecenie Set-AzAksCluster -AcrNameToAttach cmdlet używa uprawnień użytkownika uruchamiającego polecenie do utworzenia przypisania roli ACR. Ta rola jest przypisywana do tożsamości zarządzanej kubelet . Aby uzyskać więcej informacji na temat zarządzanych tożsamości AKS, zobacz Podsumowanie tożsamości zarządzanych.

Przetestowany przykładowy skrypt Terraform tworzy nowe zasoby AKS i ACR. Aby zintegrować istniejące zasoby, użyj karty Azure CLI lub Azure PowerShell albo dostosuj przykładowe AcrPull przypisanie roli tak, aby odwoływało się do istniejących zasobów.

Odłącz ACR od klastra AKS

Usuń integrację między usługą ACR i klastrem usługi AKS przy użyciu az aks update polecenia z parametrem --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

Usuń integrację między usługą ACR i klastrem usługi AKS przy użyciu Set-AzAksCluster polecenia z parametrem -AcrNameToDetach .

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

Set-AzAksCluster @DetachCluster

Przetestowany przykład Terraform nie definiuje oddzielnego przepływu pracy odłączania. Aby cofnąć dostęp, zachowując zasoby usługi AKS i usługi ACR, usuń z konfiguracji oba zasoby: kubernetes_deployment_v1.nginx i azurerm_role_assignment.aks_acr_pull, a następnie zastosuj zaktualizowany plan Terraform.

Inicjowanie i wdrażanie konfiguracji

Po zakończeniu konfiguracji zainicjuj program Terraform i przejrzyj plan wykonania przed zastosowaniem.

terraform fmt
terraform init
terraform validate
terraform plan
terraform apply

Na tym etapie klaster usługi AKS jest skonfigurowany do ściągania obrazów z usługi ACR.

Teraz możesz:

  • Zaimportuj obrazy do usługi ACR.
  • Wdrażanie obciążeń w usłudze AKS.
  • Weryfikacja wdrożenia podu.

Praca z usługami ACR i AKS

Zaimportuj obraz do usługi ACR, a następnie wdróż ten obraz w klastrze usługi AKS.

Importowanie obrazu do usługi ACR

Zaimportuj obraz z Docker Hub do usługi ACR przy użyciu polecenia az acr import.

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

Uruchom następujące polecenia, aby sprawdzić, czy obraz został zaimportowany.

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

Przykład narzędzia Terraform importuje obraz NGINX do usługi ACR podczas wdrażania.

Zaimportuj obraz z Docker Hub do usługi ACR przy użyciu polecenia cmdlet Import-AzContainerRegistryImage.

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

Import-AzContainerRegistryImage @ImportImage

Uruchom następujące polecenia, aby sprawdzić, czy obraz został zaimportowany.

Get-AzContainerRegistryRepository -RegistryName $MyAcr

Get-AzContainerRegistryTag -RegistryName $MyAcr -Repository nginx

Tworzenie pliku wdrożenia

Utwórz wdrożenie platformy Kubernetes, które odwołuje się do obrazu zaimportowanego do usługi ACR. Jeśli wdrożenie zakończy się pomyślnie, a obraz zostanie poprawnie ściągnięty, klaster usługi AKS jest prawidłowo zintegrowany z usługą ACR.

Utwórz plik o nazwie acr-nginx.yaml przy użyciu następującego przykładowego kodu YAML. W właściwości image, zastąp acr-name nazwą twojego ACR. W Azure CLI uruchom polecenie echo $MYACR, aby wyświetlić nazwę usługi ACR. W Azure PowerShell uruchom polecenie $MyAcr, aby wyświetlić nazwę usługi 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

Uzyskaj poświadczenia i przeprowadź wdrożenie

  1. Upewnij się, że masz odpowiednie poświadczenia usługi AKS, używając polecenia az aks get-credentials.

    az aks get-credentials \
      --resource-group $CLUSTER_RESOURCE_GROUP \
      --name $CLUSTER_NAME
    
  2. Uruchom wdrożenie w klastrze AKS przy użyciu polecenia kubectl apply.

    kubectl apply -f acr-nginx.yaml
    
  3. Monitoruj wdrożenie przy użyciu kubectl get pods polecenia .

    kubectl get pods
    

    Dane wyjściowe powinny pokazywać dwa uruchomione pody, jak pokazano w poniższym przykładzie.

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

Przykład Terraform konfiguruje dostawcę Kubernetes i wdraża obciążenie robocze NGINX podczas terraform apply. Pobierz poświadczenia klastra, a następnie zweryfikuj wdrożenie:

RESOURCE_GROUP=$(terraform output -raw resource_group_name)
CLUSTER_NAME=$(terraform output -raw aks_cluster_name)
az aks get-credentials \
  --resource-group $RESOURCE_GROUP \
  --name $CLUSTER_NAME
kubectl get pods
  1. Upewnij się, że masz odpowiednie poświadczenia usługi AKS za pomocą polecenia cmdlet Import-AzAksCredential.

    Import-AzAksCredential -ResourceGroupName $ClusterResourceGroup -Name $ClusterName
    
  2. Uruchom wdrożenie w klastrze AKS przy użyciu polecenia kubectl apply.

    kubectl apply -f acr-nginx.yaml
    
  3. Monitoruj wdrożenie przy użyciu kubectl get pods polecenia .

    kubectl get pods
    

    Dane wyjściowe powinny pokazywać dwa uruchomione pody, jak pokazano w poniższym przykładzie.

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

Rozwiązywanie problemów

Uprzątnij zasoby

Jeśli nie potrzebujesz już zasobów utworzonych w tym artykule, możesz usunąć grupy zasobów, aby usunąć wszystkie skojarzone zasoby. Te polecenia usuwają klaster ACR i AKS oraz grupę zasobów węzłów, która zaczyna się od MC_.

az group delete --name $ACR_RESOURCE_GROUP --yes --no-wait
az group delete --name $CLUSTER_RESOURCE_GROUP --yes --no-wait

Uruchom następujące polecenie z katalogu zawierającego konfigurację narzędzia Terraform:

terraform destroy
Remove-AzResourceGroup -Name $AcrResourceGroup -Force
Remove-AzResourceGroup -Name $ClusterResourceGroup -Force