快速入门:使用 Azure CLI 创建专用容器注册表

Azure 容器注册表是用于生成、存储和管理容器映像和相关项目的专用注册表服务。 在本快速入门中,你将使用 Azure CLI 创建一个 Azure 容器注册表实例。 然后,使用 Docker 命令将容器映像推送到注册表中,最终从注册表提取并运行该映像。

本快速入门需要运行 Azure CLI(建议运行 2.0.55 或更高版本)。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

还必须在本地安装 Docker。 Docker 提供的包可在任何 macOSWindowsLinux 系统上轻松配置 Docker。

由于 Azure Cloud Shell 并不包括所有必需的 Docker 组件(dockerd 守护程序),因此不能将 Cloud Shell 用于本快速入门。

创建资源组

使用“az group create”命令创建资源组。 Azure 资源组是在其中部署和管理 Azure 资源的逻辑容器。

以下示例在“eastus”位置创建名为“myResourceGroup”的资源组。

az group create --name myResourceGroup --___location eastus

为容器注册表配置参数

在本快速入门中,你将创建一个 标准 注册表,该注册表足以满足大多数 Azure 容器注册表工作流的需求。 有关可用服务层级的详细信息,请参阅容器注册表服务层级

使用 az acr create 命令创建 ACR 实例。 注册表名称在 Azure 中必须是唯一的,并且包含 5 到 50 个小写字母数字字符。 下面的示例采用的名称为 mycontainerregistry。 将其更新为唯一值。

配置域名标签 (DNL) 选项

域名标签(DNL)功能通过防止注册表 DNS 名称的子域接管攻击来增强安全性。 当一个注册库被删除而另一个实体重复使用相同的注册库名称时,就会发生这些攻击,这可能导致下游引用从该实体重新创建的注册库中拉取。

DNL 通过将唯一哈希追加到注册表的 DNS 名称来解决此问题。 这可确保即使其他实体重复使用相同的注册表名称,DNS 名称也会因唯一哈希而有所不同。 这样可防止下游引用无意中指向其他实体重新创建的注册表。

az acr create 命令创建注册表时,可以指定可选标志 --dnl-scope 并从可用选项中进行选择:

  • Unsecure:根据注册表名称(例如, contosoacrregistry.azurecr.io)as-is创建 DNS 名称。 此选项不包括 DNL 保护。
  • TenantReuse:基于租户和注册表名称追加唯一哈希,确保 DNS 名称在租户中是唯一的。
  • SubscriptionReuse:基于订阅、租户和注册表名称追加唯一哈希,确保 DNS 名称在订阅中是唯一的。
  • ResourceGroupReuse:基于资源组、订阅、租户和注册表名称追加唯一哈希,确保 DNS 名称在资源组中是唯一的。
  • NoReuse:每次创建注册表时,都会生成具有唯一哈希的唯一 DNS 名称,而不考虑其他因素,确保 DNS 名称始终是唯一的。

注释

不可变配置:在创建注册表期间选择的 DNL 范围是永久性的,以后无法修改。 这可确保一致的 DNS 行为,并防止下游引用中断。

DNL 选项的 DNS 名称影响

DNS 名称格式:除了Unsecure外,对于所有启用 DNL 的选项,DNS 名称遵循格式 registryname-hash.azurecr.io,其中短划线(-)用作哈希分隔符。 为了避免冲突,注册表名称中不允许使用短划线(-)。 例如,具有 contosoacrregistry DNL 作用域的TenantReuse注册表将具有类似于 contosoacrregistry-e7ggejfuhzhgedc8.azurecr.ioDNS 名称的注册表。

下游引用:DNS 名称可能与注册表名称不同,需要 Dockerfiles、Kubernetes YAML 和 Helm 图表等下游文件中的更新,以反映具有 DNL 哈希的完整 DNS 名称。 例如,如果您希望让您的下游 Dockerfile 引用一个名为 contosoacrregistry 且具有 TenantReuse DNL 作用域的注册表,则您需要在下游 Dockerfile 中更新对contosoacrregistry-e7ggejfuhzhgedc8.azurecr.io的引用。

配置角色分配权限模式

可以选择使用 --role-assignment-mode 参数来指定注册表的角色分配模式。 此选项确定如何为注册表管理 Microsoft Entra 基于角色的访问控制(RBAC)和角色分配,包括对 Microsoft Entra 存储库权限使用基于 Microsoft Entra 属性的访问控制 (ABAC)。

指定 rbac-abac 此参数以保留标准Microsoft Entra RBAC 角色分配,同时可以选择将 Microsoft Entra ABAC 条件应用于精细存储库级访问控制。

有关此选项的详细信息,请参阅 Microsoft Entra 基于属性的访问控制 (ABAC) 用于存储库权限

创建容器注册表

az acr create --resource-group myResourceGroup \
  --name mycontainerregistry --sku Standard \
  --role-assignment-mode 'rbac-abac' \
  --dnl-scope TenantReuse

创建注册表时,输出与下面类似:

{
  "adminUserEnabled": false,
  "creationDate": "2019-01-08T22:32:13.175925+00:00",
  "id": "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/myResourceGroup/providers/Microsoft.ContainerRegistry/registries/mycontainerregistry",
  "___location": "eastus",
  "loginServer": "mycontainerregistry-e7ggejfuhzhgedc8.azurecr.io",
  "name": "mycontainerregistry",
  "provisioningState": "Succeeded",
  "resourceGroup": "myResourceGroup",
  "sku": {
    "name": "Standard",
    "tier": "Standard"
  },
  "status": null,
  "storageAccount": null,
  "tags": {},
  "type": "Microsoft.ContainerRegistry/registries",
  "roleAssignmentMode": "AbacRepositoryPermissions",
  "autoGeneratedDomainNameLabelScope": "TenantReuse"
}

记下输出中的 loginServer,这是完全限定的注册表名称(全部小写)。 在本快速入门的剩余部分,<registry-name> 是容器注册表名称的占位符,<login-server> 是注册表的登录服务器名称的占位符。

提示

在本快速入门中,你将创建一个 标准 注册表,该注册表足以满足大多数 Azure 容器注册表工作流的需求。 选择其他层,以获得更高的存储和映像吞吐量,以及使用专用终结点的连接等功能。 有关可用服务层级 (SKU) 的详细信息,请参阅容器注册表服务层级

登录到注册表

在推送和拉取容器映像之前,必须登录到注册表。 为此,请使用 az acr login 命令。 使用 Azure CLI 登录时仅指定注册表资源名称。 请勿使用完全限定的登录服务器名称。

az acr login --name <registry-name>

例如:

az acr login --name mycontainerregistry

该命令在完成后会返回消息 Login Succeeded

将映像推送到注册表

要将映像推送到 Azure 容器注册表,首先必须具有一个映像。 如果还没有任何本地容器映像,请运行以下 docker pull 命令,拉取现有公共映像。 例如,从 Microsoft Container Registry 中拉取 hello-world 映像。

docker pull mcr.microsoft.com/hello-world

在将映像推送到注册表之前,必须使用具有注册表登录服务器的完全限定名称的 docker 标记对其进行标记。

  • 域名标签(DNL)受保护注册表的登录服务器名称格式为mycontainerregistry-abc123.azurecr.io,并包含唯一的 DNS 名称哈希。
  • 使用 Unsecure DNL 选项创建的注册表的登录服务器名称格式为 mycontainerregistry.azurecr.io

例如,如果注册表是使用 Tenant Reuse DNL 作用域创建的,则登录服务器可能类似于 mycontainerregistry-abc123.azurecr.io DNS 名称中的哈希。 如果注册表是使用 Unsecure DNL 选项创建的,则登录服务器将类似于 mycontainerregistry.azurecr.io 没有哈希。

有关注册表创建期间 DNL 选项和 DNS 名称影响的详细信息,请参阅 快速入门 - 在门户中创建注册表

示例:在推送之前标记图像

在使用你的注册表登录服务器时,使用 docker tag 命令标记图像。

为非 DNL 注册表标记映像:

docker tag mcr.microsoft.com/hello-world mycontainerregistry.azurecr.io/hello-world:v1

为启用 DNL 的注册表标记映像:

docker tag mcr.microsoft.com/hello-world mycontainerregistry-abc123.azurecr.io/hello-world:v1

最后,使用 docker push 将映像推送到注册表实例。 使用注册表实例的登录服务器名称替换 <login-server>。 此示例创建 hello-world 存储库,其中包含 hello-world:v1 映像。

docker push <login-server>/hello-world:v1

将映像推送到容器注册表后,请从本地 Docker 环境中删除 hello-world:v1 映像。 (请注意,此 docker rmi 命令不会从 Azure 容器注册表中的 hello-world 存储库中删除映像。

docker rmi <login-server>/hello-world:v1

列出容器映像

以下示例列出了注册表中的存储库:

az acr repository list --name <registry-name> --output table

输出:

Result
----------------
hello-world

以下示例列出了 hello-world 存储库中的标记。

az acr repository show-tags --name <registry-name> --repository hello-world --output table

输出:

Result
--------
v1

从注册表运行映像

现在,可以使用 hello-world:v1 从容器注册表拉取并运行 容器映像:

docker run <login-server>/hello-world:v1  

示例输出:

Unable to find image 'mycontainerregistry.azurecr.io/hello-world:v1' locally
v1: Pulling from hello-world
Digest: sha256:662dd8e65ef7ccf13f417962c2f77567d3b132f12c95909de6c85ac3c326a345
Status: Downloaded newer image for mycontainerregistry.azurecr.io/hello-world:v1

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

[...]

清理资源

如果不再需要存储在该处的资源组、容器注册表和容器映像,可以使用 az group delete 命令将其删除。

az group delete --name myResourceGroup

后续步骤

本快速入门介绍了如何使用 Azure CLI 创建 Azure 容器注册表,如何将容器映像推送到注册表,以及如何拉取并运行注册表中的映像。 请继续阅读 Azure 容器注册表教程,以更深入地了解 ACR。