分享方式:


如何搭配 Azure 容器執行個體使用受控識別

使用適用於 Azure 資源的受控識別在「Azure 容器執行個體」中執行與其他 Azure 服務互動的程式碼,而無須在程式碼中保有任何秘密或認證。 此功能會為「Azure 容器執行個體」部署提供一個在 Microsoft Entra ID 中自動管理的身分識別。

在本文中,您會了解「Azure 容器執行個體」中的受控識別,以及如何:

  • 在容器群組中啟用使用者指派或系統指派的身分識別
  • 將 Azure 金鑰保存庫存取權授與該身分識別
  • 使用受控識別從執行中的容器存取金鑰保存庫

請改寫範例,以啟用及使用「Azure 容器執行個體」中的身分識別來存取其他 Azure 服務。 這些範例為互動式範例。 不過,實際上您的容器映像會執行程式碼來存取 Azure 服務。

為什麼要使用受控識別?

您可以在執行中的容器使用受控身分識別,向任何支援 Microsoft Entra 驗證的服務進行驗證,而無須在您的容器程式碼中管理認證。 針對不支援 AD 驗證的服務,您可以將祕密儲存在 Azure 金鑰保存庫中,並使用受控識別來存取金鑰保存庫以擷取認證。 如需有關使用受控識別的詳細資訊,請參閱什麼是適用於 Azure 資源的受控識別?

啟用受控識別

當您建立容器群組時,可藉由設定 ContainerGroupIdentity 屬性來啟用一或多個受控識別。 您也可以在容器群組開始執行後啟用或更新受控識別;上述任一動作都會使容器群組重新啟動。 若要在新的或現有的容器群組上設定身分識別,請使用 Azure CLI、Resource Manager 範本、YAML 檔案或另一個 Azure 工具。

「Azure 容器執行個體」同時支援兩種類型的受控 Azure 身分識別:使用者指派和系統指派。 在容器群組上,您可以啟用一個系統指派的身分識別,一或多個使用者指派的身分識別,或是同時啟用這兩種身分識別。 如果您不熟悉 Azure 資源的受控識別,請參閱概觀

建立受控識別

若要使用受控識別,必須將訂閱中一或多個 Azure 服務資源 (例如 Web 應用程式、金鑰保存庫或儲存體帳戶) 的存取權授與該身分識別。 在執行中的容器中使用受控識別與在 Azure 虛擬機器 (VM) 中使用身分識別類似。 如需了解如何使用權杖Azure PowerShell 或 Azure CLIAzure SDKs,請參閱 VM 指引。

必要條件

  • 本文需要 2.0.49 版或更新版本的 Azure CLI。 如果您是使用 Azure Cloud Shell,就已安裝最新版本。

建立 Azure 金鑰保存庫

本文中的範例會在「Azure 容器執行個體」中使用受控識別來存取 Azure 金鑰保存庫祕密。

首先,使用下列 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 命令在金鑰保存庫中儲存一個範例祕密:

az keyvault secret set \
  --name SampleSecret \
  --value "Hello Container Instances" \
  --description ACIsecret --vault-name mykeyvault

請在「Azure 容器執行個體」中使用使用者指派或系統指派的受控識別,繼續進行下列範例以存取金鑰保存庫。

範例 1:使用使用者指派的身分識別來存取 Azure 金鑰保存庫

建立身分識別

首先,使用 az identity create 命令,在您的訂用帳戶中建立身分識別。 您可以使用建立金鑰保存庫時所使用的相同資源群組,也可以使用不同的資源群組。

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

若要在接下來的步驟中使用身分識別,請使用 az identity show 命令,以將身分識別的服務主體識別碼和資源識別碼儲存在變數中。

# Get service principal ID of the user-assigned identity
SP_ID=$(az identity show \
  --resource-group myResourceGroup \
  --name myACIId \
  --query principalId --output tsv)

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

將金鑰保存庫存取權授與使用者指派的身分識別

請執行下列 az keyvault set-policy 命令,以針對金鑰保存庫設定存取原則。 下列範例會允許使用者指派的身分識別從金鑰保存庫取得祕密:

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

在容器群祖上啟用使用者指派的身分識別

執行下列 az container create 命令,以根據 Microsoft 的 azure-cli 影像建立容器執行個體。 此範例會提供一個單一容器群組,可供您用來以互動方式執行 Azure CLI 來存取其他 Azure 服務。 在本節中,只會使用基底作業系統。 如需在容器中使用 Azure CLI 的範例,請參閱在容器群組上啟用系統指派的身分識別 (部分機器翻譯)。

--assign-identity 參數會將使用者指派的受控識別傳遞給群組。 長時間執行的命令會讓容器保持執行。 此範例使用建立金鑰保存庫時所使用的相同資源群組,但您也可以指定不同的資源群組。

