从 Pod 托管标识迁移到工作负载标识

本文重点介绍如何将 Pod 托管标识迁移到 Azure Kubernetes 服务 (AKS) 群集的 Microsoft Entra Workload ID 工作负载标识。 本文还根据基于容器的应用程序使用的 Azure 标识客户端库版本提供相应的指南。

如果你不熟悉 Microsoft Entra Workload ID,请参阅下面的概述一文。

开始之前

Azure CLI 版本 2.47.0 或更高版本。 可通过运行 az --version 查找版本,运行 az upgrade 升级版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

迁移方案

本部分介绍可用的迁移选项,具体取决于已安装的 Azure 标识 SDK 版本。

无论那种方案,都需要先设置联合信任,再更新应用程序以使用工作负载标识。 以下是所需的最少步骤:

从最新版本迁移

如果应用程序已使用最新版本的 Azure 标识 SDK,请执行以下步骤来完成身份验证配置:

  • 将工作负载标识与 Pod 托管标识并行部署。 可以重启应用程序部署以开始使用工作负载标识,这样能将 OIDC 注释自动注入到应用程序中。
  • 确认应用程序能成功进行验证后,即可从应用程序中删除 Pod 托管标识注释,然后删除 Pod 托管标识附加组件。

从旧版本迁移

如果应用程序未使用最新版本的 Azure 标识 SDK,那么有两种选择:

  • 可以使用我们在你的 Linux 应用程序中提供的迁移挎斗,它可以将应用程序产生的 IMDS 事务代理到 OpenID Connect (OIDC)。 迁移挎斗不旨在用作长期解决方案,而是一种快速启动和运行工作负载标识的方式。 执行以下步骤:

    • 借助迁移挎斗部署工作负载,以代理应用程序 IMDS 事务。
    • 验证身份验证事务是否已成功完成。
    • 计划应用程序的工作,以便将 SDK 更新到受支持的版本。
    • 在 SDK 更新到受支持的版本后,你可以删除代理挎斗并重新部署应用程序。

    注意

    生产使用不支持迁移挎斗。 此功能旨在让你有时间将应用程序 SDK 迁移到受支持的版本,但并不有意成为一种长期解决方案。 迁移挎斗仅适用于 Linux 容器,因为仅通过 Linux 节点池提供 Pod 托管标识。

  • 重新编写应用程序,以支持最新版本的 Azure 标识客户端库。 然后,请执行以下步骤:

    • 重启应用程序部署以开始使用工作负载标识进行身份验证。
    • 确认身份验证事务已成功完成后,即可从应用程序中删除 Pod 托管标识注释,然后删除 Pod 托管标识附加组件。

创建托管标识

如果未创建托管标识并将其分配给 Pod,请执行以下步骤来创建存储、密钥保管库或应用程序在 Azure 中进行身份验证所需的任何资源并授予必要的权限。

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

    az account set --subscription "subscriptionID"
    
    az identity create --name "userAssignedIdentityName" --resource-group "resourceGroupName" --location "location" --subscription "subscriptionID"
    
    export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "resourceGroupName" --name "userAssignedIdentityName" --query 'clientId' -otsv)"
    
  2. 向托管标识授予访问 Azure 中所需资源所需的权限。 有关如何并行部署的信息,请参阅分配对资源的托管标识访问权限

  3. 若要获取 OIDC 颁发者 URL 并将其保存到环境变量,请运行以下命令。 替换群集名称和资源组名称的默认值。

    export AKS_OIDC_ISSUER="$(az aks show -n myAKSCluster -g myResourceGroup --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/{uuid},其中 {region} 的值与部署 AKS 群集的位置相匹配。 值 {uuid} 表示 OIDC 键。

创建 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 命令在托管标识、服务帐户颁发者和使用者之间创建联合标识凭据。 替换值 resourceGroupNameuserAssignedIdentityNamefederatedIdentityNameserviceAccountNamespaceserviceAccountName

az identity federated-credential create --name federatedIdentityName --identity-name userAssignedIdentityName --resource-group resourceGroupName --issuer ${AKS_OIDC_ISSUER} --subject system:serviceaccount:${SERVICE_ACCOUNT_NAMESPACE}:${SERVICE_ACCOUNT_NAME} --audience api://AzureADTokenExchange

注意

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

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

注意

生产使用不支持迁移挎斗。 此功能旨在让你有时间将应用程序 SDK 迁移到受支持的版本,但并不有意成为一种长期解决方案。 迁移挎斗仅适用于 Linux 容器,因为 Pod 托管标识仅在 Linux 节点池上可用。

如果应用程序使用托管标识,并且仍依赖 IMDS 获取访问令牌,则可以使用工作负载标识迁移 sidecar 开始迁移到工作负载标识。 此 sidecar 是一种迁移解决方案,在长期应用程序中,应修改其代码以使用支持客户端断言的最新 Azure 标识 SDK。

若要更新或部署工作负载,请仅在要使用迁移 sidecar 时才添加这些 Pod 注释。 注入以下注释值以在 Pod 规范中使用 sidecar:

  • azure.workload.identity/inject-proxy-sidecar - 值为 truefalse
  • azure.workload.identity/proxy-sidecar-port - 值是代理 sidecar 的所需端口。 默认值是 8000

创建具有上述注释的 Pod 时,Azure 工作负载标识更改 Webhook 会自动将初始化容器和代理 sidecar 注入 Pod 规范。

已在运行的 Webhook 会将以下 YAML 代码片段添加到 Pod 部署中。 以下是已更改 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

此配置适用于正在创建 Pod 的任何配置。 更新或部署应用程序后,可以使用 kubectl describe pod 命令验证 Pod 是否处于运行状态。 将值 podName 替换为已部署 Pod 的映像名称。

kubectl describe pods podName

若要验证 Pod 是否正在传递 IMDS 事务,请使用 kubectl logs 命令。 将值 podName 替换为已部署 Pod 的映像名称:

kubectl logs podName

以下日志输出类似于通过代理 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 成功获取令牌后,可以从群集中删除 Pod 的 Microsoft Entra Pod 托管标识映射,然后删除该标识。

  1. 运行 az aks Pod-identity delete 命令以从 Pod 中删除标识。 只有在使用 Pod 托管标识映射的命名空间中的所有 Pod 都已迁移到使用 sidecar 之后,才应执行此操作。

    az aks pod-identity delete --name podIdentityName --namespace podIdentityNamespace --resource-group myResourceGroup --cluster-name myAKSCluster
    

后续步骤

本文介绍了如何将 Pod 设置为使用工作负载标识作为迁移选项进行身份验证。 有关 Microsoft Entra Workload ID 联合身份验证的详细信息,请参阅以下概述一文。