将 Azure Kubernetes 服务 AKS Pod 从 Pod 托管标识迁移到 Microsoft Entra 工作负荷 ID

使用三种方法之一(基于当前 Azure 标识 SDK 版本:最新 SDK 并行部署、迁移 sidecar 代理(仅限 Linux),或 SDK 重写),将 AKS Pod 从 Pod 托管标识迁移到 Microsoft Entra Workload ID(工作负载标识)。

先决条件

  • Azure CLI 2.47.0 或更高版本。 az --version运行命令以查找版本。 如果需要安装或升级,请参阅 安装 Azure CLI

设置环境变量。

下表列出了本文中命令中使用的环境变量。 请确保将占位符值替换为自己的值。

环境变量 Description 示例值
SUBSCRIPTION_ID 用于创建 AKS 群集和托管标识的 Azure 订阅 ID。 00000000-0000-0000-0000-000000000000
RESOURCE_GROUP 用于创建 AKS 群集和托管标识的资源组名称。 myResourceGroup
LOCATION 在其中创建 AKS 群集和托管标识的 Azure 区域。 chinanorth3
CLUSTER_NAME AKS 群集的名称。 myAKSCluster
MANAGED_IDENTITY_NAME 用户分配的托管标识的名称。 myManagedIdentity
SERVICE_ACCOUNT_NAME 要创建或关联到托管标识的 Kubernetes 服务帐户的名称。 workload-identity-sa
SERVICE_ACCOUNT_NAMESPACE Kubernetes 服务帐户的命名空间。 default
FEDERATED_IDENTITY_NAME 要创建的联合标识凭据的名称。 myFederatedIdentity

选择迁移路径

根据当前的 Azure 标识 SDK 版本选择适当的迁移方法:

  • 最新 Azure 标识 SDK:如果应用程序已使用最新版本的 Azure 标识 SDK,可以通过部署与现有 Pod 托管标识并行部署 Microsoft Entra 工作负荷 ID 进行迁移。
  • 具有迁移 sidecar 的旧 SDK - 如果应用程序使用较旧的 SDK 版本并在 Linux 容器上运行,则可以在规划 SDK 升级时使用临时迁移 sidecar 来代理实例元数据服务(IMDS)事务。
  • 旧版 SDK 重写方法:如果应用程序使用较旧的 SDK 版本,则可以更新应用程序代码以使用最新的 Azure 标识 SDK,然后迁移到工作负荷标识。

准备迁移

对于所有迁移路径,需要在更新应用程序以使用 Microsoft Entra 工作负荷 ID 之前设置联合信任。 以下是所需的最少步骤:

从最新版本的 Azure 标识 SDK 迁移

此迁移路径适用于 应用程序已使用最新版本的 Azure 标识 SDK,并且你希望通过最少的代码更改进行迁移。

迁移方法:使用 Pod 托管标识并行部署 Microsoft Entra 工作负荷 ID,验证功能,然后删除 Pod 托管标识。

步骤:

  1. 与现有 Pod 托管标识并行部署Microsoft Entra 工作负荷 ID。
  2. 重启您的应用部署以开始使用 Microsoft Entra 工作负载 ID(OIDC 注释会自动注入)。
  3. 验证应用程序是否可以使用工作负荷标识成功进行身份验证。
  4. 从应用程序中删除 Pod 托管标识 注释。
  5. 从群集中删除 Pod 管理的标识附加组件。

仅适用于 Linux 容器的迁移旁车

当应用程序使用旧版 Azure 标识 SDK、在 Linux 容器上运行以及规划 SDK 更新时需要临时解决方案时,此迁移路径适用

迁移方法:部署一个将 IMDS 事务代理为 OIDC 的迁移辅组件,使现有应用程序代码无需立即更改即可运行。

重要限制

  • 仅限 Linux 容器。 不支持 Windows 容器。
  • 临时解决方案 不适用于长期生产用途。
  • 需要计划 如何安排 SDK 更新以实现长期支持。

步骤:

  1. 使用迁移 sidecar 将工作负载 部署以代理 IMDS 事务。
  2. 验证身份验证事务是否成功完成。
  3. 安排应用程序 SDK 更新以符合受支持的 Azure 身份版本。
  4. 更新 SDK 后,删除代理 sidecar 并重新部署应用程序。

为最新的 Azure 标识 SDK 重写应用程序

当应用程序使用旧版 Azure 标识 SDK,并且希望在迁移之前更新到最新支持的 SDK 时,此迁移路径适用

迁移方法:更新应用程序代码以使用最新的 Azure 标识 SDK,然后使用更新的代码迁移到 Microsoft Entra 工作负荷 ID。

技术成果

  • 使用当前的 Azure 标识 SDK 版本(无弃用时间线)。
  • 支持 Linux 和 Windows 容器(与 sidecar 方法不同)。
  • 消除代理组件和 IMDS 转换开销。

步骤:

  1. 更新应用程序代码以使用最新的 Azure 标识 SDK
  2. 使用 Pod 托管标识测试更新的应用程序。
  3. 重启应用程序部署,开始使用 Microsoft Entra 工作负荷 ID 进行身份验证(自动注入 OIDC 批注)。
  4. 验证身份验证事务是否成功完成。
  5. 删除 Pod 托管标识 注释和加载项。

设置活动的 Azure 订阅

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

    az account set --subscription $SUBSCRIPTION_ID
    

创建管理标识

  • 使用 az identity create 命令创建托管标识。

    az identity create --name $MANAGED_IDENTITY_NAME --resource-group $RESOURCE_GROUP --location $LOCATION --subscription $SUBSCRIPTION_ID
    

获取托管标识客户端 ID

  • 获取托管标识的客户端 ID,并使用命令将其保存到环境变量 az identity show

    export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group $RESOURCE_GROUP --name $MANAGED_IDENTITY_NAME --query 'clientId' -otsv)"
    

将对 Azure 资源的访问权限授予托管标识

获取 OIDC 颁发者 URL

  • 获取 OIDC 颁发者 URL,并使用命令将其保存到环境变量 az aks show

    export AKS_OIDC_ISSUER="$(az aks show --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --query "oidcIssuerProfile.issuerUrl" -o tsv)"
    

    该变量应包含类似于以下示例的颁发者 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/{uuid},其中的值 {region} 与部署 AKS 群集的位置匹配。 值 {uuid} 表示 OIDC 键。

获取 AKS 群集凭据

  • 使用 az aks get-credentials 命令获取 AKS 群集凭据。

    az aks get-credentials --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP
    

创建 Kubernetes 服务帐户

  • 创建 Kubernetes 服务帐户,并使用 kubectl apply 命令将托管标识客户端 ID 注解到该帐户上。 请确保将占位符值替换为自己的值。

    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_NAME --identity-name $MANAGED_IDENTITY_NAME --resource-group $RESOURCE_GROUP --issuer ${AKS_OIDC_ISSUER} --subject system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME} --audience api://AzureADTokenExchange
    

    添加后,联合标识凭据需要几分钟才能传播。 如果在添加联合标识凭据后立即发出令牌请求,令牌请求可能会失败,因为 Azure AD 目录缓存包含过时的信息。

借助迁移挎斗部署工作负载

如果应用程序使用用户分配的托管标识,但仍依赖于 IMDS 来获取访问令牌,则可以使用迁移辅助程序开始迁移到 Microsoft Entra Workload ID。 在长期应用程序中,应修改代码以使用支持客户端断言的最新 Azure 标识 SDK。

若要更新或部署工作负载,请将以下 pod 注释 添加到 pod 规范(仅当需要使用迁移 sidecar 时):

Pod 批注 Description 价值
azure.workload.identity/inject-proxy-sidecar 指示是否将代理 sidecar 注入 Pod。 truefalse
azure.workload.identity/proxy-sidecar-port 代理 sidecar 的所需端口。 默认值:8000

使用这些批注创建 Pod 时,Microsoft Entra Workload ID 变更 webhook 会自动将 init-container 和代理 sidecar 注入到 Pod 规范中。以下 YAML 演示了变更 webhook 添加到 Pod 部署的示例:

apiVersion: v1
kind: Pod
metadata:
  name: httpbin-pod
  labels:
    app: httpbin
    azure.workload.identity/use: "true"
  annotations:
    azure.workload.identity/inject-proxy-sidecar: "true"
spec:
  serviceAccountName: workload-identity-sa
  initContainers:
  - name: init-networking
    image: mcr.azk8s.cn/oss/azure/workload-identity/proxy-init:v1.1.0
    securityContext:
      capabilities:
        add:
        - NET_ADMIN
        drop:
        - ALL
      privileged: true
      runAsUser: 0
    env:
    - name: PROXY_PORT
      value: "8000"
  containers:
  - name: nginx
    image: nginx:alpine
    ports:
    - containerPort: 80
  - name: proxy
    image: mcr.azk8s.cn/oss/azure/workload-identity/proxy:v1.1.0
    ports:
    - containerPort: 8000

使用迁移 sidecar 验证工作负荷

  1. 使用 kubectl describe pod 命令验证 Pod 是否处于运行状态。 将 <pod-name> 替换为你的 Pod 的名称。

    kubectl describe pods <pod-name>
    
  2. 使用 kubectl logs 命令验证 Pod 是否在传递 IMDS 事务。 将 <pod-name> 替换为你的 Pod 的名称。

    kubectl logs <pod-name>
    

    以下示例日志输出类似于通过代理 sidecar 成功通信。 验证日志显示令牌已成功获取,并且 GET 操作成功。

    I0926 00:29:29.968723       1 proxy.go:97] proxy "msg"="starting the proxy server" "port"=8080 "userAgent"="azure-workload-identity/proxy/v0.13.0-12-gc8527f3 (linux/amd64) c8527f3/2022-09-26-00:19"
    I0926 00:29:29.972496       1 proxy.go:173] proxy "msg"="received readyz request" "method"="GET" "uri"="/readyz"
    I0926 00:29:30.936769       1 proxy.go:107] proxy "msg"="received token request" "method"="GET" "uri"="/metadata/identity/oauth2/token?resource=https://management.core.chinacloudapi.cn/api-version=2018-02-01&client_id=<client_id>"
    I0926 00:29:31.101998       1 proxy.go:129] proxy "msg"="successfully acquired token" "method"="GET" "uri"="/metadata/identity/oauth2/token?resource=https://management.core.chinacloudapi.cn/api-version=2018-02-01&client_id=<client_id>"
    

删除 Pod 托管标识

完成测试后,应用程序可以通过代理 sidecar 成功获取令牌,然后可以从 AKS 群集中删除身份和 pod 托管身份映射。

  • 使用 az aks pod-identity delete 命令从 Pod 中删除 Pod 管理的身份绑定。 将<pod-identity-name><pod-identity-namespace>替换为你的 pod 身份的名称和命名空间。

    az aks pod-identity delete --name <pod-identity-name> --namespace <pod-identity-namespace> --resource-group $RESOURCE_GROUP --cluster-name $CLUSTER_NAME
    

有关 Microsoft Entra 工作负荷 ID 的详细信息,请参阅 概述 文章。