选项 1:在 EKS 集群上启用 EKS 容器组身份 - Amazon EMR
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

选项 1:在 EKS 集群上启用 EKS 容器组身份

Amazon EKS 容器组身份关联提供管理应用程序凭证的功能,类似于 Amazon EC2 实例配置文件为 Amazon EC2 实例提供凭证的方式。Amazon EKS 容器组身份通过额外的 EKS Auth API,以及在每个节点上运行的代理容器组为您的工作负载提供凭证。

自 emr-7.3.0 版本起,Amazon EMR on EKS 开始对 StartJobRun 提交模型支持 EKS 容器组身份。

有关 EKS 容器组身份的更多信息,请参阅了解 EKS 容器组身份的工作原理

为什么需要 EKS 容器组身份?

作为 EMR 设置的一部分,作业执行角色需要在特定命名空间(EMR 虚拟集群)中的 IAM 角色和服务账户之间建立信任边界。在 IRSA 中,这是通过更新 EMR 作业执行角色的信任策略来实现的。然而,由于 IAM 信任策略长度有 4096 个字符的硬性限制,因此最多只能在十二 (12) 个 EKS 集群中共享一个作业执行 IAM 角色。

借助 EMR 对容器组身份的支持,IAM 角色和服务账户之间的信任边界现在由 EKS 团队通过 EKS 容器组身份的关联 API 进行管理。

注意

EKS 容器组身份的安全边界仍处于服务账户级别,而不是容器组级别。

容器组身份注意事项

有关容器组身份限制的信息,请参阅 EKS 容器组身份注意事项

在 EKS 集群中准备 EKS 容器组身份

检查 NodeInstanceRole 中是否存在所需的权限

节点角色 NodeInstanceRole 需要让代理在 EKS Auth API 中执行 AssumeRoleForPodIdentity 操作的权限。您可以将以下内容添加到 AmazonEKSWorkerNodePolicy(在《Amazon EKS 用户指南》中定义),也可以使用自定义策略。

如果您的 EKS 集群是使用高于 0.181.0 的 eksctl 版本创建的,则 AmazonEKSWorkerNodePolicy(包括所需的 AssumeRoleForPodIdentity 权限)将自动附加到节点角色。如果权限不存在,请手动将以下权限添加到 AmazonEKSWorkerNodePolicy 中,以允许代入容器组身份的角色。EKS 容器组身份代理需要此权限才能检索容器组的凭证。

