教程:将工作负载标识用于 Azure Kubernetes 服务 (AKS) 上的应用程序

Azure Kubernetes 服务 (AKS) 是可用于快速部署和管理 Kubernetes 群集的托管式 Kubernetes 服务。 本教程介绍以下操作:

  • 使用具有 OpenID Connect (OIDC) 颁发者和托管标识的 Azure CLI 部署 AKS 群集。
  • 创建 Azure 密钥保管库和机密。
  • 创建 Microsoft Entra 工作负载 ID 和 Kubernetes 服务帐户。
  • 为令牌联合配置托管标识。
  • 部署工作负载并使用工作负载标识验证身份验证。

准备阶段

先决条件

  • 如果没有 Azure 订阅,可在开始前创建一个试用帐户
  • 本文需要 2.47.0 或更高版本的 Azure CLI。 如果使用 Azure Cloud Shell,则最新版本已安装。
  • 用于创建群集的标识必须具有相应的最低权限。 有关 AKS 的访问和标识的详细信息,请参阅 Azure Kubernetes 服务 (AKS) 的访问和标识选项
  • 如果有多个 Azure 订阅,请使用 az account set 命令选择应在其中计收资源费用的相应订阅 ID。

创建资源组

Azure 资源组是用于部署和管理 Azure 资源的逻辑组。 创建资源组时,系统会提示你指定一个位置。 此位置是资源组元数据的存储位置,也是资源在 Azure 中运行的位置(如果你在创建资源期间未指定其他区域)。

以下示例在“chinaeast2”位置创建名为“myResourceGroup”的资源组。

  • 使用 az group create 命令创建资源组。

    az group create --name myResourceGroup --location chinaeast2
    

    以下输出示例类似于成功创建资源组:

    {
      "id": "/subscriptions/<guid>/resourceGroups/myResourceGroup",
      "location": "chinaeast2",
      "managedBy": null,
      "name": "myResourceGroup",
      "properties": {
        "provisioningState": "Succeeded"
      },
      "tags": null
    }
    

导出环境变量

为了帮助简化配置所需标识的步骤,以下步骤在群集上定义了环境变量以供引用。

  • 使用这些命令创建这些变量。 替换 RESOURCE_GROUPLOCATIONSERVICE_ACCOUNT_NAMESUBSCRIPTIONUSER_ASSIGNED_IDENTITY_NAMEFEDERATED_IDENTITY_CREDENTIAL_NAME 的默认值。

    export RESOURCE_GROUP="myResourceGroup"
    export LOCATION="chinaeast2"
    export SERVICE_ACCOUNT_NAMESPACE="default"
    export SERVICE_ACCOUNT_NAME="workload-identity-sa"
    export SUBSCRIPTION="$(az account show --query id --output tsv)"
    export USER_ASSIGNED_IDENTITY_NAME="myIdentity"
    export FEDERATED_IDENTITY_CREDENTIAL_NAME="myFedIdentity"
    export KEYVAULT_NAME="azwi-kv-tutorial"
    export KEYVAULT_SECRET_NAME="my-secret"
    

创建 AKS 群集

  1. 使用带有 --enable-oidc-issuer 参数的 az aks create 命令创建 AKS 群集,以使用 OIDC 颁发者。

    az aks create -g "${RESOURCE_GROUP}" -n myAKSCluster --node-count 1 --enable-oidc-issuer --enable-workload-identity --generate-ssh-keys
    

    片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。

  2. 使用以下命令获取 OIDC 颁发者 URL 并将其保存到环境变量中。 替换参数 -n 的默认值,即群集的名称。

    export AKS_OIDC_ISSUER="$(az aks show -n myAKSCluster -g "${RESOURCE_GROUP}" --query "oidcIssuerProfile.issuerUrl" -otsv)"
    

    变量应包含类似于以下示例的颁发者 URL:

    https://eastus.oic.prod-aks.azure.com/00000000-0000-0000-0000-000000000000/00000000-0000-0000-0000-000000000000/
    

    默认情况下,颁发者设置为使用基 URL https://{region}.oic.prod-aks.azure.com,其中 {region} 的值与部署 AKS 群集的位置相匹配。

创建 Azure 密钥保管库和机密

  1. 使用 az keyvault create 命令在本教程中所创建资源组中创建 Azure 密钥保管库。

    az keyvault create --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}" --name "${KEYVAULT_NAME}"
    

    此命令的输出会显示新建的 Key Vault 的属性。 请记下下面列出的两个属性:

    • Name:为 --name 参数提供的保管库名称。
    • vaultUri:在示例中,这是 https://<your-unique-keyvault-name>.vault.azure.cn/。 通过其 REST API 使用保管库的应用程序必须使用此 URI。

    目前,只有你的 Azure 帐户才有权对这个新保管库执行任何操作。

  2. 使用 az keyvault secret set 命令将机密添加到保管库中。 密码是为环境变量 KEYVAULT_SECRET_NAME 指定的值,将在其中存储 Hello! 值。

    az keyvault secret set --vault-name "${KEYVAULT_NAME}" --name "${KEYVAULT_SECRET_NAME}" --value 'Hello!'
    
  3. 使用 az keyvault show 命令将密钥保管库 URL 添加到环境变量 KEYVAULT_URL 中。

    export KEYVAULT_URL="$(az keyvault show -g "${RESOURCE_GROUP}" -n ${KEYVAULT_NAME} --query properties.vaultUri -o tsv)"
    

创建托管标识并授予机密访问权限

  1. 使用 az account set 命令将特定订阅设置为当前活动订阅。

    az account set --subscription "${SUBSCRIPTION}"
    
  2. 使用 az identity create 命令创建托管标识。

    az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}" --subscription "${SUBSCRIPTION}"
    
  3. 为托管标识设置访问策略,以便使用以下命令访问密钥保管库机密。

    export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -otsv)"
    
    az keyvault set-policy --name "${KEYVAULT_NAME}" --secret-permissions get --spn "${USER_ASSIGNED_CLIENT_ID}"
    

创建 Kubernetes 服务帐户

  1. 创建 Kubernetes 服务帐户,并使用 az aks get-credentials 命令,使用上一步中创建的托管标识的客户端 ID 对其进行批注。 替换群集名称和资源组名称的默认值。

    az aks get-credentials -n myAKSCluster -g "${RESOURCE_GROUP}"
    
  2. 将以下多行输入复制到终端中,然后运行命令来创建服务帐户。

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      annotations:
        azure.workload.identity/client-id: ${USER_ASSIGNED_CLIENT_ID}
      name: ${SERVICE_ACCOUNT_NAME}
      namespace: ${SERVICE_ACCOUNT_NAMESPACE}
    EOF
    

    成功创建标识后的输出如下所示:

    Serviceaccount/workload-identity-sa created
    

建立联合标识凭据

  • 使用 az identity federated-credential create 命令在托管标识、服务帐户颁发者和使用者之间创建联合标识凭据。

    az identity federated-credential create --name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} --identity-name ${USER_ASSIGNED_IDENTITY_NAME} --resource-group ${RESOURCE_GROUP} --issuer ${AKS_OIDC_ISSUER} --subject system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME}
    

    注意

    联合标识凭据在最初添加后需要几秒钟的时间才能传播。 如果在添加联合标识凭据后令牌请求立即可用,则可能会在几分钟内出现故障,因为缓存是用旧数据填充在目录中的。 若要避免此问题,可以在添加联合标识凭据后添加轻微的延迟。

部署工作负载

  1. 运行以下命令来部署引用上一步骤中创建的服务帐户的 pod。

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: 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: ${KEYVAULT_URL}
          - name: SECRET_NAME
            value: ${KEYVAULT_SECRET_NAME}
      nodeSelector:
        kubernetes.io/os: linux
    EOF
    

    成功创建 pod 后的输出如下所示:

    pod/quick-start created
    
  2. 使用 kubectl describe 命令检查是否所有属性都正确地注入了 Webhook。

    kubectl describe pod quick-start
    
  3. 使用 kubectl logs 命令验证 pod 是否可以获得令牌并从密钥保管库访问密钥。

    kubectl logs quick-start
    

    成功访问令牌后的输出如下所示:

    I1013 22:49:29.872708       1 main.go:30] "successfully got secret" secret="Hello!"
    

清理资源

可能希望保留这些资源。 如果不再需要这些资源,请使用以下命令将其删除。

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

    kubectl delete pod quick-start
    
  2. 使用 kubectl delete sa 命令删除服务帐户。

    kubectl delete sa "${SERVICE_ACCOUNT_NAME}" --namespace "${SERVICE_ACCOUNT_NAMESPACE}"
    
  3. 使用 az group delete 命令删除 Azure 资源组及其所有资源。

    az group delete --name "${RESOURCE_GROUP}"
    

后续步骤

在本教程中,你部署了一个 Kubernetes 群集,然后部署了一个简单的容器应用程序来测试使用 Microsoft Entra 工作负载 ID 的情况。

本教程用于简介目的。 有关使用生产版 AKS 创建完整解决方案的指南,请参阅 AKS 解决方案指南