我正在尝试从Spark读取一个s3存储桶直到今天Spark总是抱怨请求返回403
hadoopConf = spark_context._jsc.hadoopConfiguration()
hadoopConf.set("fs.s3a.access.key", "ACCESSKEY")
hadoopConf.set("fs.s3a.secret.key", "SECRETKEY")
hadoopConf.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
logs = spark_context.textFile("s3a://mybucket/logs/*)
Spark说......无效的访问密钥[ACCESSKEY]
然而,使用相同的ACCESSKEY和SECRETKEY,这与aws-cli一起工作
aws s3 ls mybucket/logs/
并且在python boto3中这是有效的
resource = boto3.resource("s3", region_name="us-east-1")
resource.Object("mybucket", "logs/text.py") \
.put(Body=open("text.py", "rb"),ContentType="text/x-py")
因此我的凭据无效,问题肯定与Spark有关..
今天我决定打开整个火花的“DEBUG”日志并让我感到惊讶...... Spark并没有使用我提供的[SECRETKEY]而是......添加一个随机的??? ??? p>
17/03/08 10:40:04 DEBUG请求:发送请求:HEAD https://mybucket.s3.amazonaws.com / Headers :(授权:AWS ACCESSKEY: [RANDON-SECRET-KEY] ,用户-Agent:aws-sdk-java / 1.7.4 Mac_OS_X / 10.11.6 Java_HotSpot(TM)_64-Bit_Server_VM / 25.65-b01 / 1.8.0_65,日期:星期三,08三月2017 10:40:04 GMT,Content-Type :application / x-www-form-urlencoded; charset = utf-8,)
这就是它仍然返回403的原因! Spark没有使用我在fs.s3a.secret.key中提供的密钥,而是发明了一个随机的密钥?
对于记录,我使用此命令在我的机器(OSX)上本地运行
spark-submit --packages com.amazonaws:aws-java-sdk-pom:1.11.98,org.apache.hadoop:hadoop-aws:2.7.3 test.py
有人可以就此启发我吗?
答案 0 :(得分:1)
我遇到了类似的问题。使用有效AWS凭据的请求返回403 Forbidden,但仅在某些计算机上。最终我发现那些特定机器上的系统时间落后了10分钟。同步系统时钟解决了这个问题。
希望这有帮助!
答案 1 :(得分:0)
(更新为我原来的一个被低估,显然被认为是不可接受的)
AWS身份验证协议不会通过网络发送您的密码。它签署了这条消息。这就是为什么你看到的不是你传入的内容。
有关详细信息,请重读。
答案 2 :(得分:0)
这个随机密钥非常有趣。也许AWS SDK从OS环境获取密码。
在hadoop 2.8中,默认AWS提供商链显示以下提供商列表:
BasicAWSCredentialsProvider EnvironmentVariableCredentialsProvider SharedInstanceProfileCredentialsProvider
当然,订单很重要! AWSCredentialProviderChain,从提供该信息的第一个提供者处获取第一个密钥。
if (credentials.getAWSAccessKeyId() != null &&
credentials.getAWSSecretKey() != null) {
log.debug("Loading credentials from " + provider.toString());
lastUsedProvider = provider;
return credentials;
}
请参阅"GrepCode for AWSCredentialProviderChain"中的代码。
我使用配置文件凭据遇到类似的问题。 SDK忽略了〜/ .aws / credentials中的凭据(作为一种好的做法,我鼓励你不要以任何方式将凭证存储在程序中)。
我的解决方案......
将凭据提供程序设置为使用ProfileCredentialsProvider
sc._jsc.hadoopConfiguration().set("fs.s3a.endpoint", "s3.eu-central-1.amazonaws.com") # yes, I am using central eu server.
sc._jsc.hadoopConfiguration().set('fs.s3a.aws.credentials.provider', 'com.amazonaws.auth.profile.ProfileCredentialsProvider')
答案 3 :(得分:0)
伙计们,去基于角色的 IAM 配置......这将打开应该添加到 EMR 默认策略的 S3 访问策略。