JSON
{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks-auth:AssumeRoleForPodIdentity" ], "Resource": [ "*" ], "Sid": "AllowEKSAUTHAssumeroleforpodidentity" } ] }

创建 EKS 容器组身份代理附加组件

使用以下命令通过最新版本创建 EKS 容器组身份代理附加组件:

aws eks create-addon --cluster-name cluster-name --addon-name eks-pod-identity-agent kubectl get pods -n kube-system | grep 'eks-pod-identity-agent'

使用以下步骤从 Amazon EKS 控制台创建 EKS 容器组身份代理附加组件:

  1. 打开 Amazon EKS 控制台:Amazon EKS 控制台

  2. 在左侧导航窗格中,选择集群,然后为您要配置 EKS 容器组身份代理插件的集群选择集群名称。

  3. 选择附加组件选项卡。

  4. 选择获取更多附加组件

  5. 选择 EKS 容器组身份代理插件框右上角的框,然后选择下一步

  6. 配置选定的附加组件设置页面上,从版本下拉列表中选择任意版本。

  7. (可选)展开可选配置设置以输入其他配置。例如,您可以提供备用容器映像位置和 ImagePullSecrets。带有已接受键的 JSON 架构显示在附加组件配置架构中。

    配置值中输入配置键和值。

  8. 选择下一步

  9. 通过 CLI 确认代理容器组是否在您的集群上运行。

    kubectl get pods -n kube-system | grep 'eks-pod-identity-agent'

示例输出如下所示:

NAME READY STATUS RESTARTS AGE eks-pod-identity-agent-gmqp7 1/1 Running 1 (24h ago) 24h eks-pod-identity-agent-prnsh 1/1 Running 1 (24h ago) 24h

这将在 kube-system 命名空间中创建一个新的 DaemonSet。每个 EKS 节点运行上的 Amazon EKS 容器组身份代理使用 AssumeRoleForPodIdentity 操作从 EKS Auth API 检索临时凭证。然后,这些凭证可供您在容器内运行的 Amazon SDK 使用。

有关更多信息,请查看公共文档中的先决条件:设置 Amazon EKS 容器组身份代理

创建作业执行角色

创建或更新允许 EKS 容器组身份的作业执行角色

要使用 Amazon EMR on EKS 运行工作负载,您需要创建一个 IAM 角色。我们在本文档中将此角色称为任务执行角色。有关如何创建 IAM 角色的更多信息,请参阅用户指南中的创建 IAM 角色

此外,您必须创建一个 IAM 策略来指定作业执行角色所需的权限,然后将此策略附加到该角色以启用 EKS 容器组身份。

例如,您拥有以下作业执行角色。有关更多信息,请参阅创建作业执行角色

arn:aws:iam::111122223333:role/PodIdentityJobExecutionRole
重要

Amazon EMR on EKS 会根据您的作业执行角色名称自动创建 Kubernetes 服务账户。确保角色名称不要太长,因为如果 cluster_namepod_nameservice_account_name 的组合超过长度限制,您的作业可能会失败。

作业执行角色配置 – 确保使用以下 EKS 容器组身份的信任权限创建作业执行角色。要更新现有作业执行角色,请将其配置为信任以下 EKS 服务主体,作为信任策略中的附加权限。此信任权限可与现有 IRSA 信任策略共存。

cat >trust-relationship.json <<EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowEksAuthToAssumeRoleForPodIdentity", "Effect": "Allow", "Principal": { "Service": "pods.eks.amazonaws.com" }, "Action": [ "sts:AssumeRole", "sts:TagSession" ] } ] } EOF

用户权限:用户需要 iam:PassRole 权限才能执行 StartJobRun API 调用或提交作业。此权限使用户能够将作业执行角色传递给 EMR on EKS。默认情况下,作业管理员应拥有该权限。

以下是用户所需的权限:

{ "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::111122223333:role/PodIdentityJobExecutionRole", "Condition": { "StringEquals": { "iam:PassedToService": "pods.eks.amazonaws.com" } } }

要进一步限制用户对特定 EKS 集群的访问,请将 AssociatedResourceArn 属性筛选条件添加到 IAM 策略中。它将角色代入限制为已授权的 EKS 集群,从而加强资源级安全控制。

"Condition": { "ArnLike": { "iam:AssociatedResourceARN": [ "arn:aws:eks:us-west-2:111122223333:cluster/*" ] }

设置 EKS 容器组身份关联

先决条件

确保创建容器组身份关联的 IAM 身份(例如 EKS 管理员用户)拥有 eks:CreatePodIdentityAssociationiam:PassRole 权限。

JSON
{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks:CreatePodIdentityAssociation" ], "Resource": [ "arn:aws:eks:*:*:cluster/*" ], "Sid": "AllowEKSCreatepodidentityassociation" }, { "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": [ "arn:aws:iam::*:role/*" ], "Condition": { "StringEquals": { "iam:PassedToService": "pods.eks.amazonaws.com" } }, "Sid": "AllowIAMPassrole" } ] }

为角色和 EMR 服务账户创建关联

Create EMR role associations through the Amazon CLI

当您向 Kubernetes 命名空间提交作业时,管理员必须在作业执行角色和 EMR 托管服务账户的身份之间创建关联。请注意,EMR 托管式服务账户将在任务提交时自动创建,作用域为提交任务的命名空间。

使用 Amazon CLI(2.24.0 以上版本),请运行以下命令来创建与容器组身份的角色关联。

运行以下命令来创建角色与容器组身份的关联:

aws emr-containers create-role-associations \ --cluster-name mycluster \ --namespace mynamespace \ --role-name JobExecutionRoleIRSAv2

注意:

  • 每个集群最多可以有 1,000 个关联。每个作业执行角色与命名空间映射对作业提交者、驱动程序和执行程序容器组需要 3 个关联。

  • 只能关联与集群属于同一 Amazon 账户的角色。您可以将其他账户访问权限委派给此账户中的角色,也即您配置的供 EKS 容器组身份使用的角色。有关委派访问和 AssumeRole 的教程,请参阅 IAM 教程:使用 IAM 角色委派跨 Amazon 账户的访问权限

Create EMR role associations through Amazon EKS

提交作业时,EMR 会创建具有特定命名模式的服务账户。要进行手动关联或将此工作流与 Amazon SDK 集成,请按照以下步骤操作:

构造服务账户名称:

emr-containers-sa-spark-%(SPARK_ROLE)s-%(AWS_ACCOUNT_ID)s-%(BASE36_ENCODED_ROLE_NAME)s

以下示例为示例作业执行角色 JobExecutionRoleIRSAv2 创建角色关联。

角色关联示例:

RoleName: JobExecutionRoleIRSAv2 Base36EncodingOfRoleName: 2eum5fah1jc1kwyjc19ikdhdkdegh1n26vbe

示例 CLI 命令

# setup for the client service account (used by job runner pod) # emr-containers-sa-spark-client-111122223333-2eum5fah1jc1kwyjc19ikdhdkdegh1n26vbe aws eks create-pod-identity-association --cluster-name mycluster --role-arn arn:aws:iam::111122223333:role/JobExecutionRoleIRSAv2 --namespace mynamespace --service-account emr-containers-sa-spark-client-111122223333-2eum5fah1jc1kwyjc19ikdhdkdegh1n26vbe # driver service account # emr-containers-sa-spark-driver-111122223333-2eum5fah1jc1kwyjc19ikdhdkdegh1n26vbe aws eks create-pod-identity-association --cluster-name mycluster --role-arn arn:aws:iam::111122223333:role/JobExecutionRoleIRSAv2 --namespace mynamespace --service-account emr-containers-sa-spark-driver-111122223333-2eum5fah1jc1kwyjc19ikdhdkdegh1n26vbe # executor service account # emr-containers-sa-spark-executor-111122223333-2eum5fah1jc1kwyjc19ikdhdkdegh1n26vbe aws eks create-pod-identity-association --cluster-name mycluster --role-arn arn:aws:iam::111122223333:role/JobExecutionRoleIRSAv2 --namespace mynamespace --service-account emr-containers-sa-spark-executor-111122223333-2eum5fah1jc1kwyjc19ikdhdkdegh1n26vbe

完成 EKS 容器组身份所需的所有步骤后,您可以为 IRSA 设置跳过以下步骤:

您可以直接跳到以下步骤:授予用户访问 Amazon EMR on EKS 的权限

删除角色关联

每当您删除虚拟集群或作业执行角色,并且不再希望其服务账户访问 EMR 时,您应该删除该角色的关联。这是因为 EKS 允许与不存在的资源(命名空间和服务账户)建立关联。Amazon EMR on EKS 建议,如果命名空间被删除或角色不再使用,则删除关联以便为其他关联释放空间。

注意

如果不删除残留关联,它们可能会影响您的扩展能力,因为 EKS 对您可以创建的关联数量有限制(软限制:每个集群 1000 个关联)。您可以列出给定命名空间中的容器组身份关联,以检查是否存在任何需要清理的残留关联:

aws eks list-pod-identity-associations --cluster-name mycluster --namespace mynamespace

使用 Amazon CLI(版本 2.24.0 或更高版本),运行以下 emr-containers 命令来删除 EMR 的角色关联:

aws emr-containers delete-role-associations \ --cluster-name mycluster \ --namespace mynamespace \ --role-name JobExecutionRoleIRSAv2

自动将现有 IRSA 迁移到容器组身份

您可以使用 eksctl 工具将现有的 IAM 服务账户角色 (IRSA) 迁移到容器组身份关联:

eksctl utils migrate-to-pod-identity \ --cluster mycluster \ --remove-oidc-provider-trust-relationship \ --approve

运行不带 --approve 标志的命令只会输出反映迁移步骤的计划,不会进行实际迁移。

故障排除

我的作业因凭证提供程序出现 NoClassDefinitionFound 或 ClassNotFound 异常而失败,或者无法获取凭证提供程序。

EKS 容器组身份使用容器凭证提供程序来检索必要的凭证。如果您指定了自定义凭证提供程序,请确保其正常工作。或者,请确保您使用的是支持 EKS 容器组身份的正确 Amazon SDK 版本。有关更多信息,请参阅 Amazon EKS 入门

作业失败,eks-pod-identity-agent 日志中显示“由于 [x] 大小限制,无法检索凭证”错误。

EMR on EKS 会根据作业执行角色名称创建 Kubernetes 服务账户。如果角色名称过长,EKS Auth 将无法检索凭证,因为 cluster_namepod_nameservice_account_name 的组合超过了长度限制。识别占用空间最多的组件,并相应地调整其大小。

作业失败,eks-pod-identity 日志中显示“无法检索凭证 xxx”错误。

造成此问题的一个可能原因是 EKS 集群配置在私有子网下,但没有为集群正确配置 PrivateLink。检查您的集群是否位于私有网络中,并配置 Amazon PrivateLink 以解决该问题。有关详细说明,请参阅 Amazon EKS 入门