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

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

什麼是服務主體?

Microsoft Entra ID 服務主體可讓您 存取訂用帳戶內的 Azure 資源。 您可以將服務主體視為服務的使用者身分識別,其中「服務」是任何需要存取資源的應用程式、服務或平臺。 您可以設定服務主體,其訪問許可權僅限於您指定的資源。 然後,將您的應用程式或服務設定為使用服務主體的認證來存取這些資源。

在 Azure Container Registry 的內容中,您可以使用提取、推送和提取或其他許可權,在 Azure 中建立 Microsoft Entra 服務主體。 如需完整清單,請參閱 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.」錯誤,請為服務主體指定不同的名稱。

如果您想要授與不同的許可權,您可以選擇性地修改 --role az ad sp create-for-rbac 命令中的值。 如需角色的完整清單,請參閱 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 。 使用下列值:

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

Username 值的格式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

CLI 會使用您在執行 az login 時建立的令牌,向登錄驗證會話。

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

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

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

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

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

服務主體更新

服務主體的建立期限為一年。 您可以選擇將有效期限延長一年以上,或使用 命令提供您選擇的 az ad sp credential reset 到期日。

下一步