适用于:Azure Local 上的 AKS
工作负荷标识联合允许在 Microsoft Entra ID 中配置用户分配的托管标识或应用注册,以信任来自 Kubernetes 等外部标识提供程序 (IdP) 的令牌,从而能够访问受 Microsoft Entra 保护的资源,如 Azure Key Vault 或 Azure Blob 存储。
Azure Arc 支持的 Azure Kubernetes 服务 (AKS) 是一种托管 Kubernetes 服务,可让你轻松部署支持工作负荷标识的 Kubernetes 群集。 本文介绍了如何执行以下任务:
- 创建 AKS Arc 群集并启用工作负荷标识(预览版)。
- 创建 Kubernetes 服务帐户并将其绑定到 Azure 托管标识。
- 在托管标识上创建联合凭据,以信任 OIDC 颁发者。
- 部署应用程序。
- 示例:向群集中的 Pod 授予访问 Azure Key Vault 中机密的权限。
有关工作负荷标识联合的概念性概述,请参阅已启用 Azure Arc 的 Kubernetes(预览版)中的工作负荷标识联合。
重要
这些预览功能是可选择启用的自助功能。 预览功能是“按现状”和“按可用”提供的,不包括在服务级别协议和有限保证中。 由 Azure Arc 预览版启用的 Azure Kubernetes 服务将尽力由客户支持部分覆盖。
注意
在公开预览版中,Azure Local 上的 AKS 支持在创建 AKS 群集时启用工作负荷标识。 不过,目前还不支持在群集创建后启用工作负荷标识或在创建后禁用工作负荷标识。
先决条件
在部署启用了 Azure Arc 的 Kubernetes 群集之前,必须满足以下前提条件:
- 如果没有 Azure 订阅,请在开始之前创建一个免费帐户。
- 本文需要 Azure CLI 版本 1.4.23 或更高版本。 如果你使用的是 Azure Cloud Shell,则表示已安装最新版本。
导出环境变量
为帮助简化配置所需标识的步骤,以下命令定义了本文示例中引用的环境变量。 将以下值替换为你自己的值:
$AZSubscriptionID = "00000000-0000-0000-0000-000000000000"
$Location = "westeurope"
$resource_group_name = "myResourceGroup"
$aks_cluster_name = "myAKSCluster"
$SERVICE_ACCOUNT_NAMESPACE = "default"
$SERVICE_ACCOUNT_NAME = "workload-identity-sa"
$FedIdCredentialName = "myFedIdentity"
$MSIName = "myIdentity"
# To access key vault secrets from a pod in the cluster, include these variables:
$KVName = "KV-workload-id"
$KVSecretName= "KV-secret"
设置活动订阅
首先,将订阅设置为当前的活动订阅。 使用订阅 ID 运行 az account set 命令:
az login
az account set -s $AZSubscriptionID
创建资源组
Azure 资源组是用于部署和管理 Azure 资源的逻辑组。 创建资源组时,系统会提示你指定一个位置。 此位置是资源组元数据的存储位置,也是资源在 Azure 中运行的位置(如果你在创建资源期间未指定其他区域)。
若要创建资源组,请运行 az group create 命令:
az group create --name $resource_group_name --location $Location
以下示例输出显示成功创建了一个资源组:
{
"id": "/subscriptions/<guid>/resourceGroups/myResourceGroup",
"location": "westeurope",
"managedBy": null,
"name": "$resource_group_name",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null
}
第 1 步:创建 AKS Arc 群集并启用工作负荷标识
要创建 AKS Arc 群集,需要使用 $customlocation_ID 和 $logicnet_Id 两个值。
-
$customlocation_ID:自定义位置的 Azure 资源管理器 ID。 自定义位置是在 Azure Local 群集部署期间配置的。 基础结构管理员应提供自定义位置的资源管理器 ID。 如果基础结构管理员提供了自定义位置名称和资源组名称,则也可以使用$customlocation_ID = $(az customlocation show --name "<your-custom-location-name>" --resource-group $resource_group_name --query "id" -o tsv)来获取资源管理器 ID。 -
$logicnet_Id:按照以下步骤创建的 Azure Local 逻辑网络的 Azure 资源管理器 ID。 基础结构管理员应提供逻辑网络的资源管理器 ID。 如果基础结构管理员提供了逻辑网络名称和资源组名称,则也可以使用$logicnet_Id = $(az stack-hci-vm network lnet show --name "<your-lnet-name>" --resource-group $resource_group_name --query "id" -o tsv)来获取资源管理器 ID。
使用 参数运行 --enable-oidc-issuer --enable-workload-identity 命令。 提供你的 entra-admin-group-object-ids 并确保你是 Microsoft Entra ID 管理组成员,以便进行代理模式访问:
az aksarc create
-n $aks_cluster_name -g $resource_group_name
--custom-location $customlocation_ID --vnet-ids $logicnet_Id
--aad-admin-group-object-ids <entra-admin-group-object-ids>
--generate-ssh-keys
--enable-oidc-issuer --enable-workload-identity
片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。
成功创建已配置群集后,可能需要一些时间才能部署工作负荷标识扩展。 使用以下命令检查工作负荷标识扩展状态:
az connectedk8s show -n $aks_cluster_name -g $resource_group_name
# agentState = "Succeeded"
"agentPublicKeyCertificate": "",
"agentVersion": "1.21.10",
"arcAgentProfile": {
"agentAutoUpgrade": "Enabled",
"agentErrors": [],
"agentState": "Succeeded",
"desiredAgentVersion": "",
"systemComponents": null
# oidcIssuerProfile "enabled": true and "issuerUrl" present
"oidcIssuerProfile": {
"enabled": true,
"issuerUrl": "https://oidcdiscovery-{location}-endpoint-1111111111111111.000.azurefd.net/00000000-0000-0000-0000-000000000000/11111111-1111-1111-1111-111111111111/"}
在 Azure 门户中,可以查看 Kubernetes 群集“属性”部分下的 wiextension 扩展。
重要
作为 AKS Arc 群集安全增强功能的一部分,工作负荷标识启用会引发两个变化。 首先,Kubernetes 服务帐户签名密钥每 45 天自动轮换一次,有效期为 90 天。 其次,--service-account-extend-token-expiration 标志会被禁用,令牌有效期从一年缩短到最长 24 小时。
将 OIDC 颁发者 URL 保存为环境变量
成功创建 AKS 群集后,就可以获取 OIDC 颁发者 URL 并将其保存到环境变量中。 运行以下命令:
$SERVICE_ACCOUNT_ISSUER =$(az connectedk8s show --n $aks_cluster_name --resource-group $resource_group_name --query "oidcIssuerProfile.issuerUrl" --output tsv)
步骤 2:创建 Kubernetes 服务帐户并将其绑定到 Azure 托管标识
首先,创建托管标识。 运行 az identity create 命令:
az identity create --name $MSIName --resource-group $resource_group_name --location $Location --subscription $AZSubscriptionID
接下来,为托管标识客户端 ID 创建一个变量:
$MSIId=$(az identity show --resource-group $resource_group_name --name $MSIName --query 'clientId' --output tsv)
$MSIPrincipalId=$(az identity show --resource-group $resource_group_name --name $MSIName --query 'principalId' --output tsv)
创建 Kubernetes 服务帐户
在此步骤中,你将创建 Kubernetes 服务帐户,并使用在上一步中创建的托管标识的客户端 ID 对其进行批注。
使用群集连接从客户端设备访问群集。 有关详细信息,请参阅 从客户端设备访问群集:
az connectedk8s proxy -n $aks_cluster_name -g $resource_group_name
打开新的 CLI 命令窗口。 复制并粘贴以下命令:
$yaml = @"
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
azure.workload.identity/client-id: $MSIId
name: $SERVICE_ACCOUNT_NAME
namespace: $SERVICE_ACCOUNT_NAMESPACE
"@
$yaml = $yaml -replace '\$MSIId', $MSIId `
-replace '\$SERVICE_ACCOUNT_NAME', $SERVICE_ACCOUNT_NAME `
-replace '\$SERVICE_ACCOUNT_NAMESPACE', $SERVICE_ACCOUNT_NAMESPACE
$yaml | kubectl apply -f -
以下输出显示了服务帐户创建成功:
serviceaccount/workload-identity-sa created
步骤 3:在托管标识上创建联合凭据,以信任 OIDC 颁发者
首先,创建联合标识凭据。 调用 az identity federated-credential create 命令在托管标识、服务帐户颁发者和使用者之间创建联合标识凭据。 有关 Microsoft Entra 中联合标识凭据的详细信息,请参阅 Microsoft Entra ID 中的联合标识凭据概述。
# Create a federated credential
az identity federated-credential create --name $FedIdCredentialName --identity-name $MSIName --resource-group $resource_group_name --issuer $SERVICE_ACCOUNT_ISSUER --subject "system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}"
# Show the federated credential
az identity federated-credential show --name $FedIdCredentialName --resource-group $resource_group_name --identity-name $MSIName
注意
在添加联合标识凭据后,需要几秒钟的时间来传播。 紧接着进行的令牌请求可能会失败,直到缓存刷新。 为防止出现这一问题,可考虑在创建联合标识凭据后增加短暂的延迟。
步骤 4:部署应用程序
部署应用程序 Pod 时,清单应引用在创建 Kubernetes 服务帐户步骤中创建的服务帐户。 以下清单显示了如何引用帐户,特别是 metadata\namespace 和 spec\serviceAccountName 属性。 请确保为 image 指定映像,并为 containerName 指定容器名称:
$image = "<image>" # Replace <image> with the actual image name
$containerName = "<containerName>" # Replace <containerName> with the actual container name
$yaml = @"
apiVersion: v1
kind: Pod
metadata:
name: sample-quick-start
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
"@
# Replace variables within the YAML content
$yaml = $yaml -replace '\$SERVICE_ACCOUNT_NAMESPACE', $SERVICE_ACCOUNT_NAMESPACE `
-replace '\$SERVICE_ACCOUNT_NAME', $SERVICE_ACCOUNT_NAME
# Apply the YAML configuration
$yaml | kubectl apply -f -
重要
确保使用工作负荷标识的应用程序 Pod 在 Pod 规范中包含标签 azure.workload.identity/use: "true"。否则 Pod 重启后就会失败。
示例:授予访问 Azure 密钥保管库的权限
此步骤中的说明演示如何从 pod 访问 Azure 密钥保管库中的秘密、密钥或证书。 本部分中的示例为工作负载标识配置对密钥保管库中机密的访问权限,但你可以执行类似的步骤来配置对密钥或证书的访问权限。
以下示例演示如何使用 Azure 基于角色的访问控制 (Azure RBAC) 权限模型向 Pod 授予访问密钥保管库的权限。 有关 Azure Key Vault 的 Azure RBAC 权限模型的详细信息,请参阅使用 Azure RBAC 授予应用程序访问 Azure Key Vault 的权限。
创建启用了清除保护功能和 RBAC 授权的新密钥保管库。 如果为清除保护功能和 RBAC 授权配置了现有密钥保管库,也可以使用它:
az keyvault create --name $KVName --resource-group $resource_group_name --location $Location --enable-purge-protection --enable-rbac-authorization # retrieve the key vault ID for role assignment $KVId=$(az keyvault show --resource-group $resource_group_name --name $KVName --query id --output tsv)将 RBAC 密钥保管库机密主管角色分配给你自己,以便可以在新的密钥保管库中创建机密。 新角色分配最多可能需要 5 分钟才能传播并由授权服务器更新。
$CALLER_OBJECT_ID=$(az ad signed-in-user show --query id -o tsv) az role assignment create --assignee-object-id $CALLER_OBJECT_ID --role "Key Vault Secrets Officer" --scope $KVId --assignee-principal-type ServicePrincipal在密钥保管库中创建机密:
az keyvault secret set --vault-name $KVName --name $KVSecretName --value "Hello!"将密钥保管库机密用户角色分配给之前创建的用户分配的托管标识。 此步骤授予托管标识从密钥保管库读取机密的权限:
$IDENTITY_PRINCIPAL_ID=$(az identity show --name "$USER_ASSIGNED_IDENTITY_NAME" --resource-group "$resource_group_name" --query principalId --output tsv) az role assignment create --assignee-object-id $IDENTITY_PRINCIPAL_ID --role "Key Vault Secrets User" --scope $KVId --assignee-principal-type ServicePrincipal为密钥保管库 URL 创建环境变量:
$KVUrl=$(az keyvault show --resource-group $resource_group_name --name $KVName --query properties.vaultUri --output tsv)部署一个引用服务帐户和密钥保管库 URL 的 Pod:
$yaml = @" apiVersion: v1 kind: Pod metadata: name: sample-quick-start 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: $KVUrl - name: SECRET_NAME value: $KVSecretName nodeSelector: kubernetes.io/os: linux "@ # Replace variables within the YAML content $yaml = $yaml -replace '\$SERVICE_ACCOUNT_NAMESPACE', $SERVICE_ACCOUNT_NAMESPACE ` -replace '\$SERVICE_ACCOUNT_NAME', $SERVICE_ACCOUNT_NAME ` -replace '\$KVUrl', $KVUrl ` -replace '\$KVSecretName', $KVSecretName # Apply the YAML configuration $yaml | kubectl --kubeconfig <path-to-aks-cluster-kubeconfig> apply -f -
删除 AKS 弧形群
若要删除 AKS Arc 群集,请使用 az aksarc delete 命令:
az aksarc delete -n $aks_cluster_name -g $resource_group_name
注意
在删除 AKS Arc 集群时有一个已知的问题 PodDisruptionBudget (PDB) 资源:删除可能无法删除这些 PDB 资源。 微软已经意识到这个问题,并正在着手修复。
PDB 默认安装在已启用身份识别功能的 AKS Arc 集群中。 删除已启用工作负载标识的 AKS Arc 集群, 参见 故障排除指南.
后续步骤
在本文中,你部署了 Kubernetes 群集并将其配置为使用工作负荷标识,为应用程序工作负荷使用该凭据进行身份验证做好准备。 现在,你已准备好部署应用程序并将其配置为将工作负荷标识与最新版 Azure 标识客户端库配合使用。
还可以按照 Azure Arc 启用的 AKS 安全手册中的指导,以其他方式保护群集。