

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

# 为 Amazon EMR on EKS 设置跨账户访问权限
<a name="security-cross-account"></a>

您可为 Amazon EMR on EKS 设置跨账户访问权限。跨账户访问允许一个 AWS 账户的用户在 EKS 任务上运行 Amazon EMR，并访问属于 AWS 另一个账户的基础数据。

## 先决条件
<a name="security-cross-account-prereq"></a>

要在 EKS 上为 Amazon EMR 设置跨账户访问权限，您需要在登录以下账户的 AWS 同时完成任务：
+ `AccountA`-一个 AWS 账户，您通过在 EKS 集群上使用命名空间注册 Amazon EMR，在 EKS 虚拟集群上创建了 Amazon EMR。
+ `AccountB`-一个包含亚马逊 S3 存储桶或 DynamoDB 表的 AWS 账户，您想让 EKS 上的 Amazon EMR 任务访问这些存储桶或 DynamoDB 表。

在设置跨账户访问权限之前，您必须在 AWS 账户中准备好以下内容：
+ `AccountA` 中的 Amazon EMR on EKS 虚拟集群，即要运行任务之处。
+ `AccountA` 中的任务执行角色拥有在虚拟集群中运行任务所需的权限。有关更多信息，请参阅[创建任务执行角色](creating-job-execution-role.md)和[将任务执行角色与 Amazon EMR on EKS 结合使用](iam-execution-role.md)。

## 如何访问跨账户 Amazon S3 存储桶或 DynamoDB 表
<a name="security-cross-account-steps"></a>

要为 Amazon EMR on EKS 设置跨账户访问权限，请完成以下步骤。

1. 创建 Amazon S3 存储桶，即 `AccountB` 中的 `cross-account-bucket`。有关更多信息，请参阅[创建存储桶](https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html)。如果您希望跨账户访问 DynamoDB，还可以在 `AccountB` 中创建 DynamoDB 表。有关更多信息，请参阅[创建 DynamoDB 表](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-1.html)。

1. 在 `AccountB` 中创建 `Cross-Account-Role-B` IAM 角色，以便可以访问 `cross-account-bucket`。

   1. 登录到 IAM 控制台。

   1. 选择 **Roles (角色)** 并创建新角色：`Cross-Account-Role-B`。有关如何创建 IAM 角色的更多信息，请参阅《IAM 用户指南》中的[创建 IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create.html)。

   1. 创建 IAM policy 来指定针对 `Cross-Account-Role-B` 的权限以访问 `cross-account-bucket` S3 存储桶，如以下策略声明所示。然后将 IAM policy 附加到 `Cross-Account-Role-B`。有关更多信息，请参阅《IAM 用户指南》中的[创建新策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html)。

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

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "s3:*"
            ],
            "Resource": [
              "arn:aws:s3:::cross-account-bucket",
              "arn:aws:s3:::cross-account-bucket/*"
            ],
            "Sid": "AllowS3"
          }
        ]
      }
      ```

------

      如果需要 DynamoDB 访问权限，请创建 IAM policy，该策略指定访问跨账户 DynamoDB 表的权限。然后将 IAM policy 附加到 `Cross-Account-Role-B`。有关更多信息，请参阅《IAM 用户指南》中的[创建 DynamoDB 表](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_dynamodb_specific-table.html)。

      以下是访问 DynamoDB 表 `CrossAccountTable` 的策略。

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

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "dynamodb:*"
            ],
            "Resource": [
              "arn:aws:dynamodb:us-east-1:*:table/CrossAccountTable"
            ],
            "Sid": "AllowDYNAMODB"
          }
        ]
      }
      ```

------

1. 编辑 `Cross-Account-Role-B` 角色的信任关系。

   1. 要为角色配置信任关系，请选择 IAM 控制台的 **Trust Relationships (信任关系)** 选项卡，以用于在步骤 2 中创建的角色：`Cross-Account-Role-B`。

   1. 选择 **Edit Trust Relationship (编辑信任关系)**。

   1. 添加以下策略文档，该文档允许使用 `AccountA` 中的 `Job-Execution-Role-A` 来假承担该 `Cross-Account-Role-B` 角色。

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

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Sid": "AllowSTSAssumerole",
            "Effect": "Allow",
            "Principal": {
              "AWS": "arn:aws:iam::{{123456789012}}:role/Job-Execution-Role-A"
            },
            "Action": "sts:AssumeRole"
          }
        ]
      }
      ```

------

1. 授予 `AccountA` 中的 `Job-Execution-Role-A` STS 代入角色权限来代入 `Cross-Account-Role-B`。

   1. 在 AWS 账户的 IAM 控制台中`AccountA`，选择`Job-Execution-Role-A`。

   1. 添加以下 `Job-Execution-Role-A` 策略语句以便对 `Cross-Account-Role-B` 角色执行 `AssumeRole` 操作。

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

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "sts:AssumeRole"
            ],
            "Resource": [
              "arn:aws:iam::*:role/Cross-Account-Role-B"
            ],
            "Sid": "AllowSTSAssumerole"
          }
        ]
      }
      ```

------

1. 对于 Amazon S3 访问权限，请设置以下 `spark-submit` 参数（`spark conf`），同时将任务提交至 Amazon EMR on EKS。
**注意**  
默认情况下，EMRFS 使用任务执行角色以访问任务的 S3 存储桶。但当 `customAWSCredentialsProvider` 设置为 `AssumeRoleAWSCredentialsProvider` 时，EMRFS 将使用您通过 `ASSUME_ROLE_CREDENTIALS_ROLE_ARN` 指定的相应角色，而不是通过 `Job-Execution-Role-A` 以访问 Amazon S3。
   + `--conf spark.hadoop.fs.s3.customAWSCredentialsProvider=com.amazonaws.emr.AssumeRoleAWSCredentialsProvider`
   + `--conf spark.kubernetes.driverEnv.ASSUME_ROLE_CREDENTIALS_ROLE_ARN=arn:aws:iam::{{AccountB}}:role/Cross-Account-Role-B \`
   + `--conf spark.executorEnv.ASSUME_ROLE_CREDENTIALS_ROLE_ARN=arn:aws:iam::{{AccountB}}:role/Cross-Account-Role-B \`
**注意**  
您必须在任务 Spark 配置中为执行程序和驱动程序 `env` 设置 `ASSUME_ROLE_CREDENTIALS_ROLE_ARN`。

   对于 DynamoDB 跨账户访问，您必须设置 `--conf spark.dynamodb.customAWSCredentialsProvider=com.amazonaws.emr.AssumeRoleAWSCredentialsProvider`。

1. 使用跨账户访问权限运行 Amazon EMR on EKS 上的任务，如以下示例所示。

   ```
   aws emr-containers start-job-run \
   --virtual-cluster-id 123456 \
   --name myjob \
   --execution-role-arn execution-role-arn \
   --release-label emr-6.2.0-latest \
   --job-driver '{"sparkSubmitJobDriver": {"entryPoint": "entryPoint_location", "entryPointArguments": ["arguments_list"], "sparkSubmitParameters": "--class <main_class> --conf spark.executor.instances=2 --conf spark.executor.memory=2G --conf spark.executor.cores=2 --conf spark.driver.cores=1 --conf spark.hadoop.fs.s3.customAWSCredentialsProvider=com.amazonaws.emr.AssumeRoleAWSCredentialsProvider --conf spark.kubernetes.driverEnv.ASSUME_ROLE_CREDENTIALS_ROLE_ARN=arn:aws:iam::{{AccountB}}:role/Cross-Account-Role-B --conf spark.executorEnv.ASSUME_ROLE_CREDENTIALS_ROLE_ARN=arn:aws:iam::{{AccountB}}:role/Cross-Account-Role-B"}} ' \
   --configuration-overrides '{"applicationConfiguration": [{"classification": "spark-defaults", "properties": {"spark.driver.memory": "2G"}}], "monitoringConfiguration": {"cloudWatchMonitoringConfiguration": {"logGroupName": "log_group_name", "logStreamNamePrefix": "log_stream_prefix"}, "persistentAppUI":"ENABLED",  "s3MonitoringConfiguration": {"logUri": "s3://my_s3_log_location" }}}'
   ```