本文提供有关如何在 Azure Kubernetes 服务(AKS)中启用和使用系统分配的、用户分配的或预先创建的 kubelet 托管标识的分步说明。
AKS 托管标识先决条件
阅读 Azure Kubernetes 服务(AKS)中的托管标识概述 ,了解 AKS 中可用的不同类型的托管标识,以及如何使用这些标识安全地访问 Azure 资源。
运行本文中的示例之前,请使用
az account set命令将订阅设置为当前活动订阅。az account set --subscription <subscription-id>如果还没有 Azure 资源组,请通过调用
az group create该命令来创建一个。az group create \ --name <resource-group-name> \ --location <location>
Azure CLI 版本最低要求
- 确保已安装 Azure CLI 版本 2.23.0 或更高版本。 运行
az --version即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI。 - 若要使用预先创建的 kubelet 托管标识,需要安装 Azure CLI 2.26.0 或更高版本。
- 若要更新现有群集以使用系统分配的托管标识或用户分配的托管标识,需要安装 Azure CLI 2.49.0 或更高版本。
局限性
不支持将启用托管标识的群集移动或迁移到其他租户。
如果群集启用了 Microsoft Entra pod 托管标识 (
aad-pod-identity),节点托管标识 (NMI) pod 将修改节点的 iptable,以拦截对 Azure 实例元数据终结点 (IMDS) 的调用。 此配置意味着对 IMDS 终结点发出的任何请求都将被 NMI 拦截,即使特定 Pod 不使用aad-pod-identity。可以配置 AzurePodIdentityException 自定义资源定义 (CRD),以指定应该中转来自与 CRD 中定义的标签匹配的 Pod 对 IMDS 终结点的请求,而不在 NMI 中进行任何处理。 通过配置 AzurePodIdentityException CRD,排除
kubernetes.azure.com/managedby: aks中 kube-system 命名空间中带有aad-pod-identity标签的系统 Pod。 有关详细信息,请参阅在 Azure Kubernetes 服务中使用 Microsoft Entra Pod 托管标识。若要配置例外情况,请安装 mic-exception YAML。
如果使用的是自定义专用 DNS 区域,则 AKS 不支持使用系统分配的托管标识。
Azure 美国政府云中的 USDOD Central、USDOD East 和 USGov Iowa 区域不支持创建具有用户分配的托管标识的群集。
- 预先创建的 kubelet 托管标识必须是用户分配的托管标识。
- 不支持由世纪互联运营的 Azure 中的“中国东部”和“中国北部”区域。
注意
更新集群时请牢记以下信息:
仅当有要使用的 VHD 更新时,更新才有效。 如果你运行的是最新的 VHD,则需要等到下一个 VHD 可用才能执行更新。
Azure CLI 可以确保你的插件权限在迁移后正确设置。 如果不使用 Azure CLI 执行迁移操作,则需要自行处理插件身份的权限。 有关使用 Azure 资源管理器 (ARM) 模板的示例,请参阅使用 ARM 模板分配 Azure 角色。
如果您的群集使用
--attach-acr从 Azure 容器注册表(ACR)中拉取映像,那么在更新群集后,您需要运行az aks update --resource-group <resource-group-name> --name <aks-cluster-name> --attach-acr <acr-resource-id>命令,以便让新创建用于托管身份的 kubelet 获得从 ACR 拉取映像的权限。 否则,升级后将无法从 ACR 进行拉取。
在 AKS 群集上启用系统分配的托管标识
在新的 AKS 群集上启用系统分配的托管标识
创建新的 AKS 群集时,默认情况下会启用系统分配的托管标识。
使用
az aks create命令创建 AKS 群集。az aks create \ --resource-group <resource-group-name> \ --name <aks-cluster-name> \ --generate-ssh-keys
更新现有 AKS 群集以使用系统分配的托管标识
使用
az aks update命令和--enable-managed-identity参数,将现有 AKS 群集从服务主体更新为系统分配的托管标识。az aks update \ --resource-group <resource-group-name> \ --name <aks-cluster-name> \ --enable-managed-identity将群集更新为使用系统分配的托管标识而不是服务主体后,控制平面和 Pod 在访问 Azure 中的其他服务时将使用系统分配的托管标识进行授权。 Kubelet 将继续使用服务主体,直到您也升级代理池。 可以在节点上使用
az aks nodepool upgrade --resource-group <resource-group-name> --cluster-name <aks-cluster-name> --name <node-pool-name> --node-image-only命令更新到托管标识。 节点池升级会导致 AKS 群集停机,因为节点池中的节点被封锁、清空并重新映像。
获取系统分配的托管标识的主体 ID
使用
az aks show命令获取群集系统分配的托管标识的主体 ID。CLIENT_ID=$(az aks show \ --name <aks-cluster-name> \ --resource-group <resource-group-name> \ --query identity.principalId \ --output tsv)
为系统分配的托管标识添加角色分配
使用
az role assignment create命令将 Azure RBAC 角色分配给系统分配的托管标识。对于默认工作器节点资源组外部的 VNet、附加的 Azure 磁盘、静态 IP 地址或路由表,需要对自定义资源组分配
Network Contributor角色。以下示例将 网络贡献者 角色分配给系统分配的托管标识。 角色分配的范围限定为包含 VNet 的资源组。
az role assignment create \ --assignee <client-id> \ --role "Network Contributor" \ --scope <custom-resource-group-id>注意
向群集托管标识授予的权限最长可能需要 60 分钟才能填充。
创建用户分配的托管标识
如果你没有用户分配的托管标识资源,请使用
az identity create命令创建一个。az identity create \ --name <identity-name> \ --resource-group <resource-group-name>输出应与下面的示例输出类似:
{ "clientId": "<client-id>", "clientSecretUrl": "<clientSecretUrl>", "id": "/subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<identity-name>", "location": "<location>", "name": "<identity-name>", "principalId": "<principal-id>", "resourceGroup": "<resource-group-name>", "tags": {}, "tenantId": "<tenant-id>", "type": "Microsoft.ManagedIdentity/userAssignedIdentities" }
获取用户分配的托管标识的主体 ID
使用
az identity show命令获取用户分配的托管身份的主体 ID。CLIENT_ID=$(az identity show \ --name <identity-name> \ --resource-group <resource-group-name> \ --query principalId \ --output tsv)
获取用户分配的托管标识的资源 ID
使用
az identity show命令获取用户定义的托管身份的资源 ID。RESOURCE_ID=$(az identity show \ --name <identity-name> \ --resource-group <resource-group-name> \ --query id \ --output tsv)
将 Azure RBAC 角色分配给用户分配的托管标识
使用
az role assignment create命令为用户分配的托管标识添加角色分配。以下示例将“密钥保管库机密用户”角色分配给用户分配的托管标识,以授予其访问密钥保管库中的机密的权限。 角色分配的范围限定为密钥保管库资源:
az role assignment create \ --assignee <client-id> \ --role "Key Vault Secrets User" \ --scope "<keyvault-resource-id>"注意
向群集托管标识授予的权限最长可能需要 60 分钟才能填充。
在 AKS 群集上启用用户分配的托管标识
在新 AKS 群集上启用用户分配的托管标识
使用
az aks create命令创建具有用户分配的托管标识的 AKS 群集。 包含--assign-identity参数并传入用户分配的托管标识的资源 ID:az aks create \ --resource-group <resource-group-name> \ --name <cluster-name> \ --network-plugin azure \ --vnet-subnet-id <vnet-subnet-id> \ --dns-service-ip 10.2.0.10 \ --service-cidr 10.2.0.0/24 \ --assign-identity $RESOURCE_ID \ --generate-ssh-keys
更新现有群集以使用用户分配的托管标识
使用
az aks update命令更新现有群集以使用用户分配的托管标识。 包含--assign-identity参数并传入用户分配的托管标识的资源 ID:az aks update \ --resource-group <resource-group-name> \ --name <cluster-name> \ --enable-managed-identity \ --assign-identity $RESOURCE_ID成功更新群集以使用用户分配的托管标识后,输出应如以下示例所示:
"identity": { "principalId": null, "tenantId": null, "type": "UserAssigned", "userAssignedIdentities": { "/subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<identity-name>": { "clientId": "<client-id>", "principalId": "<principal-id>" } } },注意
将控制平面的托管标识从“系统分配”迁移到“用户分配”不会导致控制平面和代理池停机。 控制平面组件将继续使用旧的系统分配的标识长达几个小时,直到下一次令牌刷新。
确定群集正在使用哪种类型的托管标识
使用
az aks show命令验证群集使用的托管标识类型。az aks show \ --name <aks-cluster-name> \ --resource-group <resource-group-name> \ --query identity.type \ --output tsv如果群集使用托管标识,则 type 属性的值将为 SystemAssigned 或 UserAssigned。
如果群集正在使用服务主体,则 type 属性的值为 null。 请考虑升级群集以使用托管标识。
创建 kubelet 托管标识
如果你没有 kubelet 托管标识,请使用
az identity create命令创建一个。az identity create \ --name <kubelet-identity-name> \ --resource-group <resource-group-name>输出应与下面的示例输出类似:
{ "clientId": "<client-id>", "clientSecretUrl": "<clientSecretUrl>", "id": "/subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<kubelet-identity-name>", "location": "<location>", "name": "<kubelet-identity-name>", "principalId": "<principal-id>", "resourceGroup": "<resource-group-name>", "tags": {}, "tenantId": "<tenant-id>", "type": "Microsoft.ManagedIdentity/userAssignedIdentities" }
为 kubelet 托管标识分配 RBAC 角色
使用
acrpull命令在 kubelet 托管标识上分配az role assignment create角色。az role assignment create \ --assignee <kubelet-client-id> \ --role "acrpull" \ --scope "<acr-registry-id>"
在 AKS 群集上启用 kubelet 的托管标识
在新 AKS 群集上启用 kubelet 托管标识
使用
az aks create命令创建具有现有标识的 AKS 群集。az aks create \ --resource-group <resource-group-name> \ --name <aks-cluster-name> \ --network-plugin azure \ --vnet-subnet-id <vnet-subnet-id> \ --dns-service-ip 10.2.0.10 \ --service-cidr 10.2.0.0/24 \ --assign-identity <identity-resource-id> \ --assign-kubelet-identity <kubelet-identity-resource-id> \ --generate-ssh-keys使用 kubelet 托管标识成功创建 AKS 群集后,应生成如下所示的输出:
"identity": { "principalId": null, "tenantId": null, "type": "UserAssigned", "userAssignedIdentities": { "/subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<identity-name>": { "clientId": "<client-id>", "principalId": "<principal-id>" } } }, "identityProfile": { "kubeletidentity": { "clientId": "<client-id>", "objectId": "<object-id>", "resourceId": "/subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<kubelet-identity-name>" } },
更新现有群集以使用 kubelet 托管标识
若要更新现有群集以使用 kubelet 托管标识,请首先获取 AKS 群集的当前控制平面托管标识。
警告
更新 kubelet 托管标识会升级 AKS 群集的节点池,确保在执行之前配置正确的可用性配置(如 Pod 中断预算),以避免工作负荷中断或在维护时段内执行此作。
使用
az aks show命令确认 AKS 群集是否在使用用户分配的托管标识。az aks show \ --resource-group <resource-group-name> \ --name <aks-cluster-name> \ --query "servicePrincipalProfile"如果群集使用托管标识,则输出会显示
clientId,其值为 msi。 使用服务主体的群集会显示一个对象 ID。 例如:# The cluster is using a managed identity. { "clientId": "msi" }确认群集正在使用托管标识后,可使用
az aks show命令查找托管标识的资源 ID。az aks show --resource-group <resource-group-name> \ --name <aks-cluster-name> \ --query "identity"对于用户分配的托管标识,输出应类似于以下示例输出:
{ "principalId": null, "tenantId": null, "type": "UserAssigned", "userAssignedIdentities": <identity-resource-id> "clientId": "<client-id>", "principalId": "<principal-id>" },使用
az aks update命令更新具有现有标识的群集。 为assign-identity参数提供控制平面的用户分配托管标识的资源 ID。 为assign-kubelet-identity参数提供 kubelet 托管标识的资源 ID。az aks update \ --resource-group <resource-group-name> \ --name <aks-cluster-name> \ --enable-managed-identity \ --assign-identity <identity-resource-id> \ --assign-kubelet-identity <kubelet-identity-resource-id>使用你自己的 kubelet 托管标识成功更新 AKS 群集后,应会显示类似于以下示例输出的信息:
"identity": { "principalId": null, "tenantId": null, "type": "UserAssigned", "userAssignedIdentities": { "/subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<identity-name>": { "clientId": "<client-id>", "principalId": "<principal-id>" } } }, "identityProfile": { "kubeletidentity": { "clientId": "<client-id>", "objectId": "<object-id>", "resourceId": "/subscriptions/<subscription-id>/resourcegroups/<resource-group-name>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<kubelet-identity-name>" } },
获取 kubelet 托管标识的属性
使用
az aks show命令并在identityProfile.kubeletidentity属性上查询来获取 kubelet 托管标识的属性。az aks show \ --name <aks-cluster-name> \ --resource-group <resource-group-name> \ --query "identityProfile.kubeletidentity"
后续步骤
- 使用 [Azure 资源管理器模板][aks-arm-template] 创建已启用托管标识的群集。
- 了解如何对 AKS 中所有受支持的 Microsoft Entra 身份验证方法使用 kubelogin。