在 Azure Kubernetes 服务(AKS)上设置标识绑定(预览版)

在 Azure Kubernetes 服务(AKS)群集上设置 标识绑定 ,以在使用单个联合标识凭据(FIC)时跨多个群集映射用户分配的托管标识(UAMI)。 此设置可帮助你扩展 Microsoft Entra 的身份验证能力,以便处理工作负载,而不会达到 FIC 限制。

先决条件

安装或更新 aks-preview 扩展

  • 使用aks-previewaz extension add命令将 Azure CLI az extension update 扩展安装或更新到最新版本:

    # Install the aks-preview extension
    az extension add --name aks-preview
    
    # Update to the latest version if already installed
    az extension update --name aks-preview
    

启用IdentityBindingPreview功能标志

  1. 使用IdentityBindingPreview命令在 Azure 订阅上注册az feature register功能标识。

    az feature register --namespace Microsoft.ContainerService --name IdentityBindingPreview
    

    功能注册最长可能需要 15 分钟才能完成。

  2. 等待该功能使用 az feature show 命令完成注册。

    az feature show --namespace Microsoft.ContainerService --name IdentityBindingPreview
    
  3. 功能显示 Registered后,使用 az provider register 命令刷新提供程序注册。

    az provider register --namespace Microsoft.ContainerService
    

创建测试资源

  1. 使用 az group create 命令创建 Azure 资源组。

    export RESOURCE_GROUP="ib-test"
    export LOCATION="chinanorth3"
    
    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  2. 使用az aks create命令并加上--enable-workload-identity--enable-oidc-issuer标志,创建一个启用了工作负荷身份和OIDC颁发者的AKS群集。

    export CLUSTER_NAME="ib-test-cluster"
    
    az aks create --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --location $LOCATION --no-ssh-key --enable-workload-identity --enable-oidc-issuer
    
  3. 使用 az identity create 命令创建用户分配的托管标识(UAMI)。

    export MI_NAME="ib-test-mi"
    az identity create --resource-group $RESOURCE_GROUP --name $MI_NAME
    

验证工作负载身份 Webhook 版本

  • 标识绑定需要工作负载标识 Webhook 的预览版本。 使用以下命令 kubectl get pods 验证已安装的 Webhook 版本:

    kubectl -n kube-system get pods -l azure-workload-identity.io/system=true -o yaml | grep v1.6.0
    

    输出应显示在 v1.6.0-alpha.1 映像标记中,该标记确认安装了正确的版本。

获取 UAMI ID

  • 获取 UAMI 的资源、主体、客户端和租户 ID,并使用以下命令 az identity show 将其设置为环境变量:

    export MI_RESOURCE_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $MI_NAME --query id --output tsv)
    export MI_PRINCIPAL_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $MI_NAME --query principalId --output tsv)
    export MI_CLIENT_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $MI_NAME --query clientId --output tsv)
    export MI_TENANT_ID=$(az identity show --resource-group $RESOURCE_GROUP --name $MI_NAME --query tenantId --output tsv)
    

创建标识绑定

  • 使用 az aks identity-binding create 命令将 UAMI 映射到具有标识绑定的 AKS 群集。

    az aks identity-binding create --resource-group $RESOURCE_GROUP --cluster-name $CLUSTER_NAME --name "${MI_NAME}-ib" --managed-identity-resource-id $MI_RESOURCE_ID
    

    注释

    创建标识绑定时,AKS 会自动创建在 UAMI 下命名 aks-identity-binding 的联合标识凭据(FIC)。 此凭据由 AKS 管理。 请勿在标识绑定使用时修改或删除它。 为标识绑定创建的 FIC 在引用同一 UAMI 的所有标识绑定之间共享。

获取 UAMI 的 OIDC 颁发者 URL

  • 通过使用 az aks identity-binding show 命令检查标识绑定,获取与 UAMI 关联的 OIDC 颁发者 URL。

    az aks identity-binding show --resource-group $RESOURCE_GROUP --cluster-name $CLUSTER_NAME --name "${MI_NAME}-ib"
    

    精简示例输出:

    {
      "oidcIssuer": {
        "oidcIssuerUrl": "https://ib.oic.prod-aks.azure.com/<MI-tenant-id>/<MI-client-id>"
      }
    }
    

连接到 AKS 群集

  1. 使用 az aks get-credentials 命令获取 AKS 群集凭据,并将其保存到单独的 kubeconfig 文件中:

    az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME -a -f "${CLUSTER_NAME}.kubeconfig"
    
  2. KUBECONFIG 环境变量设置为指向新的 kubeconfig 文件:

    export KUBECONFIG="$(pwd)/${CLUSTER_NAME}.kubeconfig"
    

授权命名空间和服务帐户

  • 配置基于角色的访问控制(RBAC),以授予特定主体通过标识绑定使用托管标识的权限,方法是通过以下命令 kubectl apply 应用以下清单。

    注释

    以下示例显式引用 demo 命名空间中的 demo 服务帐户。 虽然显式引用特定服务帐户是一个选项,但也可以引用下面的 subjects服务帐户集合。 有关详细信息 ,请参阅 Kubernetes 文档中的主题。

    kubectl apply -f - <<EOF
    apiVersion: v1
    kind: Namespace
    metadata:
      name: demo
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: demo
      namespace: demo
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: use-mi-${MI_CLIENT_ID}
    rules:
      - verbs: ["use-managed-identity"]
        apiGroups: ["cid.wi.aks.azure.com"]
        resources: ["${MI_CLIENT_ID}"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: use-mi-${MI_CLIENT_ID}
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: use-mi-${MI_CLIENT_ID}
    subjects:
      - kind: ServiceAccount
        name: demo
        namespace: demo
    EOF
    

创建具有清除保护和 Azure RBAC 授权的密钥保管库

  • 使用命令 az keyvault create 和标志 --enable-purge-protection--enable-rbac-authorization 创建启用了清除保护和 Azure RBAC 授权的密钥保管库。 如果现有密钥保管库已配置为清除保护和 Azure RBAC 授权,则可以使用该密钥保管库。

    export KEY_VAULT_NAME="ib-test"
    
    az keyvault create \
        --name $KEY_VAULT_NAME \
        --resource-group $RESOURCE_GROUP \
        --location $LOCATION \
        --enable-purge-protection \
        --enable-rbac-authorization
    

获取密钥保管库资源 ID 和 URL

  1. 使用 az keyvault show 命令获取密钥保管库的资源 ID,并将其设置为环境变量:

    export KEY_VAULT_RESOURCE_ID=$(az keyvault show --resource-group $RESOURCE_GROUP \
        --name $KEY_VAULT_NAME \
        --query id \
        --output tsv)
    
  2. 使用 az keyvault show 命令获取密钥保管库 URL,并将其设置为环境变量:

    export KEYVAULT_URL="$(az keyvault show \
        --resource-group $RESOURCE_GROUP \
        --name $KEY_VAULT_NAME \
        --query properties.vaultUri \
        --output tsv)"
    

配置密钥库的访问权限并创建机密

以下步骤演示如何从 Pod 访问 Azure Key Vault 中的机密、密钥或证书。 本部分中的示例为工作负载标识配置对密钥保管库中机密的访问权限,但你可以执行类似的步骤来配置对密钥或证书的访问权限。

以下示例演示如何使用 Azure RBAC 权限模型向 Pod 授予对密钥保管库的访问权限。 有关 Azure Key Vault 的 Azure RBAC 权限模型的详细信息,请参阅 授予应用程序使用 Azure RBAC 访问 Azure Key Vault 的权限

  1. 使用 az ad signed-in-user show 命令获取已登录用户的对象 ID,并将其设置为环境变量:

    export CALLER_OBJECT_ID=$(az ad signed-in-user show --query id --output tsv)
    
  2. 使用命令为自己分配密钥保管库上的 Azure RBAC az role assignment create角色。

    az role assignment create --assignee $CALLER_OBJECT_ID \
        --role "Key Vault Secrets Officer" \
        --scope $KEY_VAULT_RESOURCE_ID
    
  3. 使用 az keyvault secret set 命令在密钥保管库中创建一个机密。

    export KEY_VAULT_SECRET_NAME="my-secret"
    
    az keyvault secret set \
        --vault-name $KEY_VAULT_NAME \
        --name $KEY_VAULT_SECRET_NAME \
        --value "Hello\!"
    
  4. 使用命令将 az role assignment create角色分配给 UAMI。

    az role assignment create \
        --assignee-object-id $MI_PRINCIPAL_ID \
        --role "Key Vault Secrets User" \
        --scope $KEY_VAULT_RESOURCE_ID \
        --assignee-principal-type ServicePrincipal
    

批注服务帐户

  1. 使用 kubectl annotate 命令对服务帐户进行批注,添加托管标识租户 ID。

    kubectl annotate sa demo -n demo azure.workload.identity/tenant-id=$MI_TENANT_ID
    
  2. 使用 kubectl annotate 命令为服务帐户标注托管标识客户端 ID。

    kubectl annotate sa demo -n demo azure.workload.identity/client-id=$MI_CLIENT_ID
    

部署示例应用程序

  • 通过使用标识绑定获取托管标识的访问令牌,部署示例 Pod,以便使用以下 kubectl apply 命令访问 Azure Key Vault:

    kubectl apply -f - <<EOF
    apiVersion: v1
    kind: Pod
    metadata:
      name: demo
      namespace: demo
      labels:
        azure.workload.identity/use: "true"
      annotations:
        azure.workload.identity/use-identity-binding: "true"
    spec:
      serviceAccount: demo
      containers:
        - name: azure-sdk
          # source code: https://github.com/Azure/azure-workload-identity/blob/feature/custom-token-endpoint/examples/identitybinding-msal-go/main.go
          image: ghcr.io/bahe-msft/azure-workload-identity/identitybinding-msal-go:latest-linux-amd64
          env:
            - name: KEYVAULT_URL
              value: ${KEYVAULT_URL}
            - name: SECRET_NAME
              value: ${KEYVAULT_SECRET_NAME}
      restartPolicy: Never
    EOF
    

验证从示例应用程序访问密钥保管库

  1. 描述 Pod,并确认使用 kubectl describe pod 命令存在环境变量和投影令牌卷装载。

    kubectl describe pod demo -n demo
    

    预期输出应包含AZURE_CLIENT_IDAZURE_TENANT_IDAZURE_FEDERATED_TOKEN_FILEAZURE_AUTHORITY_HOSTAZURE_KUBERNETES_TOKEN_PROXY的值。 AZURE_KUBERNETES_SNI_NAMEAZURE_KUBERNETES_CA_FILE

  2. 使用 kubectl logs 命令验证 Pod 是否能获取令牌并访问资源。

    kubectl logs demo -n demo
    

    如果成功,输出应类似于以下示例:

    I1107 20:03:42.865180       1 main.go:77] "successfully got secret" secret="Hello!"
    

在多个群集上扩展身份绑定

标识绑定允许将多个 AKS 群集映射到同一 UAMI,同时仍使用单个 FIC。 为在多个群集中配置标识绑定,您可以为每个要映射到同一 UAMI 的额外群集重复创建标识绑定验证示例应用程序访问 Key Vault的步骤,即为每个群集创建一个新的标识绑定。

清理资源

如果不再需要本文中创建的资源,可以清理它们以避免产生将来的成本。

  1. 请使用 kubectl delete pod 命令删除 pod。

    kubectl delete pod demo -n demo
    
  2. 使用 kubectl delete ns 命令删除命名空间。

    kubectl delete ns demo
    
  3. 使用 az group delete 命令删除资源组和所有相关资源。

    az group delete --name $RESOURCE_GROUP --yes --no-wait