分享方式:


在 ACR 工作中使用 Azure 受控識別進行外部驗證

ACR 工作中,您可以啟用 Azure 資源的受控識別。 工作可以使用身分識別存取其他 Azure 資源,不需要提供或管理認證。

在本文中,您將了解如何在存取 Azure Key Vault 所儲存秘密的工作中啟用受控識別。

若要建立 Azure,本文需要您執行 Azure CLI 2.0.68 版或更新版本。 執行 az --version 以尋找版本。 如果您需要安裝或升級,請參閱安裝 Azure CLI

案例概觀

此範例工作會讀取儲存在 Azure Key Vault 中的 Docker Hub 認證。 此認證的適用於具有私人 Docker Hub 存放庫寫入 (推送) 權限的 Docker Hub 帳戶。 若要讀取認證,您可以使用受控識別來設定工作,並為其指派適當的權限。 與身分識別相關聯的工作會建置映像,並登入 Docker Hub 將映像推送至私人存放庫。

這個範例會示範使用使用者指派或系統指派受控識別的步驟。 您所選擇的身分識別取決於貴組織的需求。

在現實世界案例中,公司可能會在建置程序期將,將映像發佈至 Docker Hub 中的私人存放庫。

必要條件

您需要執行此工作的 Azure 容器登錄。 在本文中,此登錄名為 myregistry。 請在稍後的步驟中,以您自己的登錄名稱取代。

如果您還沒有 Azure 容器登錄,請參閱快速入門:使用 Azure CLI 建立私人容器登錄。 您還不需要將映像推送至登錄。

您還需要 Docker Hub 中的私人存放庫,以及具有該存放庫寫入權的 Docker Hub 帳戶。 在此範例中,此存放庫名為 hubuser/hubrepo

建立金鑰保存庫並儲存秘密

首先,如果有必要,請使用下列 az group create 命令,在 eastus 位置中建立一個名為 myResourceGroup 的資源群組:

az group create --name myResourceGroup --location eastus

使用 az keyvault create 命令來建立金鑰保存庫。 請務必指定一個唯一的金鑰保存庫名稱。

az keyvault create --name mykeyvault --resource-group myResourceGroup --location eastus

使用 az keyvault secret set命令,將必要的 Docker Hub 認證儲存在金鑰保存庫中。 在這些命令中,這些值會傳入環境變數:

# Store Docker Hub user name
az keyvault secret set \
  --name UserName \
  --value $USERNAME \
  --vault-name mykeyvault

# Store Docker Hub password
az keyvault secret set \
  --name Password \
  --value $PASSWORD \
  --vault-name mykeyvault

在現實世界案例中,秘密可能會在不同的程序中設定和維護。

定義 YAML 檔案中的工作步驟

這個範例工作的步驟定義於 YAML 檔案。 在本機工作目錄中建立名為 dockerhubtask.yaml 的檔案,並貼上下列內容。 請務必以您的金鑰保存庫名稱取代檔案中的金鑰保存庫名稱。

version: v1.1.0
# Replace mykeyvault with the name of your key vault
secrets:
  - id: username
    keyvault: https://mykeyvault.vault.azure.net/secrets/UserName
  - id: password
    keyvault: https://mykeyvault.vault.azure.net/secrets/Password
steps:
# Log in to Docker Hub
  - cmd: bash echo '{{.Secrets.password}}' | docker login --username '{{.Secrets.username}}' --password-stdin 
# Build image
  - build: -t {{.Values.PrivateRepo}}:$ID https://github.com/Azure-Samples/acr-tasks.git -f hello-world.dockerfile
# Push image to private repo in Docker Hub
  - push:
    - {{.Values.PrivateRepo}}:$ID

工作步驟會執行下列動作:

  • 管理使用 Docker Hub 進行驗證的祕密認證。
  • 將秘密傳遞至 docker login 命令,以使用 Docker Hub 進行驗證。
  • 使用 Azure-Samples/acr-tasks 存放庫中的範例 Dockerfile 建置映像。
  • 將映像推送至私人 Docker Hub 存放庫。

選項 1:使用使用者指派的身分識別來建立工作。

本節中的步驟可建立工作,並啟用使用者指派的身分識別。 如果您想要改為啟用系統指派的身分識別,請參閱選項 2:使用系統指派的身分識別來建立工作

建立使用者指派的身分識別

使用 az identity create 命令,在您的訂用帳戶中建立名為 myACRTasksId 的身分識別。 您可以使用先前用來建立容器登錄的相同資源群組,或使用不同的資源群組。

az identity create \
  --resource-group myResourceGroup \
  --name myACRTasksId

若要在下列步驟中設定使用者指派的身分識別,請使用 az identity show 命令,以將身分識別的資源識別碼、主體識別碼與用戶端識別碼儲存在變數中。

# Get resource ID of the user-assigned identity
resourceID=$(az identity show \
  --resource-group myResourceGroup \
  --name myACRTasksId \
  --query id --output tsv)

# Get principal ID of the task's user-assigned identity
principalID=$(az identity show \
  --resource-group myResourceGroup \
  --name myACRTasksId \
  --query principalId --output tsv)

# Get client ID of the user-assigned identity
clientID=$(az identity show \
  --resource-group myResourceGroup \
  --name myACRTasksId \
  --query clientId --output tsv)

建立工作

執行下列 az acr task create 命令以建立工作 dockerhubtask。 此工作會在沒有原始程式碼內容的情況下執行,而命令會參考工作目錄中的 dockerhubtask.yaml 檔案。 --assign-identity 參數會傳遞使用者指派身分識別的資源識別碼。

az acr task create \
  --name dockerhubtask \
  --registry myregistry \
  --context /dev/null \
  --file dockerhubtask.yaml \
  --assign-identity $resourceID

在命令輸出中,identity 區段會顯示 UserAssigned 類型的身分識別已在工作中設定:

[...]
"identity": {
    "principalId": null,
    "tenantId": null,
    "type": "UserAssigned",
    "userAssignedIdentities": {
      "/subscriptions/xxxxxxxx-d12e-4760-9ab6-xxxxxxxxxxxx/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myACRTasksId": {
        "clientId": "xxxxxxxx-f17e-4768-bb4e-xxxxxxxxxxxx",
        "principalId": "xxxxxxxx-1335-433d-bb6c-xxxxxxxxxxxx"
      }
[...]

將金鑰保存庫的存取權授與身分識別

請執行下列 az keyvault set-policy 命令,以針對金鑰保存庫設定存取原則。 下列範例允許身分識別從金鑰保存庫讀取祕密。

az keyvault set-policy --name mykeyvault \
  --resource-group myResourceGroup \
  --object-id $principalID \
  --secret-permissions get

繼續手動執行工作

選項 2:使用系統指派的身分識別來建立工作

本節中的步驟可建立工作,並啟用系統指派的身分識別。 如果您想要改為啟用使用者指派的身分識別,請參閱選項 1:使用使用者指派的身分識別來建立工作

建立工作

執行下列 az acr task create 命令以建立工作 dockerhubtask。 此工作會在沒有原始程式碼內容的情況下執行,而命令會參考工作目錄中的 dockerhubtask.yaml 檔案。 不含值的 --assign-identity 參數可在工作上啟用系統指派的身分識別。

az acr task create \
  --name dockerhubtask \
  --registry myregistry \
  --context /dev/null \
  --file dockerhubtask.yaml \
  --assign-identity 

在命令輸出中,identity 區段會顯示 SystemAssigned 類型的身分識別已在工作中設定。 principalId 是工作身分識別的主體識別碼:

[...]
  "identity": {
    "principalId": "xxxxxxxx-2703-42f9-97d0-xxxxxxxxxxxx",
    "tenantId": "xxxxxxxx-86f1-41af-91ab-xxxxxxxxxxxx",
    "type": "SystemAssigned",
    "userAssignedIdentities": null
  },
  "location": "eastus",
[...]

使用 az acr task show 命令將 principalId 儲存在變數中,以便在稍後的命令中使用。 在下列命令中,取代您的工作名稱和登錄:

principalID=$(az acr task show \
  --name <task_name> --registry <registry_name> \
  --query identity.principalId --output tsv)

將金鑰保存庫的存取權授與身分識別

請執行下列 az keyvault set-policy 命令,以針對金鑰保存庫設定存取原則。 下列範例允許身分識別從金鑰保存庫讀取祕密。

az keyvault set-policy --name mykeyvault \
  --resource-group myResourceGroup \
  --object-id $principalID \
  --secret-permissions get

手動執行工作

若要確認您已啟用受控識別的工作成功執行,請使用 az acr task run 命令來手動觸發工作。 參數 --set 是用來將私人存放庫名稱傳遞至工作。 在此範例中,預留位置存放庫名稱為 hubuser/hubrepo

az acr task run --name dockerhubtask --registry myregistry --set PrivateRepo=hubuser/hubrepo

當工作成功執行時,輸出會顯示成功驗證 Docker Hub,而且已成功建置映像並推送至私人存放庫:

Queued a run with ID: cf24
Waiting for an agent...
2019/06/20 18:05:55 Using acb_vol_b1edae11-30de-4f2b-a9c7-7d743e811101 as the home volume
2019/06/20 18:05:58 Creating Docker network: acb_default_network, driver: 'bridge'
2019/06/20 18:05:58 Successfully set up Docker network: acb_default_network
2019/06/20 18:05:58 Setting up Docker configuration...
2019/06/20 18:05:59 Successfully set up Docker configuration
2019/06/20 18:05:59 Logging in to registry: myregistry.azurecr.io
2019/06/20 18:06:00 Successfully logged into myregistry.azurecr.io
2019/06/20 18:06:00 Executing step ID: acb_step_0. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'
2019/06/20 18:06:00 Launching container with name: acb_step_0
[...]
Login Succeeded
2019/06/20 18:06:02 Successfully executed container: acb_step_0
2019/06/20 18:06:02 Executing step ID: acb_step_1. Timeout(sec): 600, Working directory: '', Network: 'acb_default_network'
2019/06/20 18:06:02 Scanning for dependencies...
2019/06/20 18:06:04 Successfully scanned dependencies
2019/06/20 18:06:04 Launching container with name: acb_step_1
Sending build context to Docker daemon    129kB
[...]
2019/06/20 18:06:07 Successfully pushed image: hubuser/hubrepo:cf24
2019/06/20 18:06:07 Step ID: acb_step_0 marked as successful (elapsed time in seconds: 2.064353)
2019/06/20 18:06:07 Step ID: acb_step_1 marked as successful (elapsed time in seconds: 2.594061)
2019/06/20 18:06:07 Populating digests for step ID: acb_step_1...
2019/06/20 18:06:09 Successfully populated digests for step ID: acb_step_1
2019/06/20 18:06:09 Step ID: acb_step_2 marked as successful (elapsed time in seconds: 2.743923)
2019/06/20 18:06:09 The following dependencies were found:
2019/06/20 18:06:09
- image:
    registry: registry.hub.docker.com
    repository: hubuser/hubrepo
    tag: cf24
    digest: sha256:92c7f9c92844bbbb5d0a101b22f7c2a7949e40f8ea90c8b3bc396879d95e899a
  runtime-dependency:
    registry: registry.hub.docker.com
    repository: library/hello-world
    tag: latest
    digest: sha256:0e11c388b664df8a27a901dce21eb89f11d8292f7fca1b3e3c4321bf7897bffe
  git:
    git-head-revision: b0ffa6043dd893a4c75644c5fed384c82ebb5f9e

Run ID: cf24 was successful after 15s

若要確認已推送映像,請檢查私人 Docker Hub 存放庫中的標籤 (在本例為 cf24)。

下一步