Spark正在发明自己的AWS secretKey

时间:2017-03-08 10:49:12

标签: amazon-web-services apache-spark amazon-s3 http-status-code-403 access-keys

我正在尝试从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

有人可以就此启发我吗?

4 个答案:

答案 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 访问策略。