在 Azure Kubernetes Service (AKS) 上設定身分繫結

在 Azure Kubernetes Service (AKS) 叢集上設定身分識別繫結,以便在多個叢集對應使用者指派的受控身分識別 (UAMI),同時使用單一同盟身分識別憑證 (FIC)。 這種架構幫助你在不超過 FIC 限制的情況下擴展 Microsoft Entra 工作負載的認證。

先決條件

  • 複習 身份綁定概念 ,以了解身份綁定的運作方式。
  • Azure CLI 版本 2.73.0 或更新。 要檢查你的版本,請使用指令 az version 。 若要安裝或更新 Azure CLI,請參見 「安裝 Azure CLI」。
  • 你需要對身份和叢集範圍設定以下 Azure 權限: Microsoft.ManagedIdentity/userAssignedIdentities/federatedIdentityCredentials/write 和 Microsoft.ContainerService/managedClusters/write。
  • 你需要 Kubernetes 叢集管理員權限(或同等級)來建立 ClusterRole 和 ClusterRoleBinding 資源。

局限性

建立測試資源

  1. 使用 az group create 命令來建立 Azure 資源群組。

    export RESOURCE_GROUP="ib-test"
    export LOCATION="westus2"
    
    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  2. 使用 az aks create 命令搭配 --enable-workload-identity 和 --enable-oidc-issuer 標籤建立 AKS 叢集,並啟用工作負載身分識別及 OIDC 簽發者。

    export CLUSTER_NAME="ib-test-cluster"
    
    az aks create --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --location $LOCATION --no-ssh-key --enable-workload-identity --enable-oidc-issuer
    
  3. 使用指令 az identity create 建立使用者指派的管理身份(UAMI)。

    export MI_NAME="ib-test-mi"
    az identity create --resource-group $RESOURCE_GROUP --name $MI_NAME
    

取得UAMI識別碼

  • 取得 UAMI 的資源、主體、客戶端和租戶 ID,並使用以下 az identity show 指令將它們設為環境變數:

    export MI_RESOURCE_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $MI_NAME --query id --output tsv)
    export MI_PRINCIPAL_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $MI_NAME --query principalId --output tsv)
    export MI_CLIENT_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $MI_NAME --query clientId --output tsv)
    export MI_TENANT_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $MI_NAME --query tenantId --output tsv)
    

建立身份識別綁定

  • 用 az aks identity-binding create 指令將 UAMI 映射到 AKS 叢集,並用身份綁定。

    az aks identity-binding create --resource-group $RESOURCE_GROUP --cluster-name $CLUSTER_NAME --name "${MI_NAME}-ib" --managed-identity-resource-id $MI_RESOURCE_ID
    

    備註

    當你建立身份綁定時,AKS 會自動建立一個以 UAMI 命名 aks-identity-binding 的聯邦身份憑證(FIC)。 此憑證由AKS管理。 在使用身份綁定時,不要修改或刪除它。 為身份綁定創建的 FIC 會在所有引用相同 UAMI 的身份綁定中共享。

取得 UAMI 的 OIDC 發行者網址

  • 透過使用 az aks identity-binding show 指令檢查身份綁定,取得與 UAMI 相關的 OIDC 發行者 URL。

    az aks identity-binding show --resource-group $RESOURCE_GROUP --cluster-name $CLUSTER_NAME --name "${MI_NAME}-ib"
    

    簡短範例輸出:

    {
      "oidcIssuer": {
        "oidcIssuerUrl": "https://ib.oic.prod-aks.azure.com/<MI-tenant-id>/<MI-client-id>"
      }
    }
    

連線到 AKS 叢集

  1. 用這個 az aks get-credentials 指令取得 AKS 叢集憑證,並存到另一個 kubeconfig 檔案:

    az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME -a -f "${CLUSTER_NAME}.kubeconfig"
    
  2. 設定 KUBECONFIG 環境變數指向新的 kubeconfig 檔案:

    export KUBECONFIG="$(pwd)/${CLUSTER_NAME}.kubeconfig"
    

授權命名空間與服務帳號

  • 設定角色型存取控制 (RBAC),使用以下 kubectl apply 命令套用下列資訊清單,藉此透過身分識別繫結來為特定主體授予使用受控身分識別的權限。

    備註

    以下範例明確指涉在demo命名空間中的demo服務帳號。 雖然明確指涉特定服務帳戶是一種選項,但也可以指稱subjects下的一組服務帳戶。 欲了解更多資訊,請參閱 Kubernetes 文件中的 「參照主題 」。

    kubectl apply -f - <<EOF
    apiVersion: v1
    kind: Namespace
    metadata:
      name: demo
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: demo
      namespace: demo
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: use-mi-${MI_CLIENT_ID}
    rules:
      - verbs: ["use-managed-identity"]
        apiGroups: ["cid.wi.aks.azure.com"]
        resources: ["${MI_CLIENT_ID}"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: use-mi-${MI_CLIENT_ID}
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: use-mi-${MI_CLIENT_ID}
    subjects:
      - kind: ServiceAccount
        name: demo
        namespace: demo
    EOF
    

建立帶有清除保護與 Azure RBAC 授權的金鑰保險庫

  • 使用 az keyvault create 指令並啟用 --enable-purge-protection 和 --enable-rbac-authorization 標誌來建立一個具備清除保護和 Azure RBAC 授權的金鑰保險庫。 如果現有的金鑰庫同時設定了清除保護和 Azure RBAC 授權,你也可以使用它。

    export KEY_VAULT_NAME="ib-test"
    
    az keyvault create \
        --name $KEY_VAULT_NAME \
        --resource-group $RESOURCE_GROUP \
        --location $LOCATION \
        --enable-purge-protection \
        --enable-rbac-authorization
    

取得金鑰庫資源 ID 和網址

  1. 用指令 az keyvault show 取得金鑰保險庫的資源 ID,並將其設為環境變數:

    export KEY_VAULT_RESOURCE_ID=$(az keyvault show --resource-group $RESOURCE_GROUP \
        --name $KEY_VAULT_NAME \
        --query id \
        --output tsv)
    
  2. 用命令 az keyvault show 取得金鑰保險庫的網址,並設定為環境變數:

    export KEYVAULT_URL="$(az keyvault show \
        --resource-group $RESOURCE_GROUP \
        --name $KEY_VAULT_NAME \
        --query properties.vaultUri \
        --output tsv)"
    

設定 Key Vault 存取權並建立密碼

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

以下範例展示了如何使用 Azure RBAC 權限模型,授權 Pod 存取金鑰庫。 欲了解更多關於Azure Key Vault Azure RBAC權限模型的資訊,請參閱 「授權應用程式使用Azure RBAC存取Azure Key Vault的權限」。

  1. 使用指令 az ad signed-in-user show 取得已登入使用者的物件 ID,並將其設為環境變數:

    export CALLER_OBJECT_ID=$(az ad signed-in-user show --query id --output tsv)
    
  2. 使用 命令指派 Azure RBAC 的 az role assignment create角色給自己。

    az role assignment create --assignee $CALLER_OBJECT_ID \
        --role "Key Vault Secrets Officer" \
        --scope $KEY_VAULT_RESOURCE_ID
    
  3. 使用 az keyvault secret set 命令在金鑰保存庫中建立秘密。

    export KEY_VAULT_SECRET_NAME="my-secret"
    
    az keyvault secret set \
        --vault-name $KEY_VAULT_NAME \
        --name $KEY_VAULT_SECRET_NAME \
        --value "Hello\!"
    
  4. 使用指令將 az role assignment create角色指派給 UAMI。

    az role assignment create \
        --assignee-object-id $MI_PRINCIPAL_ID \
        --role "Key Vault Secrets User" \
        --scope $KEY_VAULT_RESOURCE_ID \
        --assignee-principal-type ServicePrincipal
    

註解服務帳號

  1. 請使用 kubectl annotate 命令將管理的身份租戶 ID 標註到服務帳號上。

    kubectl annotate sa demo -n demo azure.workload.identity/tenant-id=$MI_TENANT_ID
    
  2. 用 kubectl annotate 指令添加具有受管理身份的客戶端 ID 至服務帳戶。

    kubectl annotate sa demo -n demo azure.workload.identity/client-id=$MI_CLIENT_ID
    

部署範例應用程式

  • 使用以下 kubectl apply 命令,部署使用身份識別繫結的範例 pod 以取得存取權杖,以便讓受控身分識別存取 Azure Key Vault。

    kubectl apply -f - <<EOF
    apiVersion: v1
    kind: Pod
    metadata:
      name: demo
      namespace: demo
      labels:
        azure.workload.identity/use: "true"
      annotations:
        azure.workload.identity/use-identity-binding: "true"
    spec:
      serviceAccount: demo
      containers:
        - name: azure-sdk
          # source code: https://github.com/Azure/azure-workload-identity/blob/feature/custom-token-endpoint/examples/identitybinding-msal-go/main.go
          image: ghcr.io/bahe-msft/azure-workload-identity/identitybinding-msal-go:latest-linux-amd64
          env:
            - name: KEYVAULT_URL
              value: ${KEYVAULT_URL}
            - name: SECRET_NAME
              value: ${KEY_VAULT_SECRET_NAME}
      restartPolicy: Never
    EOF
    

從範例應用程式驗證對金鑰保險庫的存取權

  1. 使用 kubectl describe pod 命令描述 pod,並確認環境變數及預測的權杖磁碟區掛接存在。

    kubectl describe pod demo -n demo
    

    預期輸出應包含 AZURE_CLIENT_ID、 AZURE_TENANT_ID、 AZURE_FEDERATED_TOKEN_FILEAZURE_AUTHORITY_HOSTAZURE_KUBERNETES_TOKEN_PROXY、 。 AZURE_KUBERNETES_SNI_NAME 和 AZURE_KUBERNETES_CA_FILE。

  2. 確認 pod 能取得 token 並用 kubectl logs 指令存取資源。

    kubectl logs demo -n demo
    

    如果成功,輸出應該類似下列範例:

    I1107 20:03:42.865180       1 main.go:77] "successfully got secret" secret="Hello!"
    

擴展多叢集的身份綁定

身份綁定允許將多個 AKS 叢集映射到同一 UAMI,同時仍使用單一 FIC。 要擴展身份綁定至多個集群,你可以重複執行從建立身份綁定到驗證從範例應用程式存取金鑰庫的步驟,針對每個額外集群對應到同一個 UAMI(為每個集群建立新的身份綁定)。

清理資源

如果您不再需要本文中所建立的資源,您可以將其清理,以避免未來產生費用。

  1. 使用 kubectl delete pod 命令刪除 pod。

    kubectl delete pod demo -n demo
    
  2. 用指令 kubectl delete ns 刪除命名空間。

    kubectl delete ns demo
    
  3. 使用指令 az group delete 刪除資源群組及所有相關資源。

    az group delete --name $RESOURCE_GROUP --yes --no-wait