az container create \
  --resource-group myResourceGroup \
  --name mycontainer \
  --image mcr.microsoft.com/azure-cli \
  --assign-identity $RESOURCE_ID \
  --command-line "tail -f /dev/null"

您應該會在幾秒內獲得 Azure CLI 的回應,指出部署已完成。 請使用 az container show 命令來檢查其狀態。

az container show \
  --resource-group myResourceGroup \
  --name mycontainer

輸出中的 identity 區段看起來會與以下類似,顯示容器群組中已設定身分識別。 userAssignedIdentities 底下的 principalID 是您在 Microsoft Entra ID 中所建立身分識別的服務主體:

[...]
"identity": {
    "principalId": "null",
    "tenantId": "xxxxxxxx-f292-4e60-9122-xxxxxxxxxxxx",
    "type": "UserAssigned",
    "userAssignedIdentities": {
      "/subscriptions/xxxxxxxx-0903-4b79-a55a-xxxxxxxxxxxx/resourcegroups/danlep1018/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myACIId": {
        "clientId": "xxxxxxxx-5523-45fc-9f49-xxxxxxxxxxxx",
        "principalId": "xxxxxxxx-f25b-4895-b828-xxxxxxxxxxxx"
      }
    }
  },
[...]

使用使用者指派的身分識別從金鑰保存庫取得祕密

現在,您可以使用執行中容器執行個體內的受控識別來存取金鑰保存庫。 請先在容器中啟動 Bash 殼層:

az container exec \
  --resource-group myResourceGroup \
  --name mycontainer \
  --exec-command "/bin/bash"

在容器的 Bash 殼層中執行下列命令。 若要取得存取權杖以使用 Microsoft Entra ID 向金鑰保存庫進行驗證,請執行下列命令:

client_id="xxxxxxxx-5523-45fc-9f49-xxxxxxxxxxxx"
curl "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net&client_id=$client_id" -H Metadata:true -s

輸出:

{"access_token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Imk2bEdrM0ZaenhSY1ViMkMzbkVRN3N5SEpsWSIsImtpZCI6Imk2bEdrM0ZaenhSY1ViMkMzbkVRN3N5SEpsWSJ9......xxxxxxxxxxxxxxxxx","refresh_token":"","expires_in":"28799","expires_on":"1539927532","not_before":"1539898432","resource":"https://vault.azure.net/","token_type":"Bearer"}

若要將存取權杖儲存在變數中以在後續命令中用來進行驗證,請執行下列命令:

TOKEN=$(curl 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net' -H Metadata:true | jq -r '.access_token')

現在,使用存取權杖向金鑰保存庫進行驗證並讀取祕密。 請務必在 URL (https://mykeyvault.vault.azure.net/...) 中替換您的金鑰保存庫名稱:

curl https://mykeyvault.vault.azure.net/secrets/SampleSecret/?api-version=7.4 -H "Authorization: Bearer $TOKEN"

回應看起來會與以下類似,其中會顯示祕密。 在您的程式碼中,您會剖析此輸出來取得祕密。 接著,請在後續作業中使用此祕密來存取另一個 Azure 資源。

{"value":"Hello Container Instances","contentType":"ACIsecret","id":"https://mykeyvault.vault.azure.net/secrets/SampleSecret/xxxxxxxxxxxxxxxxxxxx","attributes":{"enabled":true,"created":1539965967,"updated":1539965967,"recoveryLevel":"Purgeable"},"tags":{"file-encoding":"utf-8"}}

範例 2:使用系統指派的身分識別來存取 Azure 金鑰保存庫

在容器群祖上啟用系統指派的身分識別

執行下列 az container create 命令,以根據 Microsoft 的 azure-cli 影像建立容器執行個體。 此範例會提供一個單一容器群組,可供您用來以互動方式執行 Azure CLI 來存取其他 Azure 服務。

不含任何其他值的 --assign-identity 參數可在群組上啟用系統指派的受控識別。 身分識別的範圍設為容器群組的資源群組。 長時間執行的命令會讓容器保持執行。 此範例會使用建立金鑰保存庫所使用的相同資源群組,其位於身分識別的範圍內。

# Get the resource ID of the resource group
RG_ID=$(az group show --name myResourceGroup --query id --output tsv)

# Create container group with system-managed identity
az container create \
  --resource-group myResourceGroup \
  --name mycontainer \
  --image mcr.microsoft.com/azure-cli \
  --assign-identity --scope $RG_ID \
  --command-line "tail -f /dev/null"

您應該會在幾秒內獲得 Azure CLI 的回應,指出部署已完成。 請使用 az container show 命令來檢查其狀態。

az container show \
  --resource-group myResourceGroup \
  --name mycontainer

輸出中的 identity 區段看起來會與以下類似,顯示已在 Microsoft Entra ID 中建立系統指派的身分識別:

[...]
"identity": {
    "principalId": "xxxxxxxx-528d-7083-b74c-xxxxxxxxxxxx",
    "tenantId": "xxxxxxxx-f292-4e60-9122-xxxxxxxxxxxx",
    "type": "SystemAssigned",
    "userAssignedIdentities": null
},
[...]

請將變數設定為身分識別之 principalId (服務主體識別碼) 的值,以在稍後的步驟中使用。

SP_ID=$(az container show \
  --resource-group myResourceGroup \
  --name mycontainer \
  --query identity.principalId --out tsv)

將金鑰保存庫存取權授與容器群組

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

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

使用容器群組身分識別從金鑰保存庫取得祕密

現在,您可以使用受控識別來存取執行中容器執行個體內的金鑰保存庫。 請先在容器中啟動 Bash 殼層:

az container exec \
  --resource-group myResourceGroup \
  --name mycontainer \
  --exec-command "/bin/bash"

在容器的 Bash 殼層中執行下列命令。 首先,使用受控識別登入 Azure CLI:

az login --identity

從執行中的容器,從金鑰保存庫擷取祕密:

az keyvault secret show \
  --name SampleSecret \
  --vault-name mykeyvault --query value

擷取祕密的值:

"Hello Container Instances"

使用 Resource Manager 範本來啟用受控識別

若要使用 Resource Manager 範本在容器群組中啟用受控識別,請使用 ContainerGroupIdentity 物件來設定 Microsoft.ContainerInstance/containerGroups 物件的 identity 屬性。 下列程式碼片段顯示針對不同案例設定的 identity 屬性。 請參閱 Resource Manager 範本參考。 指定 apiVersion 最低版本 2018-10-01

使用者指派的身分識別

使用者指派的身分識別是一個下列形式的資源識別碼:

"/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}"

您可以啟用一或多個使用者指派的身分識別。

"identity": {
    "type": "UserAssigned",
    "userAssignedIdentities": {
        "myResourceID1": {
            }
        }
    }

系統指派的身分識別

"identity": {
    "type": "SystemAssigned"
    }

系統指派與使用者指派的身分識別

在容器群組上,您可以啟用一個系統指派的身分識別及一或多個使用者指派的身分識別。

"identity": {
    "type": "SystemAssigned, UserAssigned",
    "userAssignedIdentities": {
        "myResourceID1": {
            }
        }
    }
...

使用 YAML 檔案來啟用受控識別

若要在使用 YAML 檔案來部署的容器群組中啟用受控識別,請包含下列 YAML。 指定 apiVersion 最低版本 2018-10-01

使用者指派的身分識別

使用者指派的身分識別是一個下列形式的資源識別碼

'/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'

您可以啟用一或多個使用者指派的身分識別。

identity:
  type: UserAssigned
  userAssignedIdentities:
    {'myResourceID1':{}}

系統指派的身分識別

identity:
  type: SystemAssigned

系統指派與使用者指派的身分識別

在容器群組上,您可以啟用一個系統指派的身分識別及一或多個使用者指派的身分識別。

identity:
  type: SystemAssigned, UserAssigned
  userAssignedIdentities:
   {'myResourceID1':{}}

Windows 容器上的受控識別

Windows 容器群組上的受控識別的運作方式與 Linux 容器群組不同。 針對 Windows 容器,元數據伺服器 (169.254.169.254) 無法取得Microsoft Entra ID 令牌。 客戶可以遵循不同的模式,在 Windows 容器中取得存取令牌。 此模式牽涉到將令牌要求傳送至IDENTITY_ENDPOINT,以及其他資訊,例如主體標識符和秘密,如下所示。 IDENTITY_ENDPOINT和IDENTITY_HEADER會插入為容器中的環境變數。

curl -G -v %IDENTITY_ENDPOINT% --data-urlencode resource=https://vault.azure.net --data-urlencode principalId=<principal id> -H secret:%IDENTITY_HEADER%

範例 powershell 腳本

identityEndpoint = $env:IDENTITY_ENDPOINT
$identityHeader = $env:IDENTITY_HEADER
$resource = "https://vault.azure.net"
$principalId = "b2ee9347-623c-4794-85af-2d5261356f67"
 
Invoke-RestMethod -Uri "$identityEndpoint" `
    -Method Get `
    -Headers @{secret = $identityHeader} `
    -Body @{resource = $resource; principalId = $principalId} `
    -ContentType "application/x-www-form-urlencoded"

Az Login 模組和其他相依於元數據伺服器 (169.254.169.254) 的用戶端連結庫無法在 Windows 容器中運作。 此外,vNet 中的 Windows 容器將無法連線到端點;因此,無法在 Windows 虛擬網路容器中產生受控識別令牌。

下一步

在本文中,您已了解「Azure 容器執行個體」中的受控識別,以及如何:

  • 在容器群組中啟用使用者指派或系統指派的身分識別
  • 將 Azure 金鑰保存庫存取權授與該身分識別
  • 使用受控識別從執行中的容器存取金鑰保存庫