java - 从 EC2 访问 kinesis 时出现问题

标签 java amazon-ec2 amazon-kinesis

我有一些 Java 代码可以从 Kinesis 中提取记录。它在我的笔记本电脑上运行良好(无论 IP),但当我尝试在 EC2 上运行它时,我收到此错误:

Exception in thread "main" com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain
  at com.amazonaws.auth.AWSCredentialsProviderChain.getCredentials(AWSCredentialsProviderChain.java:131)
  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.getCredentialsFromContext(AmazonHttpClient.java:1119)
  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.runBeforeRequestHandlers(AmazonHttpClient.java:759)
  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:723)
  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:716)
  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
  at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
  at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
  at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.doInvoke(AWSSecurityTokenServiceClient.java:1271)
  at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.invoke(AWSSecurityTokenServiceClient.java:1247)
  at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.executeAssumeRole(AWSSecurityTokenServiceClient.java:454)
at com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient.assumeRole(AWSSecurityTokenServiceClient.java:431)

有问题的代码似乎让它不高兴:

AWSSecurityTokenServiceClient sts = new AWSSecurityTokenServiceClient();

AssumeRoleResult assumeRoleResult = sts.assumeRole(new AssumeRoleRequest()
            .withRoleArn(config.getString("kinesis/arn"))
            .withExternalId(config.getString("kinesis/external_id"))
            .withRoleSessionName(config.getString("kinesis/role_session_name")));

我想知道这是否与 EC2 实例的构建方式有关。但它在我的调试器中运行良好的事实让我感到困惑。

我已检查以确保各种配置值正确通过。

<小时/>

根据@prayagupd,我更新了 EC2 实例以包含此策略:

{
"Version": "2012-10-17",
"Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "kinesis:Get*",
        "kinesis:List*",
        "kinesis:Describe*"
      ],
      "Resource": "*"
    }
  ]
}

现在错误是:

Exception in thread "main" com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException: 
User: arn:aws:sts::12345:assumed-role/kinesis-consumer/i-cab01a5 
is not authorized to perform: 
sts:AssumeRole on resource: arn:aws:iam::12345:role/kinesis-consumer 

最佳答案

在您的 ec2 中,您需要通过 ec2 VM Profile 进行身份验证.

我使用以下代码连接到本地具有属性AwsProfileNameLoader.AWS_PROFILE_SYSTEM_PROPERTY的kinesis,该属性使用(~/.aws/credentials),对我来说~/.aws/credentials 是临时的。

因此,我在 ec2 内使用 DefaultAWSCredentialsProviderChain,它实际上查找 ec2 实例配置文件。

您仍然可以将您的凭证放入 ~/.aws/credentials 中并使用相同的凭证。

/**
 * provides credentials for a client to make connection to the elastic cloud instance
 *
 * @return DefaultAWSCredentialsProviderChain
 */
private DefaultAWSCredentialsProviderChain getAuthProfileCredentials() {
    if (myAppConfig.getProperty("authentication.profile") != null) {
        System.setProperty(AwsProfileNameLoader.AWS_PROFILE_SYSTEM_PROPERTY, myAppConfig.getProperty("authentication.profile"));
    }
    return new DefaultAWSCredentialsProviderChain();
}

您的 ec2 实例配置文件需要有 kinesis access IAM role具有以下信任关系。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

trust-relationship

角色策略应该有

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "kinesis:*"
            ],
            "Resource": [
                "arn:aws:kinesis:us-west-2:*:stream/*"
            ]
        }
    ]
}

enter image description here

然后可以在 ec2 机器上使用以下命令验证 kinesis 访问(应该已安装 aws cli)

aws kinesis create-stream --stream-name gregor-samsa-ping --shard-count 1 --region us-west-2

aws kinesis list-streams --region us-west-2
{
    "StreamNames": [
        "gregor-samsa-ping"
    ]
}

关于java - 从 EC2 访问 kinesis 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44334590/

相关文章:

java - 为 TSP 问题寻找哈密顿回路的问题

amazon-ec2 - 单个 ELB 可以服务多个域吗?它可以为多个子域提供服务吗?

apache-kafka - Debezium - MySQL 连接器 - Kinesis - 服务未启动

java - HttpURLConnection.getInputStream() 抛出 SocketTimeoutException

java - 带波形符的 URL 的 Maven groupId

amazon-web-services - aws实例如何同步时间

python - 带有 ipython 笔记本的 Amazon ec2 实例

apache-spark - 如何将 Spark 实时流与另一个流在其整个生命周期中收集的所有数据一起加入?

amazon-web-services - 使用 AWS Kinesis 上传大文件

java - 使 Eclipse 鼓励特定的关键字顺序