在 Azure Kubernetes Service (AKS) 中使用 Microsoft Entra Pod 受控識別 (預覽)

Microsoft Entra Pod 受控識別會使用 Kubernetes 基本類型,以將 Azure 資源的受控識別與具有 Pod 的 Microsoft Entra ID 中的身分識別建立關聯。 系統管理員會建立身分識別和繫結作為 Kubernetes 基本類型,以讓 Pod 存取依賴於 Microsoft Entra ID 作為識別提供者的 Azure 資源。

重要

建議您檢閱 Microsoft Entra 工作負載識別碼。 此驗證方法會取代 Pod 受控識別 (預覽),其會與 Kubernetes 原生功能整合,代表應用程式來與任何外部識別提供者建立同盟。

Azure Kubernetes Service 中的開放原始碼 Microsoft Entra Pod 受控識別 (預覽) 已於 2022 年 10 月 24 日棄用,而且專案已於 2023 年 9 月封存。 如需詳細資訊,請參閱淘汰通知。 AKS Managed 附加元件將於 2024 年 9 月開始淘汰。

若要停用 AKS Managed 附加元件,請使用下列命令:az feature unregister --namespace "Microsoft.ContainerService" --name "EnablePodIdentityPreview"

開始之前

您必須安裝 Azure CLI 2.20.0 版或更新版本。

限制

  • 一個叢集最多允許 200 個 Pod 受控識別。
  • 一個叢集最多允許 200 個 Pod 受控識別例外狀況。
  • Pod 受控識別僅適用於 Linux 節點集區。
  • 此功能僅支援虛擬機器擴展集所支援的叢集。

安裝 aks-preview Azure CLI 延伸模組

重要

AKS 預覽功能可透過自助服務,以加入方式使用。 預覽會以「現狀」和「可供使用時」提供,其其不受服務等級協定和有限瑕疵擔保所保護。 客戶支援部門會盡最大努力,部分支援 AKS 預覽。 因此,這些功能不適合實際執行用途。 如需詳細資訊,請參閱下列支援文章:

若要安裝 aks-preview 延伸模組,請執行下列命令:

az extension add --name aks-preview

執行下列命令,以更新為發行的最新版延伸模組:

az extension update --name aks-preview

註冊 'EnablePodIdentityPreview' 功能旗標

使用 az feature register 命令以註冊 EnablePodIdentityPreview 功能旗標,如下列範例所示:

az feature register --namespace "Microsoft.ContainerService" --name "EnablePodIdentityPreview"

狀態需要幾分鐘的時間才會顯示「已註冊」。 使用 az feature show 命令以驗證註冊狀態:

az feature show --namespace "Microsoft.ContainerService" --name "EnablePodIdentityPreview"

當狀態反映 [已註冊] 時,請使用 az provider register 命令來重新整理 Microsoft.ContainerService 資源提供者的註冊:

az provider register --namespace Microsoft.ContainerService

作業模式選項

Microsoft Entra Pod 受控識別支援兩種作業模式:

  • 標準模式:在此模式中,下列兩個元件會部署至 AKS 叢集:
    • 受控識別控制器 (MIC):MIC 是 Kubernetes 控制器,可透過 Kubernetes API Server 監看 Pod、AzureIdentityAzureIdentityBinding 的變更。 當其偵測到相關的變更時,MIC 會視需要新增或刪除 AzureAssignedIdentity。 具體而言,排程 Pod 時,MIC 會將 Azure 上的受控識別指派給節點集區在建立階段期間所使用的基礎虛擬機器擴展集。 刪除所有使用身分識別的 Pod 時,其會從節點集區的虛擬機器擴展集移除身分識別,除非其他 Pod 使用相同的受控識別。 建立或刪除 AzureIdentity 或 AzureIdentityBinding 時,MIC 會採取類似的動作。
    • 節點管理身分識別 (NMI):NMI 是在 AKS 叢集中的每個節點上以 DaemonSet 形式執行的 Pod。 NMI 會攔截每個節點上對 Azure 執行個體中繼資料服務的安全性權杖要求,並將其重新導向至本身,然後驗證 Pod 是否有權存取向其要求權杖的身分識別,以及代表應用程式從 Microsoft Entra 租用戶擷取權杖。
  • 受控模式:此模式僅提供 NMI。 透過 AKS 叢集附加元件安裝時,Azure 會管理 Kubernetes 基本類型 (AzureIdentity 和 AzureIdentityBinding) 的建立以及身分識別指派,以回應使用者的 CLI 命令。 否則,如果透過 Helm 圖表安裝,則需要由使用者手動指派和管理身分識別。 如需詳細資訊,請參閱受控模式中的 Pod 身分識別

當您透過 Helm 圖表或 YAML 資訊清單安裝 Microsoft Entra Pod 受控識別時 (如安裝指南所示),可以在 standardmanaged 模式之間進行選擇。 如果您決定改為使用 AKS 叢集附加元件來安裝 Microsoft Entra Pod 受控識別 (如此文章所示),則安裝程式將會使用 managed 模式。

使用 Azure 容器網路介面 (CNI) 建立 AKS 叢集

注意

這是預設的建議設定

建立已啟用 Azure CNI 和 Pod 受控識別的 AKS 叢集。 下列命令會使用 az group create 來建立名為 myResourceGroup 的資源群組,而 az aks create 命令會在 myResourceGroup 資源群組中建立名為 myAKSCluster 的 AKS 叢集。

az group create --name myResourceGroup --location eastus
az aks create -g myResourceGroup -n myAKSCluster --enable-pod-identity --network-plugin azure

使用 az aks get-credentials 登入您的 AKS 叢集。 此命令也會下載並設定開發電腦上的 kubectl 用戶端憑證。

az aks get-credentials --resource-group myResourceGroup --name myAKSCluster

注意

當您在 AKS 叢集上啟用 Pod 受控識別時,名為 aks-addon-exception 的 AzurePodIdentityException 會新增至 kube-system 命名空間。 AzurePodIdentityException 可讓具有特定標籤的 Pod 存取 Azure 執行個體中繼資料服務 (IMDS) 端點,而不會遭到 NMI 伺服器攔截。 aks-addon-exception 允許 AKS 第一方附加元件 (例如 Microsoft Entra Pod 受控識別) 以在不需要手動設定 AzurePodIdentityException 的情況下運作。 您可以選擇性地使用 az aks pod-identity exception addaz aks pod-identity exception deleteaz aks pod-identity exception updatekubectl 來新增、移除及更新 AzurePodIdentityException。

使用 Azure CNI 更新現有的 AKS 叢集

使用 Azure CNI 更新現有的 AKS 叢集,以包含 Pod 受控識別。

az aks update -g $MY_RESOURCE_GROUP -n $MY_CLUSTER --enable-pod-identity

搭配使用 Kubenet 網路外掛程式與 Microsoft Entra Pod 受控識別

重要

基於安全性考量,使用 Kubenet 在叢集中執行 Microsoft Entra Pod 受控識別不是建議的設定。 預設 Kubenet 設定無法防止 ARP 詐騙,而 Pod 可能會利用此方式作為另一個 Pod,並取得其不打算擁有的身分識別存取權。 請先遵循風險降低步驟並設定原則,再使用 Kubenet 以在叢集中啟用 Microsoft Entra Pod 受控識別。

風險降低

若要降低叢集層級的弱點,您可以使用 Azure 內建原則「Kubernetes 叢集容器只能使用允許的功能」來限制 CAP_NET_RAW 攻擊。

將 NET_RAW 新增至「必要的卸除功能」

image

如果您未使用 Azure 原則,則可以使用 OpenPolicyAgent 許可控制器搭配閘道管理員驗證 Webhook。 如果您已在叢集中安裝 Gatekeeper,請新增 K8sPSPCapabilities 類型的 ConstraintTemplate:

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper-library/master/library/pod-security-policy/capabilities/template.yaml

新增範本,以使用 NET_RAW 功能限制 Pod 繁衍:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPCapabilities
metadata:
  name: prevent-net-raw
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
    excludedNamespaces:
      - "kube-system"
  parameters:
    requiredDropCapabilities: ["NET_RAW"]

使用 Kubenet 網路外掛程式建立 AKS 叢集

建立已啟用 Kubenet 網路外掛程式和 Pod 受控識別的 AKS 叢集。

az aks create -g $MY_RESOURCE_GROUP -n $MY_CLUSTER --enable-pod-identity --enable-pod-identity-with-kubenet

使用 Kubenet 網路外掛程式更新現有的 AKS 叢集

使用 Kubenet 網路外掛程式更新現有的 AKS 叢集,以包含 Pod 受控識別。

az aks update -g $MY_RESOURCE_GROUP -n $MY_CLUSTER --enable-pod-identity --enable-pod-identity-with-kubenet

建立身分識別

重要

例如,您的訂用帳戶上必須具有相關權限 (例如擁有者) 才能建立身分識別。

建立示範 Pod 將搭配 az identity create 使用的身分識別,並設定 IDENTITY_CLIENT_ID 和 IDENTITY_RESOURCE_ID 變數。

az group create --name myIdentityResourceGroup --location eastus
export IDENTITY_RESOURCE_GROUP="myIdentityResourceGroup"
export IDENTITY_NAME="application-identity"
az identity create --resource-group ${IDENTITY_RESOURCE_GROUP} --name ${IDENTITY_NAME}
export IDENTITY_CLIENT_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME} --query clientId -otsv)"
export IDENTITY_RESOURCE_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME} --query id -otsv)"

指派受控識別的權限

將指派給 Pod 的受控識別必須獲得符合所要採取動作的權限。

若要執行示範,IDENTITY_CLIENT_ID 受控識別必須在資源群組中具有虛擬機器參與者權限,其中包含 AKS 叢集的虛擬機器擴展集。

# Obtain the name of the resource group containing the Virtual Machine Scale set of your AKS cluster, commonly called the node resource group
NODE_GROUP=$(az aks show -g myResourceGroup -n myAKSCluster --query nodeResourceGroup -o tsv)

# Obtain the id of the node resource group 
NODES_RESOURCE_ID=$(az group show -n $NODE_GROUP -o tsv --query "id")

# Create a role assignment granting your managed identity permissions on the node resource group
az role assignment create --role "Virtual Machine Contributor" --assignee "$IDENTITY_CLIENT_ID" --scope $NODES_RESOURCE_ID

建立 Pod 身分識別

使用 az aks pod-identity add 建立叢集的 Pod 受控識別。

export POD_IDENTITY_NAME="my-pod-identity"
export POD_IDENTITY_NAMESPACE="my-app"
az aks pod-identity add --resource-group myResourceGroup --cluster-name myAKSCluster --namespace ${POD_IDENTITY_NAMESPACE}  --name ${POD_IDENTITY_NAME} --identity-resource-id ${IDENTITY_RESOURCE_ID}

注意

「POD_IDENTITY_NAME」必須是 RFC 1123 中定義的有效 DNS 子網域名稱

注意

當您使用 pod-identity add 指派 Pod 受控識別時,Azure CLI 會嘗試透過 Pod 受控識別 (IDENTITY_RESOURCE_ID) 將受控識別操作員角色授與叢集身分識別。

Azure 會在叢集中建立代表 Azure 中身分識別的 AzureIdentity 資源,以及將 AzureIdentity 連線至選取器的 AzureIdentityBinding 資源。 您可以使用下列方式來檢視這些資源

kubectl get azureidentity -n $POD_IDENTITY_NAMESPACE
kubectl get azureidentitybinding -n $POD_IDENTITY_NAMESPACE

執行範例應用程式

若要讓 Pod 使用 Microsoft Entra Pod 受控識別,Pod 需要 aadpodidbinding 標籤,且其值符合 AzureIdentityBinding 中的選取器。 依預設,選取器將符合 Pod 受控識別的名稱,但在呼叫 az aks pod-identity add 時,也可以使用 --binding-selector 選項進行設定。

若要使用 Microsoft Entra Pod 受控識別來執行範例應用程式,請使用下列內容來建立 demo.yaml 檔案。 將 POD_IDENTITY_NAME、IDENTITY_CLIENT_ID 和 IDENTITY_RESOURCE_GROUP 取代為先前步驟中的值。 將 SUBSCRIPTION_ID 取代為您的訂用帳戶識別碼。

注意

在先前的步驟中,您已建立 POD_IDENTITY_NAME、IDENTITY_CLIENT_ID 和 IDENTITY_RESOURCE_GROUP 變數。 您可以使用 echo 之類的命令來顯示您為變數設定的值,例如 echo $POD_IDENTITY_NAME

apiVersion: v1
kind: Pod
metadata:
  name: demo
  labels:
    aadpodidbinding: $POD_IDENTITY_NAME
spec:
  containers:
  - name: demo
    image: mcr.microsoft.com/oss/azure/aad-pod-identity/demo:v1.6.3
    args:
      - --subscriptionid=$SUBSCRIPTION_ID
      - --clientid=$IDENTITY_CLIENT_ID
      - --resourcegroup=$IDENTITY_RESOURCE_GROUP
    env:
      - name: MY_POD_NAME
        valueFrom:
          fieldRef:
            fieldPath: metadata.name
      - name: MY_POD_NAMESPACE
        valueFrom:
          fieldRef:
            fieldPath: metadata.namespace
      - name: MY_POD_IP
        valueFrom:
          fieldRef:
            fieldPath: status.podIP
  nodeSelector:
    kubernetes.io/os: linux

請注意,Pod 定義具有 aadpodidbinding 標籤,且其值符合您在上一個步驟中執行 az aks pod-identity add 的 Pod 受控識別名稱。

使用 kubectl apply,將 demo.yaml 部署至與 Pod 受控識別相同的命名空間:

kubectl apply -f demo.yaml --namespace $POD_IDENTITY_NAMESPACE

使用 kubectl logs 確認範例應用程式已成功執行。

kubectl logs demo --follow --namespace $POD_IDENTITY_NAMESPACE

確認記錄顯示權杖已成功取得,且 GET 作業成功。

...
successfully doARMOperations vm count 0
successfully acquired a token using the MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token)
successfully acquired a token, userAssignedID MSI, msiEndpoint(http://169.254.169.254/metadata/identity/oauth2/token) clientID(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
successfully made GET on instance metadata
...

執行具有多個身分識別的應用程式

若要讓應用程式使用多個身分識別,請在建立 Pod 身分識別時,將 --binding-selector 設定為相同的選取器。

az aks pod-identity add --resource-group myResourceGroup --cluster-name myAKSCluster --namespace ${POD_IDENTITY_NAMESPACE}  --name ${POD_IDENTITY_NAME_1} --identity-resource-id ${IDENTITY_RESOURCE_ID_1} --binding-selector myMultiIdentitySelector
az aks pod-identity add --resource-group myResourceGroup --cluster-name myAKSCluster --namespace ${POD_IDENTITY_NAMESPACE}  --name ${POD_IDENTITY_NAME_2} --identity-resource-id ${IDENTITY_RESOURCE_ID_2} --binding-selector myMultiIdentitySelector

然後將 Pod YAML 中的 aadpodidbinding 欄位設定為您指定的繫結選取器。

apiVersion: v1
kind: Pod
metadata:
  name: demo
  labels:
    aadpodidbinding: myMultiIdentitySelector
...

停用現有叢集上的 Pod 受控識別

若要停用現有叢集上的 Pod 受控識別,請從叢集中移除 Pod 受控識別。 然後,停用租用戶上的這個功能。

az aks pod-identity delete --name ${POD_IDENTITY_NAME} --namespace ${POD_IDENTITY_NAMESPACE} --resource-group myResourceGroup --cluster-name myAKSCluster
az aks update --resource-group myResourceGroup --name myAKSCluster --disable-pod-identity

清理

若要從叢集中移除 Microsoft Entra Pod 受控識別,請從叢集中移除範例應用程式和 Pod 受控識別。 然後移除身分識別和叢集身分識別的角色指派。

kubectl delete pod demo --namespace $POD_IDENTITY_NAMESPACE
az aks pod-identity delete --name ${POD_IDENTITY_NAME} --namespace ${POD_IDENTITY_NAMESPACE} --resource-group myResourceGroup --cluster-name myAKSCluster
az identity delete -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME}
az role assignment delete --role "Managed Identity Operator" --assignee "$IDENTITY_CLIENT_ID" --scope "$IDENTITY_RESOURCE_ID"

下一步

如需受控識別的相關詳細資訊,請參閱適用於 Azure 資源的受控識別