Raw New Markdown
Generating updated version of doc...
Rendered New Markdown
Generating updated version of doc...
---
title: Integrate Azure Container Registry with Azure Kubernetes Service (AKS)
description: Learn how to integrate Azure Kubernetes Service (AKS) with Azure Container Registry (ACR).
ms.topic: concept-article
ms.date: 11/08/2024
author: davidsmatlak
ms.author: davidsmatlak
ms.tool: azure-cli, azure-powershell
ms.devlang: azurecli
ms.custom: devx-track-azurepowershell, devx-track-azurecli
# Customer intent: As a cloud administrator, I want to integrate Azure Container Registry with Azure Kubernetes Service, so that I can streamline the deployment of container images and manage access permissions efficiently.
---
# Authenticate with Azure Container Registry (ACR) from Azure Kubernetes Service (AKS)
When using [Azure Container Registry (ACR)][acr-intro] with Azure Kubernetes Service (AKS), you need to establish an authentication mechanism. You can configure the required permissions between ACR and AKS using the Azure CLI, Azure PowerShell, or Azure portal. This article provides examples to configure authentication between these Azure services using the Azure CLI or Azure PowerShell.
The AKS to ACR integration assigns the [**AcrPull** role][acr-pull] to the [Microsoft Entra ID **managed identity**][aad-identity] associated with the agent pool in your AKS cluster. For more information on AKS managed identities, see [Summary of managed identities][summary-msi].
> [!IMPORTANT]
> There's a latency issue with Microsoft Entra groups when attaching ACR. If the **AcrPull** role is granted to a Microsoft Entra group and the kubelet identity is added to the group to complete the RBAC configuration, there may be a delay before the RBAC group takes effect. If you're running automation that requires the RBAC configuration to be complete, we recommend you use [Bring your own kubelet identity][byo-kubelet-identity] as a workaround. You can pre-create a user-assigned identity, add it to the Microsoft Entra group, then use the identity as the kubelet identity to create an AKS cluster. This ensures the identity is added to the Microsoft Entra group before a token is generated by kubelet, which avoids the latency issue.
> [!NOTE]
> This article covers automatic authentication between AKS and ACR. If you need to pull an image from a private external registry, use an [image pull secret][image-pull-secret].
> [!CAUTION]
> The AKS-ACR integration through `az aks --attach-acr` is not supported for ABAC-enabled ACR registries where the role assignment permissions mode is set to "RBAC Registry + ABAC Repository Permissions." ABAC-enabled ACR registries require the [`Container Registry Repository Reader` role](/azure/role-based-access-control/built-in-roles#container-registry-repository-reader) instead of the `AcrPull` role for granting image pull permissions. For ABAC-enabled ACR registries, you should not use `az aks --attach-acr` but instead manually assign the `Container Registry Repository Reader` role assignment using either the Azure Portal, `az role assignment` CLI, or Azure Resource Manager. Please visit https://aka.ms/acr/auth/abac for more information on ABAC-enabled ACR registries.
## Before you begin
* You need the [**Owner**][rbac-owner], [**Azure account administrator**][rbac-classic], or [**Azure co-administrator**][rbac-classic] role on your Azure subscription.
* To avoid needing one of these roles, you can instead use an existing managed identity to authenticate ACR from AKS. For more information, see [Use an Azure managed identity to authenticate to an ACR](/azure/container-registry/container-registry-authentication-managed-identity).
* If you're using Azure CLI, this article requires that you're running Azure CLI version 2.7.0 or later. Run `az --version` to find the version. If you need to install or upgrade, see [Install Azure CLI][azure-cli-install].
* If you're using Azure PowerShell, this article requires that you're running Azure PowerShell version 5.9.0 or later. Run `Get-InstalledModule -Name Az` to find the version. If you need to install or upgrade, see [Install Azure PowerShell][azure-powershell-install].
* Examples and syntax to use Terraform for configuring ACR can be found in the [Terraform reference][terraform-reference].
## Create a new ACR
#### [Azure CLI](#tab/azure-cli)
* If you don't already have an ACR, create one using the [`az acr create`][az-acr-create] command. The following example sets the `MYACR` variable to the name of the ACR, *mycontainerregistry*, and uses the variable to create the registry. Your ACR name must be globally unique and use only lowercase letters.
```azurecli-interactive
MYACR=mycontainerregistry
az acr create --name $MYACR --resource-group myContainerRegistryResourceGroup --sku basic
```
#### [Azure PowerShell](#tab/azure-powershell)
* If you don't already have an ACR, create one using the [`New-AzContainerRegistry`][new-azcontainerregistry] cmdlet. The following example sets the `MYACR` variable to the name of the ACR, *mycontainerregistry*, and uses the variable to create the registry. Your ACR name must be globally unique and use only lowercase letters.
```azurepowershell-interactive
$MYACR = 'mycontainerregistry'
New-AzContainerRegistry -Name $MYACR -ResourceGroupName myContainerRegistryResourceGroup -Sku Basic
```
---
## Create a new AKS cluster and integrate with an existing ACR
#### [Azure CLI](#tab/azure-cli)
* Create a new AKS cluster and integrate with an existing ACR using the [`az aks create`][az-aks-create] command with the [`--attach-acr` parameter][cli-param]. This command allows you to authorize an existing ACR in your subscription and configures the appropriate **AcrPull** role for the managed identity.
```azurecli-interactive
MYACR=mycontainerregistry
az aks create --name myAKSCluster --resource-group myResourceGroup --generate-ssh-keys --attach-acr $MYACR
```
This command may take several minutes to complete.
> [!NOTE]
> If you're using an ACR located in a different subscription from your AKS cluster or would prefer to use the ACR *resource ID* instead of the ACR name, you can do so using the following syntax:
>
> ```azurecli
> az aks create -n myAKSCluster -g myResourceGroup --generate-ssh-keys --attach-acr /subscriptions/<subscription-id>/resourceGroups/myContainerRegistryResourceGroup/providers/Microsoft.ContainerRegistry/registries/myContainerRegistry
> ```
#### [Azure PowerShell](#tab/azure-powershell)
* Create a new AKS cluster and integrate with an existing ACR using the [`New-AzAksCluster`][new-azakscluster] cmdlet with the [`-AcrNameToAttach` parameter][ps-attach] parameter. This command allows you to authorize an existing ACR in your subscription and configures the appropriate **AcrPull** role for the managed identity.
```azurepowershell-interactive
$MYACR = 'mycontainerregistry'
New-AzAksCluster -Name myAKSCluster -ResourceGroupName myResourceGroup -GenerateSshKey -AcrNameToAttach $MYACR
```
This command may take several minutes to complete.
---
## Configure ACR integration for an existing AKS cluster
### Attach an ACR to an existing AKS cluster
#### [Azure CLI](#tab/azure-cli)
* Integrate an existing ACR with an existing AKS cluster using the [`az aks update`][az-aks-update] command with the [`--attach-acr` parameter][cli-param] and a valid value for **acr-name** or **acr-resource-id**.
```azurecli-interactive
# Attach using acr-name
az aks update --name myAKSCluster --resource-group myResourceGroup --attach-acr <acr-name>
# Attach using acr-resource-id
az aks update --name myAKSCluster --resource-group myResourceGroup --attach-acr <acr-resource-id>
```
> [!NOTE]
> The `az aks update --attach-acr` command uses the permissions of the user running the command to create the ACR role assignment. This role is assigned to the [kubelet][kubelet] managed identity. For more information on AKS managed identities, see [Summary of managed identities][summary-msi].
#### [Azure PowerShell](#tab/azure-powershell)
* Integrate an existing ACR with an existing AKS cluster using the [`Set-AzAksCluster`][set-azakscluster] command with the [`-AcrNameToAttach` parameter][ps-attach] and a valid value for **acr-name**.
```azurepowershell-interactive
Set-AzAksCluster -Name myAKSCluster -ResourceGroupName myResourceGroup -AcrNameToAttach <acr-name>
```
> [!NOTE]
> Running the `Set-AzAksCluster -AcrNameToAttach` cmdlet uses the permissions of the user running the command to create the role ACR assignment. This role is assigned to the [kubelet][kubelet] managed identity. For more information on AKS managed identities, see [Summary of managed identities][summary-msi].
---
### Detach an ACR from an AKS cluster
#### [Azure CLI](#tab/azure-cli)
* Remove the integration between an ACR and an AKS cluster using the [`az aks update`][az-aks-update] command with the [`--detach-acr` parameter][cli-param] and a valid value for **acr-name** or **acr-resource-id**.
```azurecli-interactive
# Detach using acr-name
az aks update --name myAKSCluster --resource-group myResourceGroup --detach-acr <acr-name>
# Detach using acr-resource-id
az aks update --name myAKSCluster --resource-group myResourceGroup --detach-acr <acr-resource-id>
```
#### [Azure PowerShell](#tab/azure-powershell)
* Remove the integration between an ACR and an AKS cluster using the [`Set-AzAksCluster`][set-azakscluster] command with the [`-AcrNameToDetach` parameter][ps-detach] and a valid value for **acr-name**.
```azurepowershell-interactive
Set-AzAksCluster -Name myAKSCluster -ResourceGroupName myResourceGroup -AcrNameToDetach <acr-name>
```
---
## Working with ACR & AKS
### Import an image into your ACR
#### [Azure CLI](#tab/azure-cli)
* Import an image from Docker Hub into your ACR using the [`az acr import`][az-acr-import] command.
```azurecli-interactive
az acr import --name <acr-name> --source docker.io/library/nginx:latest --image nginx:v1
```
#### [Azure PowerShell](#tab/azure-powershell)
* Import an image from Docker Hub into your ACR using the [`Import-AzContainerRegistryImage`] cmdlet.
```azurepowershell-interactive
Import-AzContainerRegistryImage -RegistryName <acr-name> -ResourceGroupName myResourceGroup -SourceRegistryUri docker.io -SourceImage library/nginx:latest
```
---
### Deploy the sample image from ACR to AKS
#### [Azure CLI](#tab/azure-cli)
1. Ensure you have the proper AKS credentials using the [`az aks get-credentials`][az-aks-get-credentials] command.
```azurecli-interactive
az aks get-credentials --resource-group myResourceGroup --name myAKSCluster
```
2. Create a file called **acr-nginx.yaml** using the following sample YAML and replace **acr-name** with the name of your ACR.
```yaml
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
```
3. Run the deployment in your AKS cluster using the `kubectl apply` command.
```console
kubectl apply -f acr-nginx.yaml
```
4. Monitor the deployment using the `kubectl get pods` command.
```console
kubectl get pods
```
The output should show two running pods, as shown in the following example output:
```output
NAME READY STATUS RESTARTS AGE
nginx0-deployment-669dfc4d4b-x74kr 1/1 Running 0 20s
nginx0-deployment-669dfc4d4b-xdpd6 1/1 Running 0 20s
```
#### [Azure PowerShell](#tab/azure-powershell)
1. Ensure you have the proper AKS credentials using the [`Import-AzAksCredential`][import-azakscredential] cmdlet.
```azurepowershell-interactive
Import-AzAksCredential -ResourceGroupName myResourceGroup -Name myAKSCluster
```
2. Create a file called **acr-nginx.yaml** using the following sample YAML and replace **acr-name** with the name of your ACR.
```yaml
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
```
3. Run the deployment in your AKS cluster using the `kubectl apply` command.
```console
kubectl apply -f acr-nginx.yaml
```
4. Monitor the deployment using the `kubectl get pods` command.
```console
kubectl get pods
```
The output should show two running pods, as shown in the following example output:
```output
NAME READY STATUS RESTARTS AGE
nginx0-deployment-669dfc4d4b-x74kr 1/1 Running 0 20s
nginx0-deployment-669dfc4d4b-xdpd6 1/1 Running 0 20s
```
### Configure ACR with private link through Azure HTTP Proxy and AKS
ACR has two endpoints:
- REST endpoint: `{REGISTRY_NAME}.azurecr.io`
- Data endpoint: `{REGISTRY_NAME}.{REGISTRY_LOCATION}.data.azurecr.io`
1. Ensure the rest and data endpoints are added to `noProxy` under the HTTP Proxy config.
```json
{
"httpProxy": "string",
"httpsProxy": "string",
"noProxy": [
"{REGISTRY_NAME}.azurecr.io",
"{REGISTRY_NAME}.{REGISTRY_LOCATION}.data.azurecr.io"
],
"trustedCa": "string"
}
```
2. Verify through logs that traffic is through private link.
> [!NOTE]
> Both endpoints are needed otherwise some traffic will be over HTTP proxy rather than private link.
---
### Troubleshooting
* Validate the registry is accessible from the AKS cluster using the [`az aks check-acr`](/cli/azure/aks#az-aks-check-acr) command.
* Learn more about [ACR monitoring](/azure/container-registry/monitor-service).
* Learn more about [ACR health](/azure/container-registry/container-registry-check-health).
<!-- LINKS - external -->
[byo-kubelet-identity]: use-managed-identity.md#create-a-kubelet-managed-identity
[image-pull-secret]: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
[summary-msi]: managed-identity-overview.md#summary-of-managed-identities-used-by-aks
[acr-pull]: /azure/role-based-access-control/built-in-roles#acrpull
[azure-cli-install]: /cli/azure/install-azure-cli
[azure-powershell-install]: /powershell/azure/install-az-ps
[acr-intro]: /azure/container-registry/container-registry-intro
[aad-identity]: /azure/active-directory/managed-identities-azure-resources/overview
[rbac-owner]: /azure/role-based-access-control/built-in-roles#owner
[rbac-classic]: /azure/role-based-access-control/rbac-and-directory-admin-roles#classic-subscription-administrator-roles
[kubelet]: https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/
[ps-detach]: /powershell/module/az.aks/set-azakscluster#-acrnametodetach
[cli-param]: /cli/azure/aks#az-aks-update-optional-parameters
[ps-attach]: /powershell/module/az.aks/set-azakscluster#-acrnametoattach
[terraform-reference]: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/container_registry
[az-acr-import]: /cli/azure/acr#az-acr-import
[az-aks-get-credentials]: /cli/azure/aks#az-aks-get-credentials
[import-azakscredential]: /powershell/module/az.aks/import-azakscredential
[set-azakscluster]: /powershell/module/az.aks/set-azakscluster
[az-aks-update]: /cli/azure/aks#az-aks-update
[new-azakscluster]: /powershell/module/az.aks/new-azakscluster
[az-aks-create]: /cli/azure/aks#az-aks-create
[az-acr-create]: /cli/azure/acr#az-acr-create
[new-azcontainerregistry]: /powershell/module/az.containerregistry/new-azcontainerregistry