在 Azure Kubernetes 服务 (AKS) 上配置跨租户工作负载标识
本文介绍如何在 Azure Kubernetes 服务 (AKS) 上配置跨租户工作负载标识。 跨租户工作负载标识允许从你的 AKS 群集访问另一个租户中的资源。 在此示例中,你在一个租户中创建一个 Azure 服务总线,并从另一个租户的 AKS 群集中运行的工作负载向其发送消息。
有关工作负载标识的详细信息,请参阅工作负载标识概述。
先决条件
两个 Azure 订阅,每个订阅位于单独的租户中。 在本文中,我们将它们称为租户 A 和租户 B。
已安装到本地计算机的 Azure CLI。 如果未安装 Azure CLI,请参阅安装 Azure CLI。
Bash shell 环境。 本文使用 Bash shell 语法。
你需要具有以下订阅详细信息:
- 租户 A 租户 ID
- 租户 A 订阅 ID
- 租户 B 租户 ID
- 租户 B 订阅 ID
重要
请确保在本文的持续时间内停留在同一终端窗口中,以保留你设置的环境变量。 如果关闭了终端窗口,则需要再次设置环境变量。
在租户 A 中配置资源
在租户 A 中,创建启用了工作负载标识和 OIDC 颁发者的 AKS 群集。 使用此群集部署一个尝试访问租户 B 中的资源的应用程序。
登录到租户 A
使用
az login
命令登录到租户 A 订阅。# Set environment variable TENANT_A_ID=<tenant-id> az login --tenant $TENANT_A_ID
确保使用
az account set
命令在租户 A 中使用正确的订阅。# Set environment variable TENANT_A_SUBSCRIPTION_ID=<subscription-id> # Log in to your Tenant A subscription az account set --subscription $TENANT_A_SUBSCRIPTION_ID
在租户 A 中创建资源
使用
az group create
命令在租户 A 中创建资源组以托管 AKS 群集。# Set environment variables RESOURCE_GROUP=<resource-group-name> LOCATION=<location> # Create a resource group az group create --name $RESOURCE_GROUP --location $LOCATION
使用
az aks create
命令在启用了工作负载标识和 OIDC 颁发者的租户 A 中创建 AKS 群集。# Set environment variable CLUSTER_NAME=<cluster-name> # Create an AKS cluster az aks create \ --resource-group $RESOURCE_GROUP \ --name $CLUSTER_NAME \ --enable-oidc-issuer \ --enable-workload-identity \ --generate-ssh-keys
从 AKS 群集获取 OIDC 颁发者 URL
使用
az aks show
命令从租户 A 中的群集获取 OIDC 颁发者 URL。OIDC_ISSUER_URL=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query "oidcIssuerProfile.issuerUrl" --output tsv)
在租户 B 中配置资源
在租户 B 中,创建 Azure 服务总线、托管标识并为其分配向服务总线读取和写入消息的权限,并在租户 A 中的托管标识与 AKS 群集之间建立信任。
登录到租户 B
使用
az logout
命令登出租户 A 订阅。az logout
使用
az login
命令登录到租户 B 订阅。# Set environment variable TENANT_B_ID=<tenant-id> az login --tenant $TENANT_B_ID
确保使用
az account set
命令在租户 B 中使用正确的订阅。# Set environment variable TENANT_B_SUBSCRIPTION_ID=<subscription-id> # Log in to your Tenant B subscription az account set --subscription $TENANT_B_SUBSCRIPTION_ID
在租户 B 中创建资源
使用
az group create
命令在租户 B 中创建资源组以承载托管标识。# Set environment variables RESOURCE_GROUP=<resource-group-name> LOCATION=<location> # Create a resource group az group create --name $RESOURCE_GROUP --location $LOCATION
使用
az servicebus namespace create
和az servicebus queue create
命令在租户 B 中创建服务总线和队列。# Set environment variable SERVICEBUS_NAME=sb-crosstenantdemo-$RANDOM # Create a new service bus namespace and and return the service bus hostname SERVICEBUS_HOSTNAME=$(az servicebus namespace create \ --name $SERVICEBUS_NAME \ --resource-group $RESOURCE_GROUP \ --disable-local-auth \ --query serviceBusEndpoint \ --output tsv | sed -e 's/https:\/\///' -e 's/:443\///') # Create a new queue in the service bus namespace az servicebus queue create \ --name myqueue \ --namespace $SERVICEBUS_NAME \ --resource-group $RESOURCE_GROUP
使用
az identity create
命令在租户 B 中创建用户分配的托管标识。# Set environment variable IDENTITY_NAME=${SERVICEBUS_NAME}-identity # Create a user-assigned managed identity az identity create --resource-group $RESOURCE_GROUP --name $IDENTITY_NAME
在租户 B 中获取资源 ID 并分配权限
使用
az identity show
命令获取租户 B 中托管标识的主体 ID。# Get the user-assigned managed identity principalId PRINCIPAL_ID=$(az identity show \ --resource-group $RESOURCE_GROUP \ --name $IDENTITY_NAME \ --query principalId \ --output tsv)
使用
az identity show
命令获取租户 B 中托管标识的客户端 ID。CLIENT_ID=$(az identity show \ --resource-group $RESOURCE_GROUP \ --name $IDENTITY_NAME \ --query clientId \ --output tsv)
使用
az servicebus namespace show
命令获取租户 B 中服务总线命名空间的资源 ID。SERVICEBUS_ID=$(az servicebus namespace show \ --name $SERVICEBUS_NAME \ --resource-group $RESOURCE_GROUP \ --query id \ --output tsv)
使用
az role assignment create
命令在租户 B 中分配托管标识以读取和写入服务总线消息。az role assignment create \ --role "Azure Service Bus Data Owner" \ --assignee-object-id $PRINCIPAL_ID \ --assignee-principal-type ServicePrincipal \ --scope $SERVICEBUS_ID
在 AKS 群集与托管标识之间建立信任
在本部分中,你将创建在租户 A 中的 AKS 群集与租户 B 中的托管标识之间建立信任所需的联合标识凭据。使用租户 A 中 AKS 群集中的 OIDC 颁发者 URL 和租户 B 中托管标识的名称。
使用
az identity federated-credential create
命令创建联合标识凭据。az identity federated-credential create \ --name $IDENTITY_NAME-$RANDOM \ --identity-name $IDENTITY_NAME \ --resource-group $RESOURCE_GROUP \ --issuer $OIDC_ISSUER_URL \ --subject system:serviceaccount:default:myserviceaccount
--subject system:serviceaccount:default:myserviceaccount
是本文后面你在租户 A 中创建的 Kubernetes 服务帐户的名称。 当应用程序 Pod 发出身份验证请求时,此值将作为授权请求中的 subject
发送到 Microsoft Entra ID。 Microsoft Entra ID 根据此值是否与创建联合标识凭据时设置的信息相匹配来确定资格,因此请务必确保值互相匹配。
部署应用程序以将消息发送到 Azure 服务总线队列
在本部分中,你将应用程序部署到租户 A 中的 AKS 群集,而该应用程序会向租户 B 中的 Azure 服务总线队列发送消息。
登录到租户 A 并获取 AKS 凭据
使用
az logout
命令登出租户 B 订阅。az logout
使用
az login
命令登录到租户 A 订阅。az login --tenant $TENANT_A_ID
确保使用
az account set
命令在租户 A 中使用正确的订阅。az account set --subscription $TENANT_A_SUBSCRIPTION_ID
使用
az aks get-credentials
命令获取租户 A 中 AKS 群集的凭据。az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME
创建 Kubernetes 资源以将消息发送给 Azure 服务总线队列
在
default
命名空间中创建新的 Kubernetes ServiceAccount,并将租户 B 中托管标识的客户端 ID 传递给kubectl apply
命令。 该客户端 ID 用于向租户 B 中的 Azure 服务总线验证租户 A 中的应用。kubectl apply -f - <<EOF apiVersion: v1 kind: ServiceAccount metadata: annotations: azure.workload.identity/client-id: $CLIENT_ID name: myserviceaccount EOF
在
default
命名空间中创建新的 Kubernetes 作业,以将 100 条消息发送到你的 Azure 服务总线队列。 该 Pod 模板已配置为使用你在上一步创建的工作负载标识和服务帐户。 另请注意,AZURE_TENANT_ID
环境变量设置为租户 B 的租户 ID。这是必需的,因为工作负载标识默认为 AKS 群集的租户,因此需要显式设置租户 B 的租户 ID。kubectl apply -f - <<EOF apiVersion: batch/v1 kind: Job metadata: name: myproducer spec: template: metadata: labels: azure.workload.identity/use: "true" spec: serviceAccountName: myserviceaccount containers: - image: ghcr.io/azure-samples/aks-app-samples/servicebusdemo:latest name: myproducer resources: {} env: - name: OPERATION_MODE value: "producer" - name: MESSAGE_COUNT value: "100" - name: AZURE_SERVICEBUS_QUEUE_NAME value: myqueue - name: AZURE_SERVICEBUS_HOSTNAME value: $SERVICEBUS_HOSTNAME - name: AZURE_TENANT_ID value: $TENANT_B_ID restartPolicy: Never EOF
验证部署
使用
kubectl describe pod
命令检查 Pod 的状态,验证 Pod 是否已正确配置为与租户 B 中的 Azure 服务总线队列进行交互。# Get the dynamically generated pod name POD_NAME=$(kubectl get po --selector job-name=myproducer -o jsonpath='{.items[0].metadata.name}') # Verify the tenant ID environment variable is set for Tenant B kubectl describe pod $POD_NAME | grep AZURE_TENANT_ID
检查 Pod 的日志,查看应用程序是否可以使用
kubectl logs
命令跨租户发送消息。kubectl logs $POD_NAME
输出应类似于以下示例输出:
... Adding message to batch: Hello World! Adding message to batch: Hello World! Adding message to batch: Hello World! Sent 100 messages
注意
作为额外的验证步骤,你可以转到 Azure 门户 并导航到租户 B 中的 Azure 服务总线队列,以查看 Service Bus Explorer 中发送的消息。
清理资源
验证部署成功后,可以清理资源以避免产生 Azure 成本。
删除租户 A 中的资源
使用
az login
命令登录到租户 A 订阅。az login --tenant $TENANT_A_ID
确保使用
az account set
命令在租户 A 中使用正确的订阅。az account set --subscription $TENANT_A_SUBSCRIPTION_ID
使用
az group delete
命令删除 Azure 资源组及其中的所有资源。az group delete --name $RESOURCE_GROUP --yes --no-wait
删除租户 B 中的资源
使用
az login
命令登录到租户 B 订阅。az login --tenant $TENANT_B_ID
确保使用
az account set
命令在租户 B 中使用正确的订阅。az account set --subscription $TENANT_B_SUBSCRIPTION_ID
使用
az group delete
命令删除 Azure 资源组及其中的所有资源。az group delete --name $RESOURCE_GROUP --yes --no-wait
后续步骤
本文介绍了如何在 Azure Kubernetes 服务 (AKS) 上配置跨租户工作负载标识。 若要了解有关工作负载标识的详细信息,请参阅以下文章: