- 云原生
- 容器编排
- DevOps
【免费下载链接】eksctl
The official CLI for Amazon EKS
导读
eksctlv0.166.0(发布说明)为utils命令族新增了migrate-to-pod-identity子命令(PR #7343),用于把集群中所有基于 IRSAv1(即 iamserviceaccounts + IAM OIDC Provider)的配置自动转换为等价的 Pod Identity Associations 配置。本文将围绕该命令展开:先梳理 IRSA 与 EKS Pod Identity 的差异与迁移动机,再给出命令用法、关键参数与安全前提,然后深入pkg/actions/podidentityassociation源码逐层拆解迁移器生成的每个任务,最后结合测试用例给出验证与回退建议,帮助你在真实集群上安全、可控地完成这一迁移。
为什么需要迁移:IRSA 与 EKS Pod Identity 的本质差异
EKS Pod Identity Associations 是 AWS 推出的增强机制,用于让集群管理员为 Kubernetes 应用配置访问 AWS 服务的 IAM 权限。它与 IRSA(IAM Roles for Service Accounts)共享同一套"用 ServiceAccount 绑定 IAM 角色"的思路,但关键区别在于配置入口从 IAM API 转移到了 EKS API(见 userdocs/src/usage/pod-identity-associations.md):
- IRSA(IRSAv1):IAM 角色的信任策略必须引用集群的 OIDC Provider(
FederatedPrincipal +oidc.eks.<region>.amazonaws.com/id/<id>:sub条件),角色与单个集群强绑定;ServiceAccount 上需要eks.amazonaws.com/role-arn注解(常量定义见 pkg/apis/eksctl.io/v1alpha5/iam.go)。 - Pod Identity:角色信任
pods.eks.amazonaws.com这一 EKS 服务主体(见 pkg/apis/eksctl.io/v1alpha5/iam.go),不再依赖 OIDC Provider,因此同一个 IAM 角色可以跨多个 EKS 集群复用,免去角色重复创建和每建一个新集群都要改写信任策略的负担,也简化了 IRSA 的自动化流程。
迁移的收益即来源于此:把绑定单集群的 OIDC 信任关系替换为跨集群通用的 EKS 服务主体信任,同时把 ServiceAccount 的"注解式"授权改为 EKS API 原生管理的 Pod Identity Association。
前置条件
在运行迁移命令前,需要确认:
- Pod Identity Agent 已就绪:Pod Identity 在 worker 节点上以 DaemonSet 形式运行 agent,对应的官方 addon 是
eks-pod-identity-agent。若集群已启用 EKS Auto Mode,该 agent 会随集群预装,无需额外操作;否则可先用以下命令安装(usage 文档):
eksctl create addon --cluster my-cluster --name eks-pod-identity-agent- 预先存在的 IAM 角色需要信任 EKS 服务主体:如果 Pod Identity Association 使用的是已有的 IAM 角色,该角色的信任策略必须允许
pods.eks.amazonaws.com执行sts:AssumeRole与sts:TagSession。示例信任策略(来自 usage 文档):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "pods.eks.amazonaws.com" }, "Action": [ "sts:AssumeRole", "sts:TagSession" ] } ] }如果不在配置中提供既有角色的 ARN,eksctl会在创建 Pod Identity Association 时自动创建角色并配置上述信任策略。好消息是:migrate-to-pod-identity命令会自动完成信任策略改写(详见下文"迁移任务拆解"),无需手工处理。
命令用法与参数
命令通过utils子命令注册(注册点见 pkg/ctl/utils/utils.go):
eksctl utils migrate-to-pod-identity --cluster <cluster-name> [--region <region>] [--approve] [--remove-oidc-provider-trust-relationship] [--timeout <duration>]命令描述(源码见 pkg/ctl/utils/migrate_to_pod_identity.go):
Migrates all IRSA related config for a cluster to an equivalent pod identity associations config
参数说明:
| 参数 | 默认值 | 作用 |
|---|---|---|
--cluster | 必填 | 集群名称,缺失时命令会报ErrMustBeSet错误(见 migrate_to_pod_identity.go) |
--region | 默认区域 | 集群所在区域 |
--approve | false | 是否真正执行变更。默认false时以Plan 模式运行,仅打印将要执行的任务清单(PlanMode: !options.Approve,见 migrator.go) |
--remove-oidc-provider-trust-relationship | false | 是否同时移除现有 IRSA 角色信任策略中的 OIDC Provider 实体,并删除 ServiceAccount 上的eks.amazonaws.com/role-arn注解;不指定则保留原信任关系(双轨并存,风险更小) |
--timeout | 由 cmdutils 提供默认值 | 安装 addon 等任务的等待超时时间 |
命令的完整调用链(migrate_to_pod_identity.go)依次执行:
- 校验集群名称;创建 AWS Provider 并验证集群可操作(
ctl.CanOperate); - 通过
NewOpenIDConnectManager检查集群是否关联了 IAM OIDC Provider——如果集群没有 OIDC Provider,说明没有 iamserviceaccount 需要迁移,命令直接告警并退出(logger.Warning("no IAM OIDC provider associated with cluster...")); - 建立 Kubernetes 客户端(
NewStdClientSet)读取 ServiceAccount; - 初始化 addon 管理器(
addon.New)与 CloudFormation Stack 管理器(NewStackManager); - 组装
podidentityassociation.NewMigrator(...)并调用MigrateToPodIdentity(ctx, options)。
迁移任务拆解:源码视角的完整流程
Migrator.MigrateToPodIdentity(pkg/actions/podidentityassociation/migrator.go)把所有操作组织成一颗串行任务树(Parallel: false),每个迁移对象内部再并行执行子任务。整体分四个阶段:
阶段一:确保 Pod Identity Agent 已安装
IsPodIdentityAgentInstalled(migrator.go)先检查集群是否处于 Auto Mode(IsAutoModeEnabled,通过DescribeCluster读取ComputeConfig.Enabled);若不是 Auto Mode,则调用DescribeAddon查询eks-pod-identity-agent(常量见 pkg/apis/eksctl.io/v1alpha5/addon.go)。若 addon 不存在,任务树会追加一个任务:install eks-pod-identity-agent addon,通过addonCreator.Create完成安装。
阶段二:扫描 IRSA 配置(iamserviceaccount + ServiceAccount)
IRSAv1StackNameResolver.Populate(migrator.go)通过stackUpdater.GetIAMServiceAccounts(ctx, "", "")拉取所有由 eksctl CloudFormation 管理的 iamserviceaccount 及其 RoleARN、StackName、Tags、Capabilities,构建"RoleARN → IRSAv1StackSummary"映射;- 遍历 Kubernetes 集群中的全部 ServiceAccount,找出带
eks.amazonaws.com/role-arn注解的对象(migrator.go):- 通过
CreateAddonServiceAccountRoleMapper(addon_role_mapper.go)分页列出全部 EKS addon,将 addon 的ServiceAccountRoleArn映射到 addon 本身;若某 ServiceAccount 的角色 ARN 已被某个 addon 使用,则该角色不按普通 iamserviceaccount 处理,改由 AddonMigrator 专门迁移; - 其余角色被收集进
toBeCreated(待创建的PodIdentityAssociation列表),并从 ARN 推断角色名(api.RoleNameFromARN); - 按角色是否由 eksctl Stack 管理(
resolver.GetStack(roleARN)),分别生成"owned role"或"unowned role"的信任策略更新任务。
- 通过
阶段三:迁移 EKS 托管 Addon(AddonMigrator)
AddonMigrator.Migrate(addon_migrator.go)对每个"使用 IRSAv1 角色"的 addon 执行migrateAddon:
- 若 addon 已配置
PodIdentityAssociations,直接跳过; - 调用
DescribeAddonConfiguration检查该 addon 版本是否支持 Pod Identity(len(addonConfig.PodIdentityConfiguration) == 0则跳过); - 解析角色的信任策略(
getRoleServiceAccount,addon_migrator.go),从StringEquals条件中提取形如system:serviceaccount:<ns>:<name>的 ServiceAccount 主体;若提取失败且 addon 只支持一个 ServiceAccount,则使用 addon 配置中声明的默认 ServiceAccount; - 生成两个串行子任务:
- 更新该角色的信任策略(owned 角色走 CloudFormation Stack 更新,unowned 角色走
UpdateAssumeRolePolicy,此处固定传入removeOIDCProviderTrustRelationship=true); updateAddonToUsePodIdentity(addon_migrator.go):调用UpdateAddon,在PodIdentityAssociations字段中填入原ServiceAccountRoleArn与解析出的 ServiceAccount。
- 更新该角色的信任策略(owned 角色走 CloudFormation Stack 更新,unowned 角色走
阶段四:迁移 iamserviceaccount(并行任务组)
每个待迁移的 ServiceAccount 生成一个独立子任务组(Parallel: true,见 migrator.go),按序执行:
- 更新信任策略:
trustPolicyUpdater.UpdateTrustPolicyForOwnedRoleTask/UpdateTrustPolicyForUnownedRoleTask(tasks.go)——先GetRole读取现有 AssumeRolePolicyDocument,updateTrustStatements(tasks.go)做两件事:若指定了--remove-oidc-provider-trust-relationship,则删除 Principal 为Federated且指向oidc-provider的语句;随后追加api.EKSServicePrincipalTrustStatement(Service: pods.eks.amazonaws.com+sts:AssumeRole/sts:TagSession)。- owned 角色:更新 CloudFormation 模板中
AWS::IAM::Role的 AssumeRolePolicyDocument,同时更新 Stack Tags——移除eksctl-iamserviceaccount-name标签(若指定移除信任关系),并打上alpha.eksctl.io/podidentityassociation-name标签(标签常量见 pkg/apis/eksctl.io/v1alpha5/types.go),保留原 Capabilities(如CAPABILITY_IAM)后通过MustUpdateStack应用变更; - unowned 角色:直接调用 IAM
UpdateAssumeRolePolicy写入新的信任策略文档。
- owned 角色:更新 CloudFormation 模板中
- 移除注解(仅当
--remove-oidc-provider-trust-relationship为 true):删除 ServiceAccount 上的eks.amazonaws.com/role-arn注解并Update回 Kubernetes。 - 创建 Pod Identity Association:
NewCreator(...).CreateTasks(ctx, toBeCreated, true),内部调用 EKSCreatePodIdentityAssociation,传入Namespace、RoleARN、ServiceAccount、Tags 以及可选的DisableSessionTags、Policy、TargetRoleArn(跨账户角色链,见 tasks.go);若ignorePodIdentityExistsErr且目标已存在(ResourceInUseException),则跳过并提示。
全部任务执行前,命令会通过cmdutils.LogIntendedAction打印摘要:
migrate N iamserviceaccount(s) and M addon(s) to pod identity by executing the following tasks若没有任何 iamserviceaccount 或 addon 可迁移,则打印no iamserviceaccounts or addons found to migrate to pod identity并直接返回(migrator.go)。
关键参数详解与推荐迁移策略
关于--remove-oidc-provider-trust-relationship
该参数控制迁移的彻底程度:
- 不指定(推荐首轮执行):只做"加法"——为角色追加
pods.eks.amazonaws.com信任语句、创建 Pod Identity Association、安装 agent。OIDC 信任关系与 ServiceAccount 注解原样保留,IRSAv1 与 Pod Identity 双轨并存。此时 Pod 若通过注解注入凭证仍可工作,适合灰度验证。 - 指定该参数:在上一基础上执行"减法"——删除角色信任策略中的 OIDC Provider Federated 语句、删除 ServiceAccount 注解,并更新 Stack 标签以反映 IRSAv2 化。迁移完成后集群将不再依赖 IAM OIDC Provider 提供 pod 凭证。
建议流程:先用默认(Plan 模式)查看任务清单 → 不加该参数--approve执行,验证应用正常 → 确认无误后再加--remove-oidc-provider-trust-relationship --approve完成收尾清理。
关于--approve
迁移器把任务树置于PlanMode(PlanMode: !options.Approve),未指定--approve时任务只做规划与打印,不触发任何实际变更(cmdutils.LogPlanModeWarning会输出 Plan 模式提示)。这与 eksctl 一贯的--dry-run心智一致,务必先预览再批准。
迁移后的验证
迁移完成后,可用以下命令确认 Pod Identity Association 已生效(命令及输出格式见 usage 文档):
# 查看全部关联 eksctl get podidentityassociation --cluster my-cluster # 按命名空间过滤 eksctl get podidentityassociation --cluster my-cluster --namespace dev同时可检查对应 ServiceAccount 上是否已无eks.amazonaws.com/role-arn注解,以及 IAM 角色信任策略是否已包含pods.eks.amazonaws.com主体。
测试与可靠性保障
该功能的测试覆盖在 pkg/actions/podidentityassociation/migrator_test.go 中,使用 Ginkgo 表格驱动 + mockprovider + fake Clientset 验证了多个关键分支:
- API 错误路径:
DescribeAddon失败、GetIAMServiceAccounts失败均返回明确错误(migrator_test.go); - agent 安装任务:addon 未安装时任务树包含
install eks-pod-identity-agent addon;Auto Mode 下(ComputeConfig.Enabled=true)或ComputeConfig为 nil 时行为正确(migrator_test.go); - 注解移除任务:指定
RemoveOIDCProviderTrustRelationship时输出remove iamserviceaccount EKS role annotation for "default/service-account-1"(migrator_test.go); - owned / unowned 角色分支:owned 角色生成
update trust policy for owned role,unowned 角色生成update trust policy for unowned role,两者均生成create pod identity association任务(migrator_test.go); - 端到端成功:验证最终信任策略只包含
Service: pods.eks.amazonaws.com主体、Stack 标签仅保留alpha.eksctl.io/podidentityassociation-name、模板不再包含oidc(migrator_test.go)。
此外 0.166.0 还修复了build-integration-test for pod_identity_associations(PR #7336)与STS interface(PR #7345),保证迁移链路依赖的接口定义正确。
补充:以配置文件方式管理 Pod Identity
migrate-to-pod-identity是一次性的存量迁移工具;日常的声明式管理仍通过集群配置文件中的iam.podIdentityAssociations字段完成(字段定义见 pkg/apis/eksctl.io/v1alpha5/iam.go,完整示例见 examples/39-pod-identity-association.yaml):
iam: podIdentityAssociations: - namespace: default serviceAccountName: s3-reader createServiceAccount: true # 可选,默认 false roleARN: arn:aws:iam::111122223333:role/role-1 # 提供 roleARN 时仅创建关联 - namespace: dev serviceAccountName: app-cache-access roleName: pod-identity-role-app-cache # 不提供 roleARN 时由 eksctl 创建角色 permissionPolicyARNs: ["arn:aws:iam::111122223333:policy/permission-policy-1"] wellKnownPolicies: autoScaler: true permissionsBoundaryARN: arn:aws:iam::111122223333:policy/permission-boundary配套命令:
# 创建(集群创建时在 config.yaml 声明后直接生效,或对已有集群) eksctl create podidentityassociation --cluster my-cluster -f config.yaml # 更新 / 删除 eksctl update podidentityassociation --cluster my-cluster -f config.yaml eksctl delete podidentityassociation --cluster my-cluster -f config.yaml注意:eksctl create cluster -f config.yaml使用iam.podIdentityAssociations时,校验逻辑要求集群同时安装eks-pod-identity-agentaddon(见 pkg/apis/eksctl.io/v1alpha5/validation.go 与 validation.go)。
总结
eksctl utils migrate-to-pod-identity把"IRSA 迁移到 Pod Identity"这一原本需要手工修改角色信任策略、逐个创建 EKS API 关联、清理注解的复杂过程,收敛为一条可预览、可灰度、可回滚(默认保留 OIDC 信任关系)的命令。其底层由一颗结构化的任务树驱动,覆盖 agent 安装、iamserviceaccount 扫描、addon 专用迁移、owned/unowned 角色信任策略差异化处理与 Pod Identity Association 创建,并通过 migrator_test.go 对关键分支做了充分验证。对正在批量使用 iamserviceaccount 的集群而言,这是向 EKS 官方推荐的 Pod Identity 机制平滑演进的最佳起点。
- 云原生
- 容器编排
- DevOps
【免费下载链接】eksctl
The official CLI for Amazon EKS
相关推荐
eksctl 0.165.0 核心特性:EKS Pod Identity Associations 配置与迁移实战指南
eksctl 0.165.0 核心特性:EKS Pod Identity Associations 配置与迁移实战指南 本指南以 eksctl v0.165.0
云原生容器编排DevOpsAmazon EKS Pod Identity Webhook 使用教程
Amazon EKS Pod Identity Webhook 使用教程 1. 项目介绍 Amazon EKS Pod Identity Webhook 是一个
Amazon EKS Pod Identity Webhook:简化IAM角色与Pod的集成
Amazon EKS Pod Identity Webhook:简化IAM角色与Pod的集成 项目介绍 Amazon EKS Pod Identity Webh
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考