jsp*_*ner 10 amazon-s3 amazon-emr apache-spark
我有一个EMR Spark Job需要在一个帐户上从S3读取数据并写入另一个帐户.
我把工作分成两步.
从S3读取数据(因为我的EMR集群在同一帐户中,所以不需要凭据).
读取步骤1创建的本地HDFS中的数据,并将其写入另一个帐户的S3存储桶.
我试过设置hadoopConfiguration:
sc.hadoopConfiguration.set("fs.s3n.awsAccessKeyId", "<your access key>")
sc.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey","<your secretkey>")
Run Code Online (Sandbox Code Playgroud)
并导出群集上的密钥:
$ export AWS_SECRET_ACCESS_KEY=
$ export AWS_ACCESS_KEY_ID=
Run Code Online (Sandbox Code Playgroud)
我已经尝试了群集和客户端模式以及spark-shell而没有运气.
他们每个都返回一个错误:
ERROR ApplicationMaster: User class threw exception: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception:
Access Denied
Run Code Online (Sandbox Code Playgroud)
Joh*_*ein 16
解决方案实际上非常简单.
首先,EMR集群有两个作用:
EMR_DefaultRole授予权限EMR服务(例如,用于发射的Amazon EC2实例))EMR_EC2_DefaultRole),使其可以访问AWS凭据(请参阅使用IAM角色为在Amazon EC2实例上运行的应用程序授予权限)这些角色在以下内容中进行了解释:Amazon EMR的默认IAM角色
因此,在群集中启动的每个EC2实例都会分配EMR_EC2_DefaultRole角色,从而通过Instance Metadata Service提供临时凭证.(有关其工作原理的说明,请参阅:Amazon EC2的IAM角色.)Amazon EMR节点使用这些凭据访问AWS服务,如S3,SNS,SQS,CloudWatch和DynamoDB.
其次,您需要向其他帐户中的Amazon S3存储桶添加权限,以允许通过该EMR_EC2_DefaultRole角色进行访问.这可以通过向S3存储桶(此处命名)添加存储桶策略来完成,other-account-bucket如下所示:
{
"Id": "Policy1",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1",
"Action": "s3:*",
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::other-account-bucket",
"arn:aws:s3:::other-account-bucket/*"
],
"Principal": {
"AWS": [
"arn:aws:iam::ACCOUNT-NUMBER:role/EMR_EC2_DefaultRole"
]
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
此策略将所有S3权限(s3:*)授予EMR_EC2_DefaultRole属于ACCOUNT-NUMBER与策略中匹配的帐户的角色,该帐户应该是启动EMR群集的帐户.授予此类权限时要小心 - 您可能只想授予权限,GetObject而不是授予所有S3权限.
就这样!另一个帐户中的存储桶现在将接受来自EMR节点的请求,因为它们正在使用该EMR_EC2_DefaultRole角色.
免责声明:我通过在Account-A中创建一个存储桶并为Account-B中的角色分配权限(如上所示)来测试上述内容.在具有该角色的Account-B中启动了EC2实例.我能够通过AWS命令行界面(CLI)从EC2实例访问存储桶.我并没有内EMR测试它,但它应该工作方式相同.
| 归档时间: |
|
| 查看次数: |
5157 次 |
| 最近记录: |