共用方式為


在 Azure Kubernetes Service (AKS) 叢集上部署和設定工作負載身分識別

Azure Kubernetes Service (AKS) 是受控 Kubernetes 服務,可讓您快速部署及管理 Kubernetes 叢集。 本文章說明如何:

  • 使用 Azure CLI 與 OpenID Connect 簽發者和 Microsoft Entra 工作負載 ID 來部署 AKS 叢集。
  • 建立 Microsoft Entra 工作負載識別碼和 Kube 服務帳戶。
  • 設定權杖同盟的受控識別。
  • 部署工作負載,並使用工作負載身分識別驗證。
  • 選擇性地向叢集中的 Pod 授與 Azure 金鑰保存庫中秘密的存取權。

本文假設您對 Kubernetes 概念有基本瞭解。 如需詳細資訊,請參閱 Azure Kubernetes Services (AKS) 的 Kubernetes 核心概念。 如果您不熟悉 Microsoft Entra 工作負載識別碼,則請參閱下列概觀文章。

必要條件

注意

您可以使用「服務連接器」來協助您自動設定某些步驟。 另請參閱:教學課程:使用工作負載身分識別以服務連接器連線到 Azure Kubernetes Service (AKS) 中的 Azure 儲存體帳戶

設定有效的訂用帳戶

首先,呼叫 az account set 命令並傳入您的訂用帳戶識別碼,將您的訂用帳戶設定為目前的使用中訂用帳戶。

az account set --subscription <subscription-id>

匯出環境變數

為了協助簡化所需身分識別的設定步驟,下列步驟會定義本文範例所參考的環境變數。 請記得將顯示的值取代為您自己的值:

export RESOURCE_GROUP="myResourceGroup"
export LOCATION="eastus"
export CLUSTER_NAME="myAKSCluster"
export SERVICE_ACCOUNT_NAMESPACE="default"
export SERVICE_ACCOUNT_NAME="workload-identity-sa"
export SUBSCRIPTION="$(az account show --query id --output tsv)"
export USER_ASSIGNED_IDENTITY_NAME="myIdentity"
export FEDERATED_IDENTITY_CREDENTIAL_NAME="myFedIdentity"
# Include these variables to access key vault secrets from a pod in the cluster.
export KEYVAULT_NAME="keyvault-workload-id"
export KEYVAULT_SECRET_NAME="my-secret"

建立資源群組

Azure 資源群組是部署及管理 Azure 資源所在的邏輯群組。 建立資源群組時,系統會提示您指定位置。 此位置是資源群組中繼資料的儲存位置,如果未在資源建立期間指定另一個區域,此位置也會是您在 Azure 中執行資源的位置。

呼叫 az group create 命令來建立資源群組:

az group create --name "${RESOURCE_GROUP}" --location "${LOCATION}"

下列輸出範例顯示資源群組建立成功:

{
  "id": "/subscriptions/<guid>/resourceGroups/myResourceGroup",
  "location": "eastus",
  "managedBy": null,
  "name": "myResourceGroup",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null
}

建立 AKS 叢集

使用 az aks create 命令搭配 --enable-oidc-issuer 參數來建立 AKS 叢集,以啟用 OIDC 簽發者。 下列範例會建立具有單一節點的叢集:

az aks create \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${CLUSTER_NAME}" \
    --enable-oidc-issuer \
    --enable-workload-identity \
    --generate-ssh-keys

幾分鐘後,命令會完成並傳回關於叢集的 JSON 格式資訊。

注意

建立 AKS 叢集時,系統會自動建立第二個資源群組來儲存 AKS 資源。 如需詳細資訊,請參閱為何會使用 AKS 建立兩個資源群組?

更新現有的 AKS 叢集

您可以呼叫 az aks update 命令搭配 --enable-oidc-issuer--enable-workload-identity 參數,將 AKS 叢集更新為使用 OIDC 簽發者並啟用工作負載身分識別。 下列範例會更新現有叢集:

az aks update \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${CLUSTER_NAME}" \
    --enable-oidc-issuer \
    --enable-workload-identity

擷取 OIDC 簽發者 URL

若要取得 OIDC 簽發者 URL 並將其儲存至環境變數,請執行下列命令:

export AKS_OIDC_ISSUER="$(az aks show --name "${CLUSTER_NAME}" \
    --resource-group "${RESOURCE_GROUP}" \
    --query "oidcIssuerProfile.issuerUrl" \
    --output tsv)"

環境變數應包含與下列範例類似的簽發者 URL:

https://eastus.oic.prod-aks.azure.com/00000000-0000-0000-0000-000000000000/11111111-1111-1111-1111-111111111111/

