Pull images from an Azure container registry to a Kubernetes cluster using a pull secret

You can use an Azure container registry as a source of container images with any Kubernetes cluster, including "local" Kubernetes clusters such as minikube and kind. This article shows how to create a Kubernetes pull secret using credentials for an Azure container registry. Then, use the secret to pull images from an Azure container registry in a pod deployment.

This example creates a pull secret using Microsoft Entra service principal credentials. You can also configure a pull secret using other Azure container registry credentials, such as a repository-scoped access token.

Note

While pull secrets are commonly used, they bring additional management overhead. If you're using Azure Kubernetes Service, we recommend other options such as using the cluster's managed identity or service principal to securely pull the image without an additional imagePullSecrets setting on each pod.

Prerequisites

This article assumes you already created a private Azure container registry. You also need to have a Kubernetes cluster running and accessible via the kubectl command-line tool.

Create a service principal

To create a service principal with access to your container registry, run the following script in the Azure Cloud Shell or a local installation of the Azure CLI. The script is formatted for the Bash shell.

Before running the script, update the ACR_NAME variable with the name of your container registry. The SERVICE_PRINCIPAL_NAME value must be unique within your Microsoft Entra tenant. If you receive an "'http://acr-service-principal' already exists." error, specify a different name for the service principal.

You can optionally modify the --role value in the az ad sp create-for-rbac command if you want to grant different permissions. For a complete list of roles, see ACR roles and permissions.

After you run the script, take note of the service principal's ID and password. Once you have its credentials, you can configure your applications and services to authenticate to your container registry as the service principal.

#!/bin/bash
# This script requires Azure CLI version 2.25.0 or later. Check version with `az --version`.

# Modify for your environment.
# ACR_NAME: The name of your Azure Container Registry
# SERVICE_PRINCIPAL_NAME: Must be unique within your AD tenant
ACR_NAME=$containerRegistry
SERVICE_PRINCIPAL_NAME=$servicePrincipal

# Obtain the full registry ID
ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query "id" --output tsv)
# echo $registryId

# Create the service principal with rights scoped to the registry.
# Default permissions are for docker pull access. Modify the '--role'
# argument value as desired:
# acrpull:     pull only
# acrpush:     push and pull
# owner:       push, pull, and assign roles
PASSWORD=$(az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME --scopes $ACR_REGISTRY_ID --role acrpull --query "password" --output tsv)
USER_NAME=$(az ad sp list --display-name $SERVICE_PRINCIPAL_NAME --query "[].appId" --output tsv)

# Output the service principal's credentials; use these in your services and
# applications to authenticate to the container registry.
echo "Service principal ID: $USER_NAME"
echo "Service principal password: $PASSWORD"

Use an existing service principal

To grant registry access to an existing service principal, you must assign a new role to the service principal. As with creating a new service principal, you can grant pull, push and pull, and owner access, among others.

The following script uses the az role assignment create command to grant pull permissions to a service principal you specify in the SERVICE_PRINCIPAL_ID variable. Adjust the --role value if you'd like to grant a different level of access.

#!/bin/bash
# Modify for your environment. The ACR_NAME is the name of your Azure Container
# Registry, and the SERVICE_PRINCIPAL_ID is the service principal's 'appId' or
# one of its 'servicePrincipalNames' values.
ACR_NAME=$containerRegistry
SERVICE_PRINCIPAL_ID=$servicePrincipal

# Populate value required for subsequent command args
ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query id --output tsv)

# Assign the desired role to the service principal. Modify the '--role' argument
# value as desired:
# acrpull:     pull only
# acrpush:     push and pull
# owner:       push, pull, and assign roles
az role assignment create --assignee $SERVICE_PRINCIPAL_ID --scope $ACR_REGISTRY_ID --role acrpull

If you don't save or remember the service principal password, you can reset it with the az ad sp credential reset command:

az ad sp credential reset  --name http://<service-principal-name> --query password --output tsv

This command returns a new, valid password for your service principal.

Create an image pull secret

Kubernetes uses an image pull secret to store information needed to authenticate to your registry. To create the pull secret for an Azure container registry, you provide the service principal ID, password, and the registry URL.

Create an image pull secret with the following kubectl command:

kubectl create secret docker-registry <secret-name> \
    --namespace <namespace> \
    --docker-server=<container-registry-name>.azurecr.io \
    --docker-username=<service-principal-ID> \
    --docker-password=<service-principal-password>

where:

Value Description
secret-name Name of the image pull secret, for example, acr-secret
namespace Kubernetes namespace to put the secret into
Only needed if you want to place the secret in a namespace other than the default namespace
container-registry-name Name of your Azure container registry, for example, myregistry

The --docker-server is the fully qualified name of the registry login server
service-principal-ID ID of the service principal that will be used by Kubernetes to access your registry
service-principal-password Service principal password

Use the image pull secret

Once you've created the image pull secret, you can use it to create Kubernetes pods and deployments. Provide the name of the secret under imagePullSecrets in the deployment file. For example:

apiVersion: v1
kind: Pod
metadata:
  name: my-awesome-app-pod
  namespace: awesomeapps
spec:
  containers:
    - name: main-app-container
      image: myregistry.azurecr.io/my-awesome-app:v1
      imagePullPolicy: IfNotPresent
  imagePullSecrets:
    - name: acr-secret

In the preceding example, my-awesome-app:v1 is the name of the image to pull from the Azure container registry, and acr-secret is the name of the pull secret you created to access the registry. When you deploy the pod, Kubernetes automatically pulls the image from your registry, if it is not already present on the cluster.

Next steps