使用服務主體進行 Azure Container Registry 驗證Azure Container Registry authentication with service principals

您可以使用 Azure Active Directory (Azure AD) 服務主體,來提供容器登錄的容器映像 docker pushpull 存取權。You can use an Azure Active Directory (Azure AD) service principal to provide container image docker push and pull access to your container registry. 藉由使用服務主體,您可以提供「無周邊」服務和應用程式的存取權。By using a service principal, you can provide access to "headless" services and applications.

何謂服務主體?What is a service principal?

Azure AD 服務主體提供您訂用帳戶內 Azure 資源的存取權。Azure AD service principals provide access to Azure resources within your subscription. 您可以將服務主體視為服務的使用者身分識別,其中「服務」是需要存取資源的任何應用程式、服務或平台。You can think of a service principal as a user identity for a service, where "service" is any application, service, or platform that needs access to the resources. 您可以設定一個服務主體,並將其存取權限範圍限制為您指定的那些資源。You can configure a service principal with access rights scoped only to those resources you specify. 然後,請設定應用程式或服務,以使用服務主體的認證來存取那些資源。Then, configure your application or service to use the service principal's credentials to access those resources.

在 Azure Container Registry 的內容中,您可以建立一個 Azure AD 服務主體,並提供您在 Azure 中之私人登錄的提取、發送和提取,或其他權限。In the context of Azure Container Registry, you can create an Azure AD service principal with pull, push and pull, or other permissions to your private registry in Azure. 如需完整清單,請參閱 Azure Container Registry 角色和權限For a complete list, see Azure Container Registry roles and permissions.

為何要使用服務主體?Why use a service principal?

藉由使用 Azure AD 服務主體,您可以提供對您私人容器登錄之有限範圍的存取權。By using an Azure AD service principal, you can provide scoped access to your private container registry. 您可以針對每個應用程式或服務建立不同的服務主體,每個對您的登錄均具備量身訂做的存取權限。You can create different service principals for each of your applications or services, each with tailored access rights to your registry. 此外,由於您可以避免在服務和應用程式之間共用認證,因此您可以替換認證,或只撤銷您所選擇之主體服務 (以及應用程式) 的存取權。And, because you can avoid sharing credentials between services and applications, you can rotate credentials or revoke access for only the service principal (and thus the application) you choose.

例如,儘管您的建置系統可以使用已為其提供 pushpull 存取權的服務主體,但您的 Web 應用程式可以使用僅為其提供映像 pull 存取權的服務主體。For example, your web application can use a service principal that provides it with image pull access only, while your build system can use a service principal that provides it with both push and pull access. 如果應用程式的開發轉手,您可以替換其服務主體認證,而不會影響該建置系統。If development of your application changes hands, you can rotate its service principle credentials without affecting the build system.

何時使用服務主體When to use a service principal

您應該使用服務主體來提供無周邊案例中的登錄存取權。You should use a service principal to provide registry access in headless scenarios. 也就是,任何必須以自動化或其他自動方式發送或提取容器映像的應用程式、服務或指令碼。That is, any application, service, or script that must push or pull container images in an automated or otherwise unattended manner.

針對登錄的個別存取權 (例如,當您手動將容器映像提取至您的開發工作站時),您應該改用您自己的 Azure AD 身分識別進行登錄存取 (例如,使用 az acr login)。For individual access to a registry, such as when you manually pull a container image to your development workstation, you should instead use your own Azure AD identity for registry access (for example, with az acr login).

建立服務主體Create a service principal

若要建立具容器登錄存取權的服務主體,請在 Azure Cloud Shell 或本機的 Azure CLI 安裝中執行下列指令碼。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. 此指令碼會針對 Bash 殼層加以格式化。The script is formatted for the Bash shell.

執行指令碼之前,請使用容器登錄的名稱更新 ACR_NAME 變數。Before running the script, update the ACR_NAME variable with the name of your container registry. SERVICE_PRINCIPAL_NAME 值在 Azure Active Directory 租用戶內必須是唯一的。The SERVICE_PRINCIPAL_NAME value must be unique within your Azure Active Directory tenant. 如果您收到「'http://acr-service-principal' already exists.」錯誤,請為服務主體指定不同的名稱。If you receive an "'http://acr-service-principal' already exists." error, specify a different name for the service principal.

(選擇性) 如果您要授與不同權限,則可以修改 az ad sp create-for-rbac 命令中的 --role 值。You can optionally modify the --role value in the az ad sp create-for-rbac command if you want to grant different permissions. 如需角色的完整清單,請參閱 ACR 角色和權限 (英文)。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

# 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=<container-registry-name>
SERVICE_PRINCIPAL_NAME=acr-service-principal

# Obtain the full registry ID for subsequent command args
ACR_REGISTRY_ID=$(az acr show --name $ACR_NAME --query id --output tsv)

# 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
SP_PASSWD=$(az ad sp create-for-rbac --name http://$SERVICE_PRINCIPAL_NAME --scopes $ACR_REGISTRY_ID --role acrpull --query password --output tsv)
SP_APP_ID=$(az ad sp show --id http://$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: $SP_APP_ID"
echo "Service principal password: $SP_PASSWD"

使用現有的服務主體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.

以下指令碼使用 az role assignment create 命令,以授與您在 SERVICE_PRINCIPAL_ID 變數中所指定的服務主體「提取」 權限。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. 如果您要授與不同層級的存取權,請調整 --role 值。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=mycontainerregistry
SERVICE_PRINCIPAL_ID=<service-principal-ID>

# 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

範例指令碼Sample scripts

您可以找到前述適用於 GitHub 上的 Azure CLI 的範例指令碼,以及適用於 Azure PowerShell 的版本:You can find the preceding sample scripts for Azure CLI on GitHub, as well versions for Azure PowerShell:

後續步驟Next steps

一旦為服務主體授與容器登錄的存取權之後,您就可以在應用程式和服務中使用它的認證進行無周邊登錄互動。Once you have a service principal that you've granted access to your container registry, you can use its credentials in your applications and services for headless registry interaction. 您可以使用服務主體認證,從使用 Azure 容器登錄進行驗證的任何 Azure 服務。You can use service principal credentials from any Azure service that can authenticate with an Azure container registry. 範例包括:Examples include: