在 hadoop 中指定 AWS 凭证

Specify the AWS credentials in hadoop

我想在 运行 时指定 AWS_SECRET_ACCESS_KEYAWS_ACCESS_KEY_ID

我已经尝试使用

hadoop -Dfs.s3a.access.key=${AWS_ACESS_KEY_ID} -Dfs.s3a.secret.key=${AWS_SECRET_ACCESS_KEY} fs -ls s3a://my_bucket/

export HADOOP_CLIENT_OPTS="-Dfs.s3a.access.key=${AWS_ACCESS_KEY_ID} -Dfs.s3a.secret.key=${AWS_SECRET_ACCESS_KEY}"

export HADOOP_OPTS="-Dfs.s3a.access.key=${AWS_ACCESS_KEY_ID} -Dfs.s3a.secret.key=${AWS_SECRET_ACCESS_KEY}"

在最后两个示例中,我尝试 运行 使用:

hadoop fs -ls s3a://my-bucket/

在我得到的所有案例中:

-ls: Fatal internal error
com.amazonaws.AmazonClientException: Unable to load AWS credentials from any provider in the chain
        at com.amazonaws.auth.AWSCredentialsProviderChain.getCredentials(AWSCredentialsProviderChain.java:117)
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3521)
        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.hadoop.fs.shell.PathData.expandAsGlob(PathData.java:325)
        at org.apache.hadoop.fs.shell.Command.expandArgument(Command.java:235)
        at org.apache.hadoop.fs.shell.Command.expandArguments(Command.java:218)
        at org.apache.hadoop.fs.shell.Command.processRawArguments(Command.java:201)
        at org.apache.hadoop.fs.shell.Command.run(Command.java:165)
        at org.apache.hadoop.fs.FsShell.run(FsShell.java:287)
        at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
        at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:84)
        at org.apache.hadoop.fs.FsShell.main(FsShell.java:340)

哪里做错了?

这是在运行时传递凭据的正确方法,

hadoop fs -Dfs.s3a.access.key=${AWS_ACCESS_KEY_ID} -Dfs.s3a.secret.key=${AWS_SECRET_ACCESS_KEY} -ls s3a://my_bucket/

您的语法需要稍作修改。确保不将空字符串作为值传递给这些属性。它会使这些运行时属性无效,并会根据身份验证链继续搜索凭据。

The S3A client follows the following authentication chain:

  1. If login details were provided in the filesystem URI, a warning is printed and then the username and password extracted for the AWS key and secret respectively.
  2. The fs.s3a.access.key and fs.s3a.secret.key are looked for in the Hadoop XML configuration.
  3. The AWS environment variables are then looked for.
  4. An attempt is made to query the Amazon EC2 Instance Metadata Service to retrieve credentials published to EC2 VMs.

在运行时传递凭据的其他可能方法(请注意,在运行时提供它们既不安全也不推荐),

1) 将它们嵌入 S3 URI

hdfs dfs -ls s3a://AWS_ACCESS_KEY_ID:AWS_SECRET_ACCESS_KEY@my-bucket/

如果密钥包含任何+/符号,分别用%2B%2F转义它们。

切勿共享 URL、使用它生成的日志,或在生产中使用此类内联身份验证机制。

2) export 会话的环境变量

export AWS_ACCESS_KEY_ID=<YOUR_AWS_ACCESS_KEY_ID>
export AWS_SECRET_ACCESS_KEY=<YOUR_AWS_SECRET_ACCESS_KEY>

hdfs dfs -ls s3a://my-bucket/

我认为部分问题在于,令人困惑的是,与 JVM -D opts 不同,Hadoop -D 命令需要 -D 和密钥之间的 space,例如:

hadoop fs -ls -D fs.s3a.access.key=AAIIED s3a://landsat-pds/

虽然我仍然会避免在命令行上这样做,因为任何可以执行 ps 命令的人都可以看到你的秘密。

通常 我们 将它们插入 core-site.xml 当 运行 在 EC2 之外时;在 EC2 中它被神奇地处理