AWS使用IAM角色从Spark访问s3

时间:2019-01-16 18:31:06

标签: amazon-web-services apache-spark amazon-s3 amazon-iam aws-iam

我想从spark访问s3,我不想配置任何秘密和访问密钥,我想通过配置IAM角色进行访问,所以我遵循https://i.stack.imgur.com/9T4lP.png

中给出的步骤

但是仍然无法从我的EC2实例(正在运行独立的Spark)运行

它在我测试时有效

[ec2-user@ip-172-31-17-146 bin]$ aws s3 ls s3://testmys3/
2019-01-16 17:32:38        130 e.json

但是当我尝试如下操作时它不起作用

scala> val df = spark.read.json("s3a://testmys3/*")

我收到以下错误

19/01/16 18:23:06 WARN FileStreamSink: Error while looking for metadata directory.
com.amazonaws.services.s3.model.AmazonS3Exception: Status Code: 400, AWS Service: Amazon S3, AWS Request ID: E295957C21AFAC37, AWS Error Code: null, AWS Error Message: Bad Request
  at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:798)
  at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:421)
  at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:232)
  at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3528)
  at com.amazonaws.services.s3.AmazonS3Client.headBucket(AmazonS3Client.java:1031)
  at com.amazonaws.services.s3.AmazonS3Client.doesBucketExist(AmazonS3Client.java:994)
  at org.apache.hadoop.fs.s3a.S3AFileSystem.initialize(S3AFileSystem.java:297)
  at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2669)
  at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:94)
  at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2703)
  at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2685)
  at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:373)
  at org.apache.hadoop.fs.Path.getFileSystem(Path.java:295)
  at org.apache.spark.sql.execution.datasources.DataSource$.org$apache$spark$sql$execution$datasources$DataSource$$checkAndGlobPathIfNecessary(DataSource.scala:616)

3 个答案:

答案 0 :(得分:3)

此配置有效

./spark-shell \
    --packages com.amazonaws:aws-java-sdk:1.7.4,org.apache.hadoop:hadoop-aws:2.7.3 \
    --conf spark.hadoop.fs.s3a.endpoint=s3.us-east-2.amazonaws.com \
    --conf spark.hadoop.fs.s3a.impl=org.apache.hadoop.fs.s3a.S3AFileSystem \
    --conf spark.hadoop.fs.s3a.aws.credentials.provider=com.amazonaws.auth.InstanceProfileCredentialsProvider \
    --conf spark.executor.extraJavaOptions=-Dcom.amazonaws.services.s3.enableV4=true \
    --conf spark.driver.extraJavaOptions=-Dcom.amazonaws.services.s3.enableV4=true  

答案 1 :(得分:1)

“ 400错误的请求”是完全无济于事的,不仅S3没有提供太多信息,而且S3A连接器也没有显示与auth相关的太多信息。 troubleshooting the error

上有很大一部分

它发出请求的事实意味着它具有一些凭据,只有远端不喜欢它们

可能性

  • 您的IAM角色没有s3:ListBucket的权限。参见IAM role permissions for working with s3a
  • 您的存储桶名称错误
  • fs.s3a或AWS_ env vars中有一些设置比IAM角色具有优先权,这是错误的。

您应该使用S3A连接器自动将IAM身份验证作为身份验证机制;它是最后检查的:config&env vars。

  1. 看看fs.s3a.aws.credentials.provider中设置了什么-它必须未设置或包含选项com.amazonaws.auth.InstanceProfileCredentialsProvider
  2. 假设您在命令行上也有hadoop,抓住storediag
hadoop jar cloudstore-0.1-SNAPSHOT.jar storediag s3a://testmys3/

它应该转储有关身份验证的内容。

更新

正如原始发布者所评论的,这是由于特定S3端点上需要进行v4身份验证。可以在s3a客户端的2.7.x版本上启用此功能,但只能通过Java系统属性启用。对于2.8+,有一些fs.s3a。选项,您可以改为设置

答案 2 :(得分:0)

  • 步骤1。配置火花容器框架(如Yarn core-site.xml)。然后重新启动Yarn

fs.s3a.aws.credentials.provider-- com.cloudera.com.amazonaws.auth.InstanceProfileCredentialsProvider

fs.s3a.endpoint-- s3-ap-northeast-2.amazonaws.com

fs.s3.impl-- org.apache.hadoop.fs.s3a.S3AFileSystem

  • 第二步。火花壳进行如下测试。

val rdd=sc.textFile("s3a://path/file")
 rdd.count()
 rdd.take(10).foreach(println)

对我有用