

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 选项 1：在 EKS 集群上启用 EKS 容器组身份
<a name="setting-up-enable-IAM"></a>

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

自 emr-7.3.0 发布提交模型以来，EKS 上的 Amazon EMR 开始支持 EKS 容器身份。 StartJobRun 

有关 EKS 容器组身份的更多信息，请参阅[了解 EKS 容器组身份的工作原理](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-how-it-works.html)。

## 为什么需要 EKS 容器组身份？
<a name="setting-up-enable-IAM-pod-identity-why"></a>

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

由于 EMR 对 Pod 身份的支持，IAM 角色和服务账户之间的信任边界现在由 EKS 团队通过 EKS pod 身份的关联 APIs进行管理。

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

## 容器组身份注意事项
<a name="setting-up-enable-IAM-pod-identity-consider"></a>

有关容器组身份限制的信息，请参阅 [EKS 容器组身份注意事项](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html#pod-id-considerations)。

## 在 EKS 集群中准备 EKS 容器组身份
<a name="setting-up-enable-IAM-pod-eks-cluster"></a>

### 检查所需权限是否存在于 NodeInstanceRole
<a name="setting-up-enable-IAM-pod-eks-cluster-permission"></a>

节点角色 `NodeInstanceRole` 需要让代理在 EKS Auth API 中执行 `AssumeRoleForPodIdentity` 操作的权限。您可以将以下内容添加到 [Amazon EKSWorker NodePolicy](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/security-iam-awsmanpol.html#security-iam-awsmanpol-amazoneksworkernodepolicy)（在 Amazon EKS 用户指南中定义），也可以使用自定义策略。

如果您的 EKS 集群是使用高于 **0.181.0** 的 eksctl 版本创建的 EKSWorkerNodePolicy，则 Amazon（包括所需的`AssumeRoleForPodIdentity`权限）将自动附加到节点角色。如果该权限不存在，请手动向 Amazon 添加以下权限 EKSWorkerNodePolicy ，允许担任 pod 身份的角色。EKS 容器组身份代理需要此权限才能检索容器组的凭证。

------
#### [ JSON ]

****  

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

------

### 创建 EKS 容器组身份代理附加组件
<a name="setting-up-enable-IAM-pod-eks-cluster-agent"></a>

使用以下命令通过最新版本创建 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 控制台](https://console.aws.amazon.com/eks/home#/clusters)。

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

1. 选择**附加组件**选项卡。

1. 选择**获取更多附加组件**。

1. 选择 EKS 容器组身份代理插件框右上角的框，然后选择**下一步**。

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

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

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

1. 选择**下一步**。

1. 通过 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 Pod 身份代理使用[AssumeRoleForPodIdentity](https://docs.aws.amazon.com/eks/latest/APIReference/API_auth_AssumeRoleForPodIdentity.html)操作从 EKS 身份验证 API 检索临时证书。然后，这些凭证可供您在容器内运行 AWS SDKs 的凭证使用。

有关更多信息，请查看公共文档中的先决条件：[设置 Amazon EKS 容器组身份代理](https://docs.aws.amazon.com/eks/latest/userguide/pod-id-agent-setup.html)。

## 创建作业执行角色
<a name="setting-up-enable-IAM-pod-create-job-role"></a>

### 创建或更新允许 EKS 容器组身份的作业执行角色
<a name="setting-up-enable-IAM-pod-create-job-role-update"></a>

要使用 Amazon EMR on EKS 运行工作负载，您需要创建一个 IAM 角色。我们在本文档中将此角色称为任务执行角色。有关如何创建 IAM 角色的更多信息，请参阅用户指南中的[创建 IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create.html)。

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

例如，您拥有以下作业执行角色。有关更多信息，请参阅[创建作业执行角色](https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/creating-job-execution-role.html)。

```
arn:aws:iam::111122223333:role/PodIdentityJobExecutionRole
```

**重要**  
Amazon EMR on EKS 会根据您的作业执行角色名称自动创建 Kubernetes 服务账户。确保角色名称不要太长，因为如果 `cluster_name`、`pod_name` 和 `service_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 容器组身份关联
<a name="setting-up-enable-IAM-pod-identity-asociations"></a>

### 先决条件
<a name="setting-up-enable-IAM-pod-identity-asociations-prereq"></a>

确保创建容器组身份关联的 IAM 身份（例如 EKS 管理员用户）拥有 `eks:CreatePodIdentityAssociation` 和 `iam: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 服务账户创建关联
<a name="setting-up-enable-IAM-pod-identity-asociations-emr-service"></a>

------
#### [ Create EMR role associations through the AWS CLI ]

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

使用 AWS CLI （2.24.0 以上版本），运行以下命令来创建具有 pod 标识的角色关联。

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

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

注意：
+ 每个集群最多可以有 1,000 个关联。每个作业执行角色与命名空间映射对作业提交者、驱动程序和执行程序容器组需要 3 个关联。
+ 您只能关联与集群属于同一 AWS 账户的角色。您可以将其他账户访问权限委派给此账户中的角色，也即您配置的供 EKS 容器组身份使用的角色。有关委派访问权限的教程和`AssumeRole`，请参阅 [IAM 教程：使用 IAM 角色跨 AWS 账户委派访问权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html)。

------
#### [ Create EMR role associations through Amazon EKS ]

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

构造服务账户名称：

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

以下示例为示例 Job 执行角色创建角色关联 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 设置跳过以下步骤：
+ [在 EKS 集群上为服务账户 (IRSA) 启用 IAM 角色](https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/setting-up-enable-IAM.html)
+ [创建任务执行角色](https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/creating-job-execution-role.html)
+ [更新任务执行角色的信任策略](https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/setting-up-trust-policy.html)

您可以直接跳到以下步骤：[授予用户访问 Amazon EMR on EKS 的权限](https://docs.aws.amazon.com/emr/latest/EMR-on-EKS-DevelopmentGuide/setting-up-iam.html)

## 删除角色关联
<a name="setting-up-enable-IAM-pod-identity-asociations-delete-associations"></a>

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

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

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

使用 AWS CLI （版本 2.24.0 或更高版本），运行以下 emr-containers 命令以删除 EMR 的角色关联：

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

## 自动将现有 IRSA 迁移到容器组身份
<a name="setting-up-enable-IAM-pod-identity-auto-migrate"></a>

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

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

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

## 问题排查
<a name="setting-up-enable-IAM-pod-identity-troubleshooting"></a>

### 我的任务因证书提供者出现 ClassNotFound 异常而失败，或者无法获取凭证提供商。 NoClassDefinitionFound
<a name="setting-up-enable-IAM-pod-identity-troubleshooting-no-class"></a>

EKS 容器组身份使用容器凭证提供程序来检索必要的凭证。如果您指定了自定义凭证提供程序，请确保其正常工作。或者，请确保您使用的是支持 EKS Pod 身份的正确 AWS SDK 版本。有关更多信息，请参阅 [Amazon EKS 入门](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html)。

### Job 失败， eks-pod-identity-agent日志中显示 “由于 [x] 大小限制而无法检索凭证” 错误。
<a name="setting-up-enable-IAM-pod-identity-troubleshooting-creds"></a>

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

### Job 失败， eks-pod-identity日志中显示 “无法检索凭证 xxx” 错误。
<a name="setting-up-enable-IAM-pod-identity-troubleshooting-creds-error"></a>

此问题的一个可能原因是 EKS 群集是在私有子网下配置的，而没有 PrivateLink 为群集正确配置。检查您的集群是否位于私有网络中，然后进行配置 AWS PrivateLink 以解决该问题。有关详细说明，请参阅 [Amazon EKS 入门](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html)。