使用 Azure 容器注册表从 Azure 容器实例进行身份验证

可以使用 Microsoft Entra 服务主体来提供对 Azure 容器注册表中的专用容器注册表的访问权限。

本文介绍如何创建和配置具有注册表拉取权限的 Microsoft Entra 服务主体。 然后,启动 Azure 容器实例 (ACI) 中的某个容器,以从专用注册表拉取其映像,并使用服务主体进行身份验证。

何时使用服务主体

无外设方案中(如在自动或以其他无人参与方式创建容器实例的应用程序或服务中),应使用服务主体从 ACI 进行身份验证。

例如,如果你有一个在夜间自动运行的脚本,并创建了一个基于任务的容器实例来处理一些数据,则它可以使用具有“仅拉取”权限的服务主体对注册表进行身份验证。 然后可以轮换服务主体的凭据或完全撤消其访问权限,而不会影响其他服务和应用程序。

在禁用了注册表管理员用户时,也应使用服务主体。

创建服务主体

若要创建可以访问容器注册表的服务主体,请在本地安装的 Azure CLI 中运行以下脚本。 此脚本已针对 Bash Shell 格式化。

运行脚本之前,请将 ACR_NAME 变量更新为容器注册表的名称。 SERVICE_PRINCIPAL_NAME 值在 Microsoft Entra 租户中必须是唯一的。 如果收到“'http://acr-service-principal' already exists.”错误,请为服务主体指定另一名称。

如果需要授予其他权限,可以选择修改 az ad sp create-for-rbac 命令中的 --role 值。 有关角色的完整列表,请参阅 ACR 角色和权限

运行脚本后,请记下服务主体的 ID密码。 获得其凭据后,可以配置应用程序和服务使其作为服务主体对容器注册表进行身份验证。

#!/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"

使用现有的服务主体

若要向现有服务主体授予注册表访问权限,必须为服务主体分配新角色。 与创建新的服务主体一样,可以授予“拉取”、“推送和拉取”以及“所有者”访问权限等。

以下脚本使用 az role assignment create 命令向 SERVICE_PRINCIPAL_ID 变量中指定的服务主体授予“拉取”权限。 如果要授予不同的访问级别,请调整 --role 值。

#!/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

使用服务主体进行身份验证

若要使用服务主体启动 Azure 容器实例中的容器,请为 --registry-username 指定其 ID,并为 --registry-password 指定其密码。

az container create \
    --resource-group myResourceGroup \
    --name mycontainer \
    --image mycontainerregistry.azurecr.cn/myimage:v1 \
    --registry-login-server mycontainerregistry.azurecr.cn \
    --registry-username <service-principal-ID> \
    --registry-password <service-principal-password>

注意

建议在最新版本的 Azure CLI Shell 中运行命令。 设置 export MSYS_NO_PATHCONV=1 以便在 perm bash 环境中运行。

示例脚本

可以在 GitHub 上找到前面的 Azure CLI 示例脚本以及 Azure PowerShell 所对应的版本:

注意

必须修改从 GitHub 存储库下载或引用的示例脚本,以适应由世纪互联运营的 Azure 环境。 例如,替换某些终结点(将“blob.core.windows.net”替换为“blob.core.chinacloudapi.cn”,将“cloudapp.azure.com”替换为“cloudapp.chinacloudapi.cn”);必要时更改某些不受支持的区域、VM 映像、VM 大小、SKU 以及资源提供程序的 API 版本。

后续步骤

以下文章包含有关使用服务主体和 ACR 的其他详细信息: