本文介绍如何在新的或现有的 AKS 群集上启用用户分配的托管标识,获取用户分配的托管标识的主体 ID,并为用户分配的托管标识添加角色分配。
先决条件
阅读 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 2.23.0 或更高版本。 运行
az --version即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI。 - 若要更新现有群集以使用 用户分配的托管标识,需要安装 Azure CLI 2.49.0 或更高版本。
- 在本地安装 Terraform。 有关安装说明,请参阅 安装 Terraform。
局限性
- 使用托管标识创建群集后,无法切换回使用服务主体。
- 不支持将启用托管标识的群集移动或迁移到其他租户。
- 如果群集已启用 Microsoft Entra pod 托管标识(
aad-pod-identity),Node-Managed Identity(NMI)Pod 将修改节点的 iptables,以截获对 Azure 实例元数据(IMDS)终结点的调用。 此配置意味着对 IMDS 终结点发出的任何请求都将被 NMI 拦截,即使特定 Pod 不使用aad-pod-identity。- 可以配置 AzurePodIdentityException 自定义资源定义(CRD),以指定来自匹配 CRD 中定义标签的 Pod 的请求应在不经过 NMI 处理的情况下直接代理至 IMDS 终结点。 通过配置 AzurePodIdentityException CRD,排除
kubernetes.azure.com/managedby: aks中 kube-system 命名空间中带有aad-pod-identity标签的系统 Pod。 有关详细信息,请参阅 在 Azure Kubernetes 服务(AKS)中使用 Microsoft Entra pod 托管标识。 - 若要配置例外情况,请安装 mic-exception YAML。
- 可以配置 AzurePodIdentityException 自定义资源定义(CRD),以指定来自匹配 CRD 中定义标签的 Pod 的请求应在不经过 NMI 处理的情况下直接代理至 IMDS 终结点。 通过配置 AzurePodIdentityException CRD,排除
更新群集注意事项
更新群集时,请考虑以下信息:
- 仅当有 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 拉取。
创建用户分配的托管标识
如果你没有用户分配的托管标识资源,请使用 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)
在新 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>"
}
}
},
...
更新群集以使用用户分配的托管标识而不是服务主体后,控制平面和 Pod 在访问 Azure 中的其他服务时会使用用户分配的托管标识进行授权。 Kubelet 继续使用服务主体,直到您升级节点池。 节点池升级会导致 AKS 群集停机,因为节点池中的节点被封锁、清空并重新映像。 可以在您的节点上使用命令将其更新为用户分配的托管身份。
az aks nodepool upgrade \
--resource-group <resource-group-name> \
--cluster-name <aks-cluster-name> \
--name <node-pool-name> \
--node-image-only
注意
将控制平面的托管标识从“系统分配”迁移到“用户分配”不会导致控制平面和代理池停机。 控制平面组件将继续使用旧系统分配的标识长达数小时,直到下一次令牌刷新。
将 Azure RBAC 角色分配给用户分配的托管标识
使用 az role assignment create 命令为用户分配的托管标识添加角色分配。 以下示例将“密钥保管库机密用户”角色分配给用户分配的托管标识,以授予其访问密钥保管库中的机密的权限。 角色的分配范围限定于密钥保管库资源。
az role assignment create \
--assignee <client-id> \
--role "Key Vault Secrets User" \
--scope "<key-vault-resource-id>"
注意
群集托管标识的权限传播可能最长需要 60 分钟才能生效。
创建 Terraform 配置文件
Terraform 配置文件定义 Terraform 创建和管理的基础结构。
创建名为
main.tf的文件,并添加以下代码以定义 Terraform 版本并指定Azure提供程序:terraform { required_version = ">= 1.0" required_providers { azurerm = { source = "hashicorp/azurerm" version = "~> 4.0" } } } provider "azurerm" { features {} }添加以下代码到
main.tf来创建 Azure 资源组。 根据需要随时更改资源组的名称和位置。resource "azurerm_resource_group" "example" { name = "aks-rg" location = "chinanorth3" }
使用 Terraform 创建具有用户分配的托管标识的 AKS 群集
要创建用户分配的托管标识和使用该标识的 AKS 群集,请在 main.tf 中添加以下代码:
resource "azurerm_user_assigned_identity" "uai" {
name = "aks-user-identity"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
}
resource "azurerm_kubernetes_cluster" "user_assigned" {
name = "aks-user"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
dns_prefix = "aksuser"
identity {
type = "UserAssigned"
identity_ids = [azurerm_user_assigned_identity.uai.id]
}
default_node_pool {
name = "system"
node_count = 1
vm_size = "Standard_DS2_v2"
}
}
使用 Terraform 为用户分配的托管标识添加角色分配
添加以下代码,为 main.tf 用户分配的托管标识创建角色分配。 此示例将 Key Vault 机密用户 角色分配给用户分配的托管标识,以授予它访问密钥保管库中的机密的权限。 角色的分配范围限定于密钥保管库资源。
resource "azurerm_role_assignment" "user_assigned_key_vault_secrets_user" {
scope = azurerm_resource_group.example.id
role_definition_name = "Key Vault Secrets User"
principal_id = azurerm_user_assigned_identity.uai.principal_id
}
初始化 Terraform
使用main.tf命令在包含terraform init文件的目录中初始化 Terraform。 此命令下载用于通过 Terraform 管理 Azure 资源所需的 Azure 提供程序。
terraform init
创建 Terraform 执行计划
使用 terraform plan 命令创建 Terraform 执行计划。 此命令显示 Terraform 将在 Azure 订阅中创建或修改的资源。
terraform plan
应用 Terraform 配置
查看并确认执行计划后,使用 terraform apply 命令应用 Terraform 配置。 此命令创建或修改 Azure 订阅中 main.tf 文件中定义的资源。
terraform apply
验证 Terraform 部署
应用 Terraform 配置后,可以使用 [az aks show][az-aks-show] 命令,并结合 --query 参数来验证部署,以筛选输出并显示标识信息。 例如:
az aks show \
--name <cluster-name> \
--resource-group <resource-group> \
--query identity.type \
--output tsv
相关内容
若要详细了解 AKS 中的托管标识,请参阅以下文章: