你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure 虚拟网络中的服务终结点限制对容器注册表的访问

Azure 虚拟网络为 Azure 资源和本地资源提供安全的专用网络。 使用服务终结点可以保护容器注册表的公共 IP 地址,仅在自己的虚拟网络中对其进行访问。 此终结点为流量提供通过 Azure 主干网络到达资源的最优路径。 虚拟网络和子网的标识也随每个请求进行传输。

本文介绍如何在虚拟网络中配置容器注册表服务终结点(预览版)。

每个注册表最多支持 100 条虚拟网络规则。

重要

Azure 容器注册表现支持 Azure 专用链接,允许将来自虚拟网络的专用终结点放置在注册表上。 可以使用专用 IP 地址从虚拟网络内部访问专用终结点。 在大多数网络方案中,我们建议使用专用终结点,而不是服务终结点。 容器注册表不支持同时启用从虚拟网络配置的专用链接和服务终结点功能。 因此,建议根据需要运行该列表并删除网络规则

“高级”容器注册表服务层级支持配置注册表服务终结点。 若要了解注册表服务层和限制,请参阅 Azure 容器注册表服务层

预览版限制

  • 目前尚未打算在未来开发 Azure 容器注册表的服务终结点。 我们推荐改用专用终结点
  • 不能使用 Azure 门户在注册表上配置服务终结点。
  • 只有 Azure Kubernetes 服务群集或 Azure 虚拟机可以用作主机,以使用服务终结点访问容器注册表。 其他 Azure 服务(包括 Azure 容器实例)不受支持。
  • Azure 美国政府云或由世纪互联运营的 Microsoft Azure 云不支持 Azure 容器注册表的服务终结点。

重要

某些功能可能不可用,或者需要在容器注册表中进行更多配置,以限制对专用终结点、选定子网或 IP 地址的访问。

  • 在禁止公用网络访问注册表时,某些受信任的服务(包括 Azure 安全中心)访问注册表就需要启用某个网络设置来绕过网络规则。
  • 禁用公用网络访问后,某些 Azure 服务(包括 Azure DevOps 服务)的实例当前无法访问容器注册表。
  • Azure DevOps 托管代理当前不支持专用终结点。 需要使用与专用终结点建立了网络直通的自托管代理。
  • 如果注册表具有已批准的专用终结点,并且公用网络访问已禁用,则无法使用 Azure 门户、Azure CLI 或其他工具在虚拟网络外部列出存储库和标记。

先决条件

  • 若要使用本文中所述的 Azure CLI 步骤,需要安装 Azure CLI 版本 2.0.58 或更高版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

  • 如果还没有容器注册表,请创建一个(需要高级层),并推送示例映像,如来自 Docker Hub 的 hello-world。 例如,使用 Azure 门户Azure CLI 创建注册表。

  • 若要使用其他 Azure 订阅中的服务终结点限制注册表访问,请在该订阅中注册 Azure 容器注册表的资源提供程序。 例如:

    az account set --subscription <Name or ID of subscription of virtual network>
    
    az provider register --namespace Microsoft.ContainerRegistry
    

创建启用了 Docker 的虚拟机

为了进行测试,请使用启用了 Docker 的 Ubuntu VM 来访问 Azure 容器注册表。 若要使用向注册表进行的 Microsoft Entra 身份验证,另请在该 VM 上安装 Azure CLI。 如果已有 Azure 虚拟机,请跳过此创建步骤。

对于虚拟机和容器注册表,可以使用同一资源组。 此设置可简化结束时的清理工作,但并不是必需的。 如果选择为虚拟机和虚拟网络创建一个单独的资源组,请运行 az group create。 以下示例假定你已为资源组名称和注册表位置设置了环境变量:

az group create --name $RESOURCE_GROUP --location $REGISTRY_LOCATION

现在,请使用 az vm create 来部署默认的 Ubuntu Azure 虚拟机。 以下示例创建名为“myDockerVM”的 VM。

VM_NAME=myDockerVM

az vm create \
  --resource-group $RESOURCE_GROUP \
  --name $VM_NAME \
  --image Ubuntu2204 \
  --admin-username azureuser \
  --generate-ssh-keys

创建 VM 需要几分钟时间。 等该命令完成后,记下 Azure CLI 显示的 publicIpAddress。 使用此地址与 VM 建立 SSH 连接。

在 VM 上安装 Docker

等 VM 正常运行后,与 VM 建立 SSH 连接。 将 publicIpAddress 替换为 VM 的公共 IP 地址。

ssh azureuser@publicIpAddress

