共用方式為


使用服務主體進行 Azure Container Registry 驗證

您可以使用 Microsoft Entra 服務主體,以提供容器登錄的推送、提取或其他存取權。 藉由使用服務主體,您可以提供「無周邊」服務和應用程式的存取權。

何謂服務主體?

Microsoft Entra ID 服務主體提供訂用帳戶內 Azure 資源的存取權。 您可以將服務主體視為服務的使用者身分識別,其中「服務」是需要存取資源的任何應用程式、服務或平台。 您可以設定一個服務主體,並將其存取權限範圍限制為您指定的那些資源。 然後,請設定應用程式或服務,以使用服務主體的認證來存取那些資源。

在 Azure Container Registry 的內容中,您可以建立 Microsoft Entra 服務主體,並提供您在 Azure 中之私人登錄的提取、推送和提取,或其他權限。 如需完整清單,請參閱 Azure Container Registry 角色和權限

為何要使用服務主體?

您可以使用 Microsoft Entra 服務主體,以提供對私人容器登錄之有限範圍的存取權。 請針對每個應用程式或服務建立不同的服務主體,以便讓每個主體具備針對您登錄的適當存取權限。 此外,由於您可以避免在服務和應用程式之間共用認證,因此您可以替換認證,或只撤銷您所選擇之主體服務 (以及應用程式) 的存取權。

例如,設定您的 Web 應用程式使用僅為其提供映像 pull 存取權的服務主體,同時讓您的建置系統使用為其提供 pushpull 存取權的服務主體。 如果應用程式的開發轉手,您可以替換其服務主體認證,而不會影響該建置系統。

何時使用服務主體

您應該使用服務主體來提供無周邊案例中的登錄存取權。 也就是,必須以自動化或其他自動方式發送或提取容器映像的應用程式、服務或指令碼。 例如:

  • 提取:將容器從登錄部署到協調流程系統,包括 Kubernetes、DC/OS 及 Docker Swarm。 您也可以從容器登錄提取到相關的 Azure 服務,例如 App ServiceBatchService Fabric 等。

    提示

    在幾個 Kubernetes 案例中都建議使用服務主體,以從 Azure 容器登錄提取映像。 透過 Azure Kubernetes Service (AKS),您也可以藉由啟用叢集的受控識別,使用自動化機制向目標登錄進行驗證。

    • 推送:建置容器映像,並使用 Azure Pipelines 或 Jenkins 等持續整合和部署解決方案將其推送到登錄。

針對登錄的個別存取權 (例如,當您手動將容器映像提取至開發工作站時),建議改用您自己的 Microsoft Entra 身分識別進行登錄存取 (例如,使用 az acr login)。

建立服務主體

若要建立具容器登錄存取權的服務主體,請在 Azure Cloud Shell 或本機的 Azure CLI 安裝中執行下列指令碼。 此指令碼會針對 Bash 殼層加以格式化。

執行指令碼之前,請使用容器登錄的名稱更新 ACR_NAME 變數。 此 SERVICE_PRINCIPAL_NAME 值在 Microsoft Entra 租用戶中必須是唯一的。 如果您收到「'http://acr-service-principal' already exists.」錯誤,請為服務主體指定不同的名稱。

(選擇性) 如果您要授與不同權限,則可以修改 az ad sp create-for-rbac 命令中的 --role 值。 如需角色的完整清單,請參閱 ACR 角色和權限 \(英文\)。

執行指令碼之後,請記下的服務主體的識別碼密碼。 一旦擁有其認證,便可以將您的應用程式和服務設定為以服務主體向您的容器登錄進行驗證。

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

範例指令碼

您可以找到前述適用於 GitHub 上的 Azure CLI 的範例指令碼,以及適用於 Azure PowerShell 的版本:

使用服務主體進行驗證

當您擁有已授與容器登錄存取權的服務主體之後,可以設定其認證來存取「無前端」服務和應用程式,或使用 docker login 命令輸入認證。 使用下列值:

  • 使用者名稱:服務主體的應用程式 (用戶端) 識別碼
  • 密碼 - 服務主體的密碼 (用戶端密碼)

使用者名稱值的格式為 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

提示

您可以執行 az ad sp credential reset 命令來重新產生服務主體的密碼 (用戶端密碼)。

搭配 Azure 服務使用認證

您可以在透過 Azure 容器登錄進行驗證的任何 Azure 服務使用服務主體認證。 您可以在許多案例中,使用服務主體認證來取代登錄的系統管理員認證。

搭配 Docker 使用

您可以使用服務主體來執行 docker login。 在下列範例中,服務主體應用程式識別碼會傳入環境變數 $SP_APP_ID,以及變數 $SP_PASSWD 中的密碼。 如需管理 Docker 認證的建議作法,請參閱 docker login 命令參考。

# Log in to Docker with service principal credentials
docker login myregistry.azurecr.io --username $SP_APP_ID --password $SP_PASSWD

在登入後,Docker 會快取認證。

搭配憑證使用

如果您已將憑證新增至服務主體,您可以使用憑證式驗證登入 Azure CLI,然後使用 az acr login 命令來存取登錄。 當您使用 CLI 時,請使用憑證作為秘密而不是密碼,以獲得額外的安全性。

當您建立服務主體時,可以建立自我簽署憑證。 或者,將一或多個憑證新增至現有的服務主體。 例如,如果您使用本文中的其中一個指令碼來建立或更新具有從登錄提取或推送映像權限的服務主體,請使用 az ad sp credential reset 命令新增憑證。

若要使用服務主體搭配憑證來登入 Azure CLI,憑證的格式必須是 PEM 格式,並包含私密金鑰。 如果您的憑證不符合所需格式,請使用 openssl 之類的工具來轉換憑證。 當您執行 az login 以使用服務主體登入 CLI 時,也提供服務主體的應用程式識別碼和 Active Directory 租用戶識別碼。 下列範例會將這些值顯示為環境變數:

az login --service-principal --username $SP_APP_ID --tenant $SP_TENANT_ID  --password /path/to/cert/pem/file

然後,執行 az acr login 透過登錄進行驗證:

az acr login --name myregistry

當您執行 az login 透過登錄驗證工作階段時,CLI 會使用建立的權杖。

建立跨租用戶案例的服務主體

服務主體也可用於下列 Azure 案例:從某個 Microsoft Entra ID (租用戶) 中的容器登錄,將映像提取到另一個租用戶中的服務或應用程式。 例如,組織可能會在租用戶 A 中執行一個應用程式,該應用程式需要從租用戶 B 的共用容器登錄提取映像。

若要建立可在跨租用戶案例中透過容器登錄進行驗證的服務主體:

  • 在租用戶 A 中建立多租用戶應用程式 (服務主體)
  • 在租用戶 B 中佈建應用程式
  • 授與服務主體從租用戶 B 中登錄提取的權限
  • 更新租用戶 A 中的服務或應用程式,以使用新的服務主體進行驗證

如需範例步驟,請參閱將映像從容器登錄提取至不同 AD 租用戶中的 AKS 叢集

服務主體更新

服務主體建立後具有一年有效性。 您可以選擇將有效性延長超過一年,或使用 az ad sp credential reset 命令提供指定的到期日。

下一步