在 Azure Kubernetes 服务 (AKS) 群集上部署和配置工作负荷标识

Azure Kubernetes 服务 (AKS) 是可用于快速部署和管理 Kubernetes 群集的托管式 Kubernetes 服务。 在本文中,你将:

  • 使用 Azure CLI 部署一个包含 OpenID Connect 颁发者和 Microsoft Entra Workload ID 的 AKS 群集
  • 授予对 Azure Key Vault 的访问权限
  • 创建 Microsoft Entra Workload ID 和 Kubernetes 服务帐户
  • 为令牌联合配置托管标识。

本文假定你对 Kubernetes 概念有基本的了解。 有关详细信息,请参阅 Azure Kubernetes 服务 (AKS) 的 Kubernetes 核心概念。 如果你不熟悉 Microsoft Entra Workload ID,请参阅下面的概述一文。

  • 本文需要 2.47.0 或更高版本的 Azure CLI。

  • 用于创建群集的标识具有合适的的最低权限。 有关 AKS 的访问和标识的详细信息,请参阅 Azure Kubernetes 服务 (AKS) 的访问和标识选项

  • 如果你有多个 Azure 订阅,请使用 az account 命令选择应在其中计收资源费用的相应订阅 ID。

导出环境变量

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

运行以下命令创建这些变量。 替换 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"

创建 AKS 群集

使用带有 --enable-oidc-issuer 参数的 az aks create 命令创建 AKS 群集,以使用 OIDC 颁发者。 以下示例创建名为“myAKSCluster”的群集,其中一个节点位于 myResourceGroup 中:

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

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

注意

创建 AKS 群集时,会自动创建另一个资源组来存储 AKS 资源。 有关详细信息,请参阅为何使用 AKS 创建两个资源组?

更新现有的 AKS 群集

可以使用带有 --enable-oidc-issuer--enable-workload-identity 参数的 az aks update 命令更新 AKS 群集,以使用 OIDC 颁发者并启用工作负载标识。 以下示例更新名为 myAKSCluster 的群集:

az aks update -g "${RESOURCE_GROUP}" -n myAKSCluster --enable-oidc-issuer --enable-workload-identity

检索 OIDC 颁发者 URL

若要获取 OIDC 颁发者 URL 并将其保存到环境变量,请运行以下命令。 替换参数 -n(群集名称)的默认值:

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

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

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

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

创建托管标识

使用 Azure CLI az account set 命令将特定订阅设置为当前活动订阅。 然后使用 az identity create 命令创建托管标识。

az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}" --subscription "${SUBSCRIPTION}"

接下来,让我们为托管标识 ID 创建一个变量。

export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -o tsv)"

创建 Kubernetes 服务帐户

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

az aks get-credentials -n myAKSCluster -g "${RESOURCE_GROUP}"

将以下多行输入复制粘贴到 Azure CLI 中。

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}" --audience api://AzureADTokenExchange

注意

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

部署应用程序

部署应用程序 Pod 时,清单应引用在创建 Kubernetes 服务帐户步骤中创建的服务帐户。 以下清单演示如何引用帐户,特别是 metadata\namespacespec\serviceAccountName 属性:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: your-pod
  namespace: "${SERVICE_ACCOUNT_NAMESPACE}"
  labels:
    azure.workload.identity/use: "true"  # Required, only the pods with this label can use workload identity
spec:
  serviceAccountName: "${SERVICE_ACCOUNT_NAME}"
  containers:
    - image: <your image>
      name: <containerName>
EOF

重要

确保使用工作负载标识的应用程序 Pod 已将标签 azure.workload.identity/use: "true" 添加到 Pod 规范,否则 Pod 在重启后会失败。

可选 - 授予访问 Azure 密钥保管库的权限

如果需要从 Pod 访问 Azure Key Vault 中装载的机密、密钥和证书,则必须执行此步骤。 请执行以下步骤,以使用托管标识配置访问权限。 这些步骤假定你已在订阅中创建和配置 Azure Key Vault。 如果没有 Azure Key Vault,请参阅使用 Azure CLI 创建 Azure Key Vault

在继续操作之前,需要以下信息:

  • Key Vault 的名称
  • 包含 Key Vault 的资源组

可以使用 Azure CLI 命令 az keyvault list 检索此信息。

  1. 通过运行以下命令为托管标识设置访问策略,以访问 Key Vault 中的机密:

    export KEYVAULT_RESOURCE_GROUP="myResourceGroup"
    export KEYVAULT_NAME="myKeyVault"
    export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -o tsv)"
    
    az keyvault set-policy --name "${KEYVAULT_NAME}" --secret-permissions get --spn "${USER_ASSIGNED_CLIENT_ID}"
    
  2. 在 Key Vault 中创建机密:

    export KEYVAULT_SECRET_NAME="my-secret"
    
    az keyvault secret set --vault-name "${KEYVAULT_NAME}" \
       --name "${KEYVAULT_SECRET_NAME}" \
       --value "Hello\!"
    
  3. 导出 Key Vault URL:

    export KEYVAULT_URL="$(az keyvault show -g ${KEYVAULT_RESOURCE_GROUP} -n ${KEYVAULT_NAME} --query properties.vaultUri -o tsv)"
    
  4. 部署引用上述服务帐户和 Key Vault URL 的 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
    

若要检查 webhook 是否正确注入了所有属性,请使用 kubectl describe 命令:

kubectl describe pod quick-start | grep "SECRET_NAME:"

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

      SECRET_NAME:                 ${KEYVAULT_SECRET_NAME}

若要验证 Pod 是否能够获取令牌和访问资源,请使用 kubectl logs 命令:

kubectl logs quick-start

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

I0114 10:35:09.795900       1 main.go:63] "successfully got secret" secret="Hello\\!"

禁用工作负载标识

若要在已启用和配置的 AKS 群集上禁用 Microsoft Entra Workload ID,可以运行以下命令:

az aks update --resource-group "${RESOURCE_GROUP}" --name myAKSCluster --disable-workload-identity

后续步骤

在本文中,你部署了 Kubernetes 群集并将其配置为使用工作负荷标识,为应用程序工作负荷使用该凭据进行身份验证做好准备。 现在,你已准备好部署应用程序并将其配置为将工作负荷标识与最新版 Azure 标识客户端库配合使用。 如果无法重写应用程序以使用最新的客户端库版本,则可以设置应用程序 Pod,以使用托管标识和工作负荷标识作为短期迁移解决方案进行身份验证。