AKS(Azure Kubernetes Service)에서 ACR(Azure Container Registry)으로 인증

AKS(Azure Kubernetes Service)에서 ACR(Azure Container Registry을 사용하는 경우 인증 메커니즘을 설정해야 합니다. Azure CLI, Azure PowerShell 또는 Azure 포털을 사용하여 ACR과 AKS 간에 필요한 권한을 구성할 수 있습니다. 이 문서에서는 Azure CLI 또는 Azure PowerShell 사용하여 이러한 Azure 서비스 간에 인증을 구성하는 예제를 제공합니다.

AKS to ACR 통합은 AKS 클러스터의 에이전트 풀과 연결된 Microsoft Entra ID 관리 IDAcrPull 역할을 할당합니다. AKS 관리 ID에 대한 자세한 내용은 관리 ID 요약을 참조하세요.

중요함

ACR을 연결할 때 Microsoft Entra 그룹에 대기 시간 문제가 있습니다. AcrPull 역할이 Microsoft Entra 그룹에 부여되고 kubelet 정체성이 그룹에 추가되어 Azure RBAC(역할 기반 액세스 제어) 구성을 완료하는 경우, RBAC 그룹이 적용되기 전에 지연이 발생할 수 있습니다. Azure RBAC 구성을 완료해야 하는 자동화를 실행하는 경우 해결 방법으로 자체 kubelet ID 작성을 사용하는 것이 좋습니다. 사용자 할당 ID를 미리 만들고, Microsoft Entra 그룹에 추가한 다음, ID를 kubelet ID로 사용하여 AKS 클러스터를 만들 수 있습니다. 이 메서드는 kubelet에서 토큰을 생성하기 전에 id가 Microsoft Entra 그룹에 추가되어 대기 시간 문제를 방지합니다.

참고

이 문서에서는 AKS와 ACR 간의 자동 인증을 다룹니다. 프라이빗 외부 레지스트리에서 이미지를 풀해야 하는 경우 이미지 풀 비밀을 사용합니다.

주의

역할 할당 권한 모드가 "RBAC 레지스트리 + ABAC 리포지토리 권한"으로 설정된 ABAC 지원 ACR 레지스트리에는 AKS-ACR 통합 az aks --attach-acr 이 지원되지 않습니다. ABAC 사용 ACR 레지스트리에는 이미지 끌어오기 권한을 부여하는 역할 대신 Container Registry Repository Reader 역할이 필요합니다AcrPull. ABAC 사용 ACR 레지스트리의 경우 az aks --attach-acr 대신 Azure 포털, Container Registry Repository Reader CLI 또는 Azure Resource Manager 사용하여 az role assignment 역할 할당을 수동으로 할당해야 합니다. ABAC 사용 ACR 레지스트리에 대한 자세한 내용은 Azure 특성 기반 액세스 제어 참조하세요.

이 연습에서는 ACR(Azure Container Registry)에서 이미지를 안전하게 끌어오도록 AKS(Azure Kubernetes Service) 클러스터를 구성합니다. Azure CLI에서 --attach-acr를 사용합니다. Terraform에서 AKS kubelet 관리 ID에 AcrPull 역할을 할당합니다. 이 가이드는 인프라 프로비저닝에 Terraform을 사용하는 동안 Azure CLI 워크플로와 동일한 흐름을 따릅니다.

시작하기 전에

  • Azure CLI 사용하는 경우 이 문서에서는 Azure CLI 버전 2.7.0 이상을 실행해야 합니다. 버전을 찾으려면 명령을 실행합니다 az --version . 설치하거나 업그레이드해야 하는 경우 Azure CLI 설치를 참조하세요.
  • Azure PowerShell 사용하는 경우 이 문서에서는 Azure PowerShell 버전 5.9.0 이상을 실행해야 합니다. 버전을 찾으려면 Get-InstalledModule -Name Az 명령을 실행합니다. 설치하거나 업그레이드해야 하는 경우 Azure PowerShell 설치를 참조하세요.
  • ACR을 구성하기 위해 Terraform을 사용하는 예제 및 구문은 Terraform 참조에서 찾을 수 있습니다.
  • Terraform이 설치되었습니다(>= 1.6).
  • Azure CLI 구독을 설치하고 로그인했습니다.
  • 역할을 할당할 수 있는 권한(소유자 또는 사용자 액세스 관리자).

이 문서에서는 ACR(Azure Container Registry)에서 이미지를 안전하게 끌어오도록 AKS(Azure Kubernetes Service) 클러스터를 구성합니다. Azure CLI에서 --attach-acr를 사용하십시오. Terraform에서 AKS kubelet 관리 ID에 AcrPull 역할을 할당합니다.

이 문서에서는 인프라 프로비저닝에 Terraform을 사용하는 동안 Azure CLI 워크플로와 동일한 흐름을 따릅니다. 올바른 구독에 로그인했는지 확인하려면 다음 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 Container Registry 이름이 기존 레지스트리와 충돌하지 않습니다.

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 클러스터를 만들고 az aks create 명령과 --attach-acr 매개 변수를 사용하여 기존 ACR과 통합합니다. 이 명령을 사용하면 구독에서 기존 ACR에 권한을 부여하고 관리 ID에 대한 적절한 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을 사용하거나 리소스 ID를 사용하여 연결

AKS 클러스터와 다른 구독에 있는 ACR을 사용하거나 ACR 이름 대신 ACR 리소스 ID 를 사용하려는 경우 다음 구문을 사용합니다. 이 예제에서는 이전 섹션에서 만든 컨테이너 레지스트리를 사용하여 변수를 만듭니다 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 클러스터를 새로 만들고 New-AzAksCluster cmdlet을 -AcrNameToAttach 매개 변수와 함께 사용하여 기존 ACR과 통합합니다. 이 명령을 사용하면 구독에서 기존 ACR에 권한을 부여하고 관리 ID에 대한 적절한 AcrPull 역할을 구성할 수 있습니다.

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

New-AzResourceGroup -Name $ClusterResourceGroup -Location $Location

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

New-AzAksCluster @NewCluster

다른 구독에서 ACR을 사용하거나 리소스 ID를 사용하여 연결

Azure PowerShell -AcrNameToAttach 매개 변수를 사용하여 AKS에 ACR을 연결하는 것만 지원하며 resource ID ACR에 연결하는 것을 지원하지 않습니다.

다음으로 리소스 그룹 및 Azure Container Registry 만듭니다. 이 레지스트리는 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 클러스터를 만듭니다. 이 클러스터는 이미지를 끌어올 수 있는 권한이 부여되는 시스템 할당 관리 ID를 사용합니다.

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
}

기존 AKS 클러스터에 대한 ACR 통합 구성

ACR을 기존 AKS 클러스터에 연결하거나 클러스터가 레지스트리에 더 이상 액세스하지 않도록 하려면 AKS 클러스터에서 ACR을 분리할 수 있습니다.

문서의 이전 예제에서는 ACR에 연결된 Azure Container Registry 및 Azure Kubernetes Service 클러스터를 만들었습니다. 다음은 클러스터에서 컨테이너 레지스트리를 연결하거나 분리하고 이 문서에서 만든 ACR 및 AKS 클러스터를 사용하는 방법의 예입니다. 변수 값을 고유한 ACR 및 AKS 클러스터 값으로 바꿀 수 있습니다.

기존 AKS 클러스터에 ACR 연결

az aks update 명령과 --attach-acr 매개 변수를 사용하여 기존 ACR을 기존 AKS 클러스터와 통합합니다.

# 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 관리 ID에 할당됩니다. AKS 관리 ID에 대한 자세한 내용은 관리 ID 요약을 참조하세요.

기존 ACR을 기존 AKS 클러스터와 통합하려면 Set-AzAksCluster 명령과 -AcrNameToAttach 매개 변수를 사용하세요.

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

Set-AzAksCluster @AttachCluster

cmdlet은 Set-AzAksCluster -AcrNameToAttach 명령을 실행하는 사용자의 권한을 사용하여 역할 ACR 할당을 만듭니다. 이 역할은 kubelet 관리 ID에 할당됩니다. AKS 관리 ID에 대한 자세한 내용은 관리 ID 요약을 참조하세요.

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
}

AKS 클러스터에서 ACR을 분리하기

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

Set-AzAksCluster 명령과 -AcrNameToDetach 매개 변수를 사용하여 ACR과 AKS 클러스터 간의 통합을 제거합니다.

$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로 이미지 가져오기

az acr import 명령을 사용하여 Docker Hub 이미지를 ACR로 가져옵니다.

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

Import-AzContainerRegistryImage cmdlet을 사용하여 Docker Hub 이미지를 ACR로 가져옵니다.

$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

배포 파일 만들기

ACR로 가져온 이미지를 참조하는 Kubernetes 배포를 만듭니다. 배포에 성공하고 이미지가 올바르게 끌어오면 AKS 클러스터가 ACR과 제대로 통합됩니다.

다음 샘플 YAML을 사용하여 acr-nginx.yaml 이라는 파일을 만듭니다. 속성에서 imageacr-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. az aks get-credentials 명령을 사용하여 적절한 AKS 자격 증명을 보유해야 합니다.

    az aks get-credentials \
      --resource-group $CLUSTER_RESOURCE_GROUP \
      --name $CLUSTER_NAME
    
  2. kubectl apply 명령을 사용하여 AKS 클러스터에서 배포를 실행합니다.

    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. Import-AzAksCredential cmdlet을 사용하여 적절한 AKS 자격 증명을 보유해야 합니다.

    Import-AzAksCredential -ResourceGroupName $ClusterResourceGroup -Name $ClusterName
    
  2. kubectl apply 명령을 사용하여 AKS 클러스터에서 배포를 실행합니다.

    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
    

문제 해결

  • az aks check-acr 명령을 사용하여 AKS 클러스터에서 레지스트리에 액세스할 수 있는지 확인합니다.
  • AKS 클러스터가 HTTP 프록시를 사용하고 ACR이 Private Link 사용하는 경우 클러스터 noProxy 목록에 ACR 엔드포인트(REST 및 데이터)를 모두 추가합니다. 자세한 내용은 AKS(Azure Kubernetes Service)의 HTTP 프록시 지원을 참조하세요.
  • ACR 모니터링에 대해 자세히 알아봅니다.
  • ACR 상태에 대해 자세히 알아봅니다.

자원을 정리하세요

이 문서에서 만든 리소스가 더 이상 필요하지 않은 경우 리소스 그룹을 삭제하여 연결된 모든 리소스를 제거할 수 있습니다. 이러한 명령은 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