Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Limit access to a registry by assigning virtual network private IP addresses to the registry endpoints and using Azure Private Link. Network traffic between the clients on the virtual network and the registry's private endpoints traverses the virtual network and a private link on the Microsoft backbone network, eliminating exposure from the public internet. Private Link also enables private registry access from on-premises through Azure ExpressRoute, private peering, or a VPN gateway.
You can configure DNS settings for the registry's private endpoints so that the settings resolve to the registry's allocated private IP address. With DNS configuration, clients and services in the network can continue to access the registry at the registry's fully qualified domain name, such as myregistry.azurecr.io.
This article shows how to configure a private endpoint for your registry by using the Azure portal (recommended) or the Azure CLI. This feature is available in the Premium container registry service tier (SKU), with a maximum of 200 private endpoints.
Important
If your container registry restricts access to private endpoints, selected subnets, or IP addresses, some functionality might be unavailable or require more configuration.
- When you disable public network access to a registry, certain trusted services, including Microsoft Defender for Cloud, can access the registry only if you enable a network setting to bypass the network rules.
- Once you disable the public network access, instances of certain Azure services, including Azure DevOps Services, can't access the container registry.
- Private endpoints aren't currently supported with agents managed by Azure DevOps. You need to use a self-hosted agent with network line of sight to the private endpoint.
- If the registry has an approved private endpoint and you disable public network access, you can't list repositories and tags outside the virtual network by using the Azure portal, Azure CLI, or other tools.
Prerequisites
- A virtual network and subnet in which to set up the private endpoint. If needed, create a new virtual network and subnet.
- For testing, set up a VM in the virtual network. For steps to create a test virtual machine to access your registry, see Create a Docker-enabled virtual machine.
- To use the Azure CLI steps in this article, Azure CLI version 2.6.0 or later is recommended. To install or upgrade, see Install Azure CLI.
- If you don't already have a Premium container registry, create one and import a sample public image such as
mcr.microsoft.com/hello-worldfrom Microsoft Container Registry. For example, use the Azure portal or the Azure CLI to create a registry.
Register container registry resource provider
To configure registry access by using a private link in a different Azure subscription or tenant, you need to register the resource provider for Azure Container Registry in that subscription. Use the Azure portal, Azure CLI, or other tools.
Example:
az account set --subscription <Name or ID of subscription of private link>
az provider register --namespace Microsoft.ContainerRegistry
Set up a private endpoint in the Azure portal
Set up a private endpoint when you create a registry, or add a private endpoint to an existing registry.
Create a private endpoint in a new registry
When you create a registry in the portal, on the Basics tab, select Premium for Pricing plan.
In the Networking tab, for Connectivity configuration, select Private access (recommended).
Select Create a private endpoint connection.
Enter or select the following information:
Setting Value Subscription Select your subscription. Resource group Enter the name of an existing group or create a new one. Name Enter a unique name. Registry subresource Ensure registry is selected. Virtual network Select the virtual network for the private endpoint. Example: myDockerVMVNET. Subnet Select the subnet for the private endpoint. Example: myDockerVMSubnet. Integrate with private DNS zone Select Yes. Private DNS Zone Select (New) privatelink.azurecr.io
Select OK.
Configure the remaining registry settings, and then select Review + create. Your registry is created with the private endpoint.
Create a private endpoint for an existing registry
- Go to your container registry in the Azure portal.
- In the service menu, under Settings, select Networking.
- On the Private access tab, select Create a private endpoint connection.
- In the Basics tab, select a subscription, resource group, and region, and enter a name for the private endpoint. The network interface name is created using your endpoint name.
- Select Next: Resource. The private endpoint is for the registry resource, so the resource type and subresource are preselected. Then select Next: Virtual Network.
- Select the virtual network and subnet for the private endpoint. Don't change the other options, and then select Next: DNS.
- Ensure that Integrate with private DNS zone is set to Yes, and that the private DNS zone is set to (New) privatelink.azurecr.io. Select Next: Tags and add any desired tags, then select Next: Review + create.
- When you see the Validation passed message, select Create.
Confirm endpoint configuration
After you create the private endpoint, the Private endpoints settings in the portal show the DNS settings. To confirm:
- In your container registry's service menu, under Settings, select Networking.
- On the Private access tab, select the name of the private endpoint you created.
- In the service menu, under Settings, select DNS configuration.
- Review the details for your private link's DNS configuration.
Set up private endpoint by using the Azure CLI
The Azure CLI examples in this article are formatted for the Bash shell and use the following environment variables. Replace the example values with the names of an existing container registry, virtual network, and subnet to set up a private endpoint.
REGISTRY_NAME=<container-registry-name>
REGISTRY_LOCATION=<container-registry-location> # Azure region such as westeurope where registry created
RESOURCE_GROUP=<resource-group-name> # Resource group for your existing virtual network and subnet
NETWORK_NAME=<virtual-network-name>
SUBNET_NAME=<subnet-name>
Disable network policies in subnet
Disable network policies such as network security groups in the subnet for the private endpoint. Update your subnet configuration by using az network vnet subnet update:
az network vnet subnet update \
--name $SUBNET_NAME \
--vnet-name $NETWORK_NAME \
--resource-group $RESOURCE_GROUP \
--disable-private-endpoint-network-policies
Configure the private DNS zone
Create a private Azure DNS zone for the private Azure container registry domain. In later steps, you create DNS records for your registry domain in this DNS zone. For more information, see DNS configuration options, later in this article.
To use a private zone to override the default DNS resolution for your Azure container registry, name the zone privatelink.azurecr.io. Run the following az network private-dns zone create command to create the private zone:
az network private-dns zone create \
--resource-group $RESOURCE_GROUP \
--name "privatelink.azurecr.io"
Create an association link
Run az network private-dns link vnet create to associate your private zone with the virtual network. This example creates a link named myDNSLink.
az network private-dns link vnet create \
--resource-group $RESOURCE_GROUP \
--zone-name "privatelink.azurecr.io" \
--name MyDNSLink \
--virtual-network $NETWORK_NAME \
--registration-enabled false
Create a private registry endpoint
In this section, create the registry's private endpoint in the virtual network. First, get the resource ID of your registry:
REGISTRY_ID=$(az acr show --name $REGISTRY_NAME \
--query 'id' --output tsv)
Run the az network private-endpoint create command to create the registry's private endpoint.
The following example creates the endpoint myPrivateEndpoint and service connection myConnection. To specify a container registry resource for the endpoint, pass --group-ids registry:
az network private-endpoint create \
--name myPrivateEndpoint \
--resource-group $RESOURCE_GROUP \
--vnet-name $NETWORK_NAME \
--subnet $SUBNET_NAME \
--private-connection-resource-id $REGISTRY_ID \
--group-ids registry \
--connection-name myConnection
Get endpoint IP configuration
To configure DNS records, get the IP configuration of the private endpoint. In this example, the private endpoint's network interface connects to two private IP addresses for the container registry: one for the registry itself, and one for the registry's data endpoint. If your registry is geo-replicated, each replica has an additional IP address.
First, run az network private-endpoint show to query the private endpoint for the network interface ID:
NETWORK_INTERFACE_ID=$(az network private-endpoint show \
--name myPrivateEndpoint \
--resource-group $RESOURCE_GROUP \
--query 'networkInterfaces[0].id' \
--output tsv)
The following az network nic show commands get the private IP addresses and FQDNs for the container registry and the registry's data endpoint:
REGISTRY_PRIVATE_IP=$(az network nic show \
--ids $NETWORK_INTERFACE_ID \
--query "ipConfigurations[?privateLinkConnectionProperties.requiredMemberName=='registry'].privateIPAddress" \
--output tsv)
DATA_ENDPOINT_PRIVATE_IP=$(az network nic show \
--ids $NETWORK_INTERFACE_ID \
--query "ipConfigurations[?privateLinkConnectionProperties.requiredMemberName=='registry_data_$REGISTRY_LOCATION'].privateIPAddress" \
--output tsv)
# An FQDN is associated with each IP address in the IP configurations
REGISTRY_FQDN=$(az network nic show \
--ids $NETWORK_INTERFACE_ID \
--query "ipConfigurations[?privateLinkConnectionProperties.requiredMemberName=='registry'].privateLinkConnectionProperties.fqdns" \
--output tsv)
DATA_ENDPOINT_FQDN=$(az network nic show \
--ids $NETWORK_INTERFACE_ID \
--query "ipConfigurations[?privateLinkConnectionProperties.requiredMemberName=='registry_data_$REGISTRY_LOCATION'].privateLinkConnectionProperties.fqdns" \
--output tsv)
Additional endpoints for geo-replicas
If your registry is geo-replicated, query for the additional data endpoint for each registry replica. For example, in the eastus region:
REPLICA_LOCATION=eastus
GEO_REPLICA_DATA_ENDPOINT_PRIVATE_IP=$(az network nic show \
--ids $NETWORK_INTERFACE_ID \
--query "ipConfigurations[?privateLinkConnectionProperties.requiredMemberName=='registry_data_$REPLICA_LOCATION'].privateIPAddress" \
--output tsv)
GEO_REPLICA_DATA_ENDPOINT_FQDN=$(az network nic show \
--ids $NETWORK_INTERFACE_ID \
--query "ipConfigurations[?privateLinkConnectionProperties.requiredMemberName=='registry_data_$REPLICA_LOCATION'].privateLinkConnectionProperties.fqdns" \
--output tsv)
When you add a new geo-replication, a private endpoint connection is pending. To approve a private endpoint connection that you configured manually, run az acr private-endpoint-connection approve.
Create DNS records in the private zone
The following commands create DNS records in the private zone for the registry endpoint and its data endpoint. For example, if you have a registry named myregistry in the westeurope region, the endpoint names are myregistry.azurecr.io and myregistry.westeurope.data.azurecr.io.
First, run az network private-dns record-set a create to create empty A-record sets for the registry endpoint and data endpoint:
az network private-dns record-set a create \
--name $REGISTRY_NAME \
--zone-name privatelink.azurecr.io \
--resource-group $RESOURCE_GROUP
# Specify registry region in data endpoint name
az network private-dns record-set a create \
--name ${REGISTRY_NAME}.${REGISTRY_LOCATION}.data \
--zone-name privatelink.azurecr.io \
--resource-group $RESOURCE_GROUP
Run the az network private-dns record-set a add-record command to create the A-records for the registry endpoint and data endpoint:
az network private-dns record-set a add-record \
--record-set-name $REGISTRY_NAME \
--zone-name privatelink.azurecr.io \
--resource-group $RESOURCE_GROUP \
--ipv4-address $REGISTRY_PRIVATE_IP
# Specify registry region in data endpoint name
az network private-dns record-set a add-record \
--record-set-name ${REGISTRY_NAME}.${REGISTRY_LOCATION}.data \
--zone-name privatelink.azurecr.io \
--resource-group $RESOURCE_GROUP \
--ipv4-address $DATA_ENDPOINT_PRIVATE_IP
Additional records for geo-replicas
If your registry is geo-replicated, create additional DNS settings for each replica. Continuing the example in the eastus region:
az network private-dns record-set a create \
--name ${REGISTRY_NAME}.${REPLICA_LOCATION}.data \
--zone-name privatelink.azurecr.io \
--resource-group $RESOURCE_GROUP
az network private-dns record-set a add-record \
--record-set-name ${REGISTRY_NAME}.${REPLICA_LOCATION}.data \
--zone-name privatelink.azurecr.io \
--resource-group $RESOURCE_GROUP \
--ipv4-address $GEO_REPLICA_DATA_ENDPOINT_PRIVATE_IP
The private link is now configured and ready for use.
Disable public access to a registry
For many scenarios, disable registry access from public networks. This configuration prevents all clients outside the virtual network from reaching the registry endpoints.
To disable public access to a container registry in the Azure portal, follow these steps:
- In your container registry's service menu, under Settings, select Networking.
- On the Public access tab, in Public network access, select Disabled. Then select Save.
You can also use the Azure CLI to disable public access by running az acr update and set --public-network-enabled to false.
Note
If you disable public access to a registry, az acr build commands no longer work.
az acr update --name $REGISTRY_NAME --public-network-enabled false
Use az acr build with private endpoint and private registry
Note
If you disable public network access, az acr build commands will fail.
Unless you use dedicated agent pools, public IPs are typically required. Tasks reserve a set of public IPs in each region for outbound requests. If needed, you can add these IPs to your firewall's allowed list for seamless communication. az acr build command uses the same set of IPs as tasks.
Consider the following options to execute the az acr build successfully.
- Assign a dedicated agent pool.
- If agent pool isn't available in your region, add the regional Azure Container Registry Service Tag IPv4 to the firewall access rules. Tasks reserve a set of public IPs in each region (
AzureContainerRegistryservice tag) for outbound requests. You can add these IPs to the firewall allowed list.
Disable access to a container registry by using a service endpoint
Important
You can't use both private link and service endpoint features configured from a virtual network in your container registry.
After you disable public access and configure private link for your registry, disable service endpoint access from a virtual network by removing virtual network rules.
- Run
az acr network-rule listcommand to list the existing network rules. - Run
az acr network-rule removecommand to remove the network rule.
Validate private link connection
Validate that the resources within the subnet of the private endpoint connect to your registry over a private IP address and have the correct private DNS zone integration.
To validate the private link connection, connect to the virtual machine you set up in the virtual network. Then, run a utility such as nslookup or dig to look up the IP address of your registry over the private link. For example:
dig $REGISTRY_NAME.azurecr.io
Example output shows the registry's IP address in the address space of the subnet:
[...]
; <<>> DiG 9.11.3-1ubuntu1.13-Ubuntu <<>> myregistry.azurecr.io
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52155
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;myregistry.azurecr.io. IN A
;; ANSWER SECTION:
myregistry.azurecr.io. 1783 IN CNAME myregistry.privatelink.azurecr.io.
myregistry.privatelink.azurecr.io. 10 IN A 10.0.0.7
[...]
Compare this result with the public IP address in dig output for the same registry over a public endpoint:
[...]
;; ANSWER SECTION:
myregistry.azurecr.io. 2881 IN CNAME myregistry.privatelink.azurecr.io.
myregistry.privatelink.azurecr.io. 2881 IN CNAME xxxx.xx.azcr.io.
xxxx.xx.azcr.io. 300 IN CNAME xxxx-xxx-reg.trafficmanager.net.
xxxx-xxx-reg.trafficmanager.net. 300 IN CNAME xxxx.westeurope.cloudapp.azure.com.
xxxx.westeurope.cloudapp.azure.com. 10 IN A 20.45.122.144
[...]
Confirm registry operations over private link
Also verify that you can perform registry operations from the virtual machine in the network. Make an SSH connection to your virtual machine, and run az acr login to authenticate to your registry. Depending on your VM configuration, you might need to prefix the following commands with sudo.
az acr login --name $REGISTRY_NAME
Perform registry operations such as docker pull to pull a sample image from the registry. Replace hello-world:v1 with an image and tag appropriate for your registry, prefixed with the registry login server name (all lowercase):
docker pull myregistry.azurecr.io/hello-world:v1
Confirm that Docker successfully pulls the image to the VM.
Manage private endpoint connections
Manage a registry's private endpoint connections by using the Azure portal or commands in the az acr private-endpoint-connection command group. You can approve, delete, list, reject, or show details of a registry's private endpoint connections.
To list the private endpoint connections of a registry, run the az acr private-endpoint-connection list command:
az acr private-endpoint-connection list \
--registry-name $REGISTRY_NAME
When you set up a private endpoint connection by using the steps in this article, the registry automatically accepts connections from clients and services that have Azure RBAC permissions on the registry. You can set up the endpoint to require manual approval of connections. For information about how to approve and reject private endpoint connections, see Manage a Private Endpoint Connection.
Important
Currently, if you delete a private endpoint from a registry, you might also need to delete the virtual network's link to the private zone. If you don't delete the link, you might see an unresolvable host error.
DNS configuration options
The private endpoint in this example integrates with a private DNS zone associated with a basic virtual network. This setup uses the Azure-provided DNS service directly to resolve the registry's public FQDN to its private IP addresses in the virtual network.
Private link supports additional DNS configuration scenarios that use the private zone, including custom DNS solutions. For example, you might have a custom DNS solution deployed in the virtual network, or on-premises in a network you connect to the virtual network using a VPN gateway or Azure ExpressRoute.
To resolve the registry's public FQDN to the private IP address in these scenarios, you need to configure a server-level forwarder to the Azure DNS service (168.63.129.16). Exact configuration options and steps depend on your existing networks and DNS. For examples, see Azure Private Endpoint private DNS zone values.
Important
If you create private endpoints in several regions to enable high availability, use a separate resource group in each region and place the virtual network and the associated private DNS zone in it. This configuration also prevents unpredictable DNS resolution caused by sharing the same private DNS zone.
Manually configure DNS records
For some scenarios, you might need to manually configure DNS records in a private zone instead of using the Azure-provided private zone. Be sure to create records for the registry endpoint, the registry's data endpoint, and the data endpoint for any additional regional replica. If you don't configure all records, the registry might be unreachable.
Important
If you later add a new replica, you need to manually add a new DNS record for the data endpoint in that region. For example, if you create a replica of myregistry in the northeurope location, add a record for myregistry.northeurope.data.azurecr.io.
The FQDNs and private IP addresses that you need to create DNS records are associated with the private endpoint's network interface. You can get this information by using the Azure portal or Azure CLI.
- In the portal, go to your private endpoint, and select DNS configuration.
- By using the Azure CLI, run az network nic show. For example commands, see Get endpoint IP configuration.
After creating DNS records, make sure that the registry FQDNs resolve properly to their respective private IP addresses.
Pull from a registry with private link enabled
To pull content from a registry with private link enabled, clients must allow access to the registry REST endpoint and all regional data endpoints. The client proxy or firewall must allow access to:
- REST endpoint:
{REGISTRY_NAME}.azurecr.io - Data endpoints:
{REGISTRY_NAME}.{REGISTRY_LOCATION}.data.azurecr.io
For a geo-replicated registry, you must configure access to the data endpoint for each regional replica.
Update the routing configuration for the client proxy and client firewall with the data endpoints to handle the pull requests successfully. A client proxy provides central traffic control to outbound requests. To handle local traffic, a client proxy isn't required. You can add endpoints into the noProxy section to bypass the proxy. For more information, see HTTP proxy support in AKS.
Requests to the token server over a private endpoint connection don't require data endpoint configuration.
Clean up resources
If you created all the Azure resources in the same resource group and you no longer need them, you can delete the resource group in the Azure portal or by using a single az group delete command:
az group delete --name $RESOURCE_GROUP
Related content
- To learn more about Private Link, see the Azure Private Link documentation.
- To verify DNS settings in the virtual network that route to a private endpoint, run the az acr check-health command with the
--vnetparameter. For more information, see Check the health of an Azure container registry. - If you need to set up registry access rules from behind a client firewall, see Configure rules to access an Azure container registry behind a firewall.
- Troubleshoot Azure Private Endpoint connectivity problems.
- If you need to deploy Azure Container Instances that can pull images from an ACR through a private endpoint, see Deploy to Azure Container Instances from Azure Container Registry using a managed identity.