请运行以下命令,以便在 Ubuntu VM 上安装 Docker:

sudo apt-get update
sudo apt install docker.io -y

安装完成后,运行以下命令验证 Docker 在 VM 上是否正常运行:

sudo docker run -it hello-world

输出:

Hello from Docker!
This message shows that your installation appears to be working correctly.
[...]

安装 Azure CLI

按照使用 apt 安装 Azure CLI 中的步骤在 Ubuntu 虚拟机上安装 Azure CLI。 例如:

curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

退出 SSH 连接。

为注册表配置网络访问

在本部分中,将容器注册表配置为允许从 Azure 虚拟网络中的子网进行访问。 使用 Azure CLI 提供步骤。

将服务终结点添加到子网

创建 VM 时,Azure 默认情况下会在同一个资源组中创建虚拟网络。 虚拟网络的名称基于虚拟机的名称。 例如,如果将虚拟机命名为 myDockerVM,则默认虚拟网络名称为 myDockerVMVNET,其中包含名为 myDockerVMSubnet 的子网。 使用 az network vnet list 命令对此进行验证:

az network vnet list \
  --resource-group myResourceGroup \
  --query "[].{Name: name, Subnet: subnets[0].name}"

输出:

[
  {
    "Name": "myDockerVMVNET",
    "Subnet": "myDockerVMSubnet"
  }
]

使用 az network vnet subnet update 命令将 Microsoft.ContainerRegistry 服务终结点添加到子网。 使用以下命令替换虚拟网络和子网的名称:

az network vnet subnet update \
  --name myDockerVMSubnet \
  --vnet-name myDockerVMVNET \
  --resource-group myResourceGroup \
  --service-endpoints Microsoft.ContainerRegistry

使用 az network vnet subnet show 命令检索子网的资源 ID。 在后面的步骤中,你将使用此 ID 配置网络访问规则。

az network vnet subnet show \
  --name myDockerVMSubnet \
  --vnet-name myDockerVMVNET \
  --resource-group myResourceGroup \
  --query "id"
  --output tsv

输出:

/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myDockerVMVNET/subnets/myDockerVMSubnet

更改默认网络对注册表的访问权限

默认情况下,Azure 容器注册表允许来自任何网络上的主机的连接。 要将访问权限仅授予所选网络,请将默认操作更改为拒绝访问。 在以下 az acr update 命令中,替换注册表的名称:

az acr update --name myContainerRegistry --default-action Deny

向注册表添加网络规则

使用 az acr network-rule add 命令向注册表添加允许从 VM 子网进行访问的网络规则。 使用以下命令替换容器注册表的名称和子网的资源 ID:

az acr network-rule add \
  --name mycontainerregistry \
  --subnet <subnet-resource-id>

验证对注册表的访问

等待几分钟以更新配置后,请验证 VM 是否可以访问容器注册表。 建立与 VM 的 SSH 连接,并运行 az acr login 命令以登录注册表。

az acr login --name mycontainerregistry

可以执行注册表操作(如运行 docker pull),以从注册表拉取示例映像。 替换适用于注册表的映像和标记值,并以注册表登录服务器名称(全部小写)作为前缀:

docker pull mycontainerregistry.azurecr.io/hello-world:v1

Docker 已成功将映像拉取到 VM。

此示例演示了如何通过网络访问规则访问专用容器注册表。 但是,无法从未配置网络访问规则的登录主机访问注册表。 如果尝试使用 az acr login 命令或 docker login 命令从另一个主机登录,则输出类似于以下内容:

Error response from daemon: login attempt to https://xxxxxxx.azurecr.io/v2/ failed with status: 403 Forbidden

还原默认注册表访问

若要将注册表还原为默认允许访问,请删除配置的所有网络规则。 然后,设置默认操作以允许访问。

删除网络规则

若要查看为注册表配置的网络规则列表,请运行以下 az acr network-rule list 命令:

az acr network-rule list --name mycontainerregistry 

对于配置的每个规则,运行 az acr network-rule remove 命令将其删除。 例如:

# Remove a rule that allows access for a subnet. Substitute the subnet resource ID.

az acr network-rule remove \
  --name mycontainerregistry \
  --subnet /subscriptions/ \
  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myDockerVMVNET/subnets/myDockerVMSubnet

允许访问

在以下 az acr update 命令中,替换注册表的名称:

az acr update --name myContainerRegistry --default-action Allow

清理资源

如果在同一资源组中创建了所有 Azure 资源,并且不再需要这些资源,则可以选择使用单个 az group delete 命令删除资源:

az group delete --name myResourceGroup

后续步骤