根據預設,簽發者會設定為使用基底 URL https://{region}.oic.prod-aks.azure.com/{tenant_id}/{uuid},其中 {region} 的值會符合作為 AKS 叢集部署目的地的位置。 值 {uuid} 代表 OIDC 金鑰,這是為每個叢集隨機產生的 GUID,是不可變的。

建立受控識別

呼叫 az identity create 命令來建立受控識別。

az identity create \
    --name "${USER_ASSIGNED_IDENTITY_NAME}" \
    --resource-group "${RESOURCE_GROUP}" \
    --location "${LOCATION}" \
    --subscription "${SUBSCRIPTION}"

接下來,為受控識別的用戶端識別碼建立變數。

export USER_ASSIGNED_CLIENT_ID="$(az identity show \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${USER_ASSIGNED_IDENTITY_NAME}" \
    --query 'clientId' \
    --output tsv)"

建立 Kubernetes 服務帳戶

建立 Kubernetes 服務帳戶,並使用在上一個步驟中建立之受控識別的用戶端識別碼加以標註。 使用 az aks get-credentials 命令,並取代叢集名稱和資源群組名稱的值。

az aks get-credentials --name "${CLUSTER_NAME}" --resource-group "${RESOURCE_GROUP}"

在 Azure CLI 中複製並貼上下列多行輸入。

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  annotations:
    azure.workload.identity/client-id: "${USER_ASSIGNED_CLIENT_ID}"
  name: "${SERVICE_ACCOUNT_NAME}"
  namespace: "${SERVICE_ACCOUNT_NAMESPACE}"
EOF

下列輸出顯示工作負載身分識別建立成功:

serviceaccount/workload-identity-sa created

建立同盟身分識別認證

呼叫 az identity federated-credential create 命令,在受控識別、服務帳戶簽發者與主體之間建立同盟身分識別認證。 如需 Microsoft Entra 中同盟身分識別認證的詳細資訊,請參閱 Microsoft Entra ID 中的同盟身分識別認證概觀

az identity federated-credential create \
    --name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} \
    --identity-name "${USER_ASSIGNED_IDENTITY_NAME}" \
    --resource-group "${RESOURCE_GROUP}" \
    --issuer "${AKS_OIDC_ISSUER}" \
    --subject system:serviceaccount:"${SERVICE_ACCOUNT_NAMESPACE}":"${SERVICE_ACCOUNT_NAME}" \
    --audience api://AzureADTokenExchange

注意

同盟身分識別認證在新增後,需要幾秒鐘的時間來散佈。 如果在新增同盟身分識別認證後立即提出權杖要求,在快取重新整理之前,要求可能會失敗。 若要避免此問題,您可以在新增同盟身分識別認證之後稍待片刻,再提出權杖要求。

部署應用程式

當您部署應用程式 Pod 時,資訊清單應該參考建立 Kubernetes 服務帳戶步驟中所建立的服務帳戶。 下列資訊清單顯示如何參考帳戶,特別是 metadata\namespace 和 spec\serviceAccountName 屬性。 請務必為 <image> 指定映像,並為 <containerName> 指定容器名稱:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: sample-workload-identity
  namespace: ${SERVICE_ACCOUNT_NAMESPACE}
  labels:
    azure.workload.identity/use: "true"  # Required. Only pods with this label can use workload identity.
spec:
  serviceAccountName: ${SERVICE_ACCOUNT_NAME}
  containers:
    - image: <image>
      name: <containerName>
EOF

重要

請確定使用工作負載身分識別的應用程式 Pod 有在 Pod 規格中納入標籤 azure.workload.identity/use: "true"。否則,Pod 會於重新啟動後失敗。

授與存取 Azure Key Vault 的權限

此步驟中的指示會示範如何從 Pod 存取 Azure 金鑰保存庫中的秘密、金鑰或憑證。 本節中的範例會設定工作負載身分識別金鑰保存庫中秘密的存取權,但您可以執行類似的步驟來設定金鑰或憑證的存取權。

下列範例會示範如何使用 Azure 角色型存取控制 (Azure RBAC) 權限模型,向 Pod 授與金鑰保存庫的存取權。 如需 Azure Key Vault 的 Azure RBAC 權限模型詳細資訊,請參閱使用 Azure RBAC 向應用程式授與存取 Azure 金鑰保存庫的權限

  1. 建立已啟用清除保護和 RBAC 授權的金鑰保存庫。 如果現有的金鑰保存庫已針對清除保護和 RBAC 授權進行設定,您也可以使用現有的金鑰保存庫:

    export KEYVAULT_RESOURCE_GROUP="myResourceGroup"
    export KEYVAULT_NAME="myKeyVault"
    
    az keyvault create \
        --name "${KEYVAULT_NAME}" \
        --resource-group "${KEYVAULT_RESOURCE_GROUP}" \
        --location "${LOCATION}" \
        --enable-purge-protection \
        --enable-rbac-authorization
    
  2. 向自己指派 RBAC 的 Key Vault 祕密長角色,以便您可以在新的金鑰保存庫中建立秘密:

    export KEYVAULT_RESOURCE_ID=$(az keyvault show --resource-group "${KEYVAULT_RESOURCE_GROUP}" \
        --name "${KEYVAULT_NAME}" \
        --query id \
        --output tsv)
    
    az role assignment create --assignee "\<user-email\>" \
        --role "Key Vault Secrets Officer" \
        --scope "${KEYVAULT_RESOURCE_ID}"
    
  3. 在金鑰保存庫中建立秘密:

    export KEYVAULT_SECRET_NAME="my-secret"
    
    az keyvault secret set \
        --vault-name "${KEYVAULT_NAME}" \
        --name "${KEYVAULT_SECRET_NAME}" \
        --value "Hello\!"
    
  4. 向您先前建立的使用者指派的受控識別指派 Key Vault 秘密使用者角色。 此步驟會向受控識別提供從金鑰保存庫讀取秘密的權限:

    export IDENTITY_PRINCIPAL_ID=$(az identity show \
        --name "${USER_ASSIGNED_IDENTITY_NAME}" \
        --resource-group "${RESOURCE_GROUP}" \
        --query principalId \
        --output tsv)
    
    az role assignment create \
        --assignee-object-id "${IDENTITY_PRINCIPAL_ID}" \
        --role "Key Vault Secrets User" \
        --scope "${KEYVAULT_RESOURCE_ID}" \
        --assignee-principal-type ServicePrincipal
    
  5. 為金鑰儲存庫 URL 建立環境變數:

    export KEYVAULT_URL="$(az keyvault show \
        --resource-group ${KEYVAULT_RESOURCE_GROUP} \
        --name ${KEYVAULT_NAME} \
        --query properties.vaultUri \
        --output tsv)"
    
  6. 部署會參考服務帳戶和金鑰保存庫 URL 的 Pod:

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: sample-workload-identity-key-vault
      namespace: ${SERVICE_ACCOUNT_NAMESPACE}
      labels:
        azure.workload.identity/use: "true"
    spec:
      serviceAccountName: ${SERVICE_ACCOUNT_NAME}
      containers:
        - image: ghcr.io/azure/azure-workload-identity/msal-go
          name: oidc
          env:
          - name: KEYVAULT_URL
            value: ${KEYVAULT_URL}
          - name: SECRET_NAME
            value: ${KEYVAULT_SECRET_NAME}
      nodeSelector:
        kubernetes.io/os: linux
    EOF
    

若要檢查 Webhook 是否已正確插入所有屬性,請使用 kubectl describe 命令:

kubectl describe pod sample-workload-identity-key-vault | grep "SECRET_NAME:"

如果成功,則輸出應該與下列輸出類似:

      SECRET_NAME:                 ${KEYVAULT_SECRET_NAME}

若要確認 Pod 能夠取得權杖並存取資源,請使用 kubectl logs 命令:

kubectl logs sample-workload-identity-key-vault

如果成功,則輸出應該與下列輸出類似:

I0114 10:35:09.795900       1 main.go:63] "successfully got secret" secret="Hello\\!"

重要

Azure RBAC 角色指派最多需要十分鐘來散佈。 如果 Pod 無法存取秘密,您可能需要等候角色指派散佈開來。 如需詳細資訊,請參閱針對 Azure RBAC 進行疑難排解

停用工作負載身分識別

若要在已啟用並設定 Microsoft Entra 工作負載識別碼的 AKS 叢集上將其停用,您可以執行下列命令:

az aks update \
    --resource-group "${RESOURCE_GROUP}" \
    --name "${CLUSTER_NAME}" \
    --disable-workload-identity

下一步

在本文中,您已部署 Kubernetes 叢集,並將其設定為使用工作負載身分識別來準備應用程式工作負載,以使用該認證進行驗證。 現在您已準備好部署應用程式,並將其設定為使用工作負載身分識別搭配最新版的 Azure 身分識別用戶端程式庫。 如果您無法將應用程式重寫為使用最新的用戶端程式庫版本,您可以設定應用程式 Pod,以使用受控識別搭配工作負載身分識別進行驗證,作為短期移轉解決方案。

服務連接器整合可協助簡化 AKS 工作負載和 Azure 備份服務的連線設定。 其會安全地處理驗證和網路設定,並遵循連線至 Azure 服務的最佳做法。 如需詳細資訊,請參閱使用工作負載身分識別連線到 AKS 中的 Azure OpenAI 服務服務連接器簡介