aws 使用 IAM 角色从 spark 访问 s3
aws access s3 from spark using IAM role
我想从 spark 访问 s3,我不想配置任何秘密和访问密钥,我想通过配置 IAM 角色来访问,所以我按照 s3-spark
但我的 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.access0(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)
“400 Bad Request”是相当无用的,不仅 S3 没有提供太多,S3A 连接器也没有与 auth 相关的日期打印。 troubleshooting the error
上有很大一部分
它发出请求的事实意味着它有一些凭据,只是远端不喜欢它们
可能性
- 您的 IAM 角色没有 s3:ListBucket 的权限。参见 IAM role permissions for working with s3a
- 您的存储桶名称错误
- fs.s3a 或 AWS_env vars 中的某些设置优先于 IAM 角色,但它们是错误的。
您应该自动将 IAM 身份验证作为 S3A 连接器的身份验证机制;它是最后检查的那个:config & env vars.
- 查看
fs.s3a.aws.credentials.provider
中设置的内容 - 它必须未设置或包含选项 com.amazonaws.auth.InstanceProfileCredentialsProvider
- 假设你在命令行上也有
hadoop
,抓取 storediag
hadoop jar cloudstore-0.1-SNAPSHOT.jar storediag s3a://testmys3/
它应该转储有关身份验证的内容。
更新
正如发帖人评论的那样,这是由于特定 S3 端点需要 v4 身份验证。这可以在 2.7.x 版本的 s3a 客户端上启用,但只能通过 Java 系统属性。对于 2.8+,有一些 fs.s3a。您可以设置它的选项
此配置有效
./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 \
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
- 第一步。配置像 Yarn core-site.xml.Then 这样的 spark 容器框架 重启 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
- 第二步。 spark shell 进行如下测试。
val rdd=sc.textFile("s3a://path/file")
rdd.count()
rdd.take(10).foreach(println)
对我有用
我想从 spark 访问 s3,我不想配置任何秘密和访问密钥,我想通过配置 IAM 角色来访问,所以我按照 s3-spark
但我的 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.access0(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)
“400 Bad Request”是相当无用的,不仅 S3 没有提供太多,S3A 连接器也没有与 auth 相关的日期打印。 troubleshooting the error
上有很大一部分它发出请求的事实意味着它有一些凭据,只是远端不喜欢它们
可能性
- 您的 IAM 角色没有 s3:ListBucket 的权限。参见 IAM role permissions for working with s3a
- 您的存储桶名称错误
- fs.s3a 或 AWS_env vars 中的某些设置优先于 IAM 角色,但它们是错误的。
您应该自动将 IAM 身份验证作为 S3A 连接器的身份验证机制;它是最后检查的那个:config & env vars.
- 查看
fs.s3a.aws.credentials.provider
中设置的内容 - 它必须未设置或包含选项com.amazonaws.auth.InstanceProfileCredentialsProvider
- 假设你在命令行上也有
hadoop
,抓取 storediag
hadoop jar cloudstore-0.1-SNAPSHOT.jar storediag s3a://testmys3/
它应该转储有关身份验证的内容。
更新
正如发帖人评论的那样,这是由于特定 S3 端点需要 v4 身份验证。这可以在 2.7.x 版本的 s3a 客户端上启用,但只能通过 Java 系统属性。对于 2.8+,有一些 fs.s3a。您可以设置它的选项
此配置有效
./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 \
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
- 第一步。配置像 Yarn core-site.xml.Then 这样的 spark 容器框架 重启 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
- 第二步。 spark shell 进行如下测试。
val rdd=sc.textFile("s3a://path/file")
rdd.count()
rdd.take(10).foreach(println)
对我有用