通过Java获取EC2实例的实例ID

Fla*_*nix 11 java ip amazon-ec2 amazon-web-services

我部署了一个AWS EC2实例,我需要找到它的公共IP.但是,要知道我必须首先知道我的实例的实例ID.

目的:

  • 我在我的实例中运行了一个Java代码,我希望该代码能够找出运行它的实例的当前IP或Instance-ID.

在阅读了亚马逊文档后,我想出了一个返回所有实例的IP的Java方法,但这不是我想要的,我想要一个只返回正在运行的实例的instance-id或公共IP地址的方法.

    /**
     * Returns a list with the public IPs of all the active instances, which are
     * returned by the {@link #getActiveInstances()} method.
     * 
     * @return  a list with the public IPs of all the active instances.
     * @see     #getActiveInstances()
     * */
    public List<String> getPublicIPs(){
        List<String> publicIpsList = new LinkedList<String>();

        //if there are no active instances, we return immediately to avoid extra 
        //computations.
        if(!areAnyActive())
            return publicIpsList;

        DescribeInstancesRequest request =  new DescribeInstancesRequest();
        request.setInstanceIds(instanceIds);

        DescribeInstancesResult result = ec2.describeInstances(request);
        List<Reservation> reservations = result.getReservations();

        List<Instance> instances;
        for(Reservation res : reservations){
            instances = res.getInstances();
            for(Instance ins : instances){
                LOG.info("PublicIP from " + ins.getImageId() + " is " + ins.getPublicIpAddress());
                publicIpsList.add(ins.getPublicIpAddress());
            }
        }

        return publicIpsList;
    }
Run Code Online (Sandbox Code Playgroud)

在这段代码中,我有一个包含所有活动实例的instance-id的数组,但我不知道它们是否是"我".所以我假设我的第一步是知道我是谁,然后要求我的公共IP地址.

我可以对之前的方法做些改变,给我想要的东西吗?有没有更有效的方法呢?

kna*_*lli 37

我建议/建议使用AWS SDK for Java.

// Resolve the instanceId
String instanceId = EC2MetadataUtils.getInstanceId();

// Resolve (first/primary) private IP
String privateAddress = EC2MetadataUtils.getInstanceInfo().getPrivateIp();

// Resolve public IP
AmazonEC2 client = AmazonEC2ClientBuilder.defaultClient();
String publicAddress = client.describeInstances(new DescribeInstancesRequest()
                                                    .withInstanceIds(instanceId))
                             .getReservations()
                             .stream()
                             .map(Reservation::getInstances)
                             .flatMap(List::stream)
                             .findFirst()
                             .map(Instance::getPublicIpAddress)
                             .orElse(null);
Run Code Online (Sandbox Code Playgroud)

除非Java8可用,否则这将需要更多的锅炉代码.但简而言之,就是这样.

/sf/answers/2122256601/已经提到了EC2MetadataUtils,但这里也包含了工作代码.


小智 24

您需要aws-java-sdk中的com.amazonaws.util.EC2MetadataUtils类.


DGo*_*erg 5

以下方法将返回 EC2 实例 ID。

public String retrieveInstanceId() throws IOException {
    String EC2Id = null;
    String inputLine;
    URL EC2MetaData = new URL("http://169.254.169.254/latest/meta-data/instance-id");
    URLConnection EC2MD = EC2MetaData.openConnection();
    BufferedReader in = new BufferedReader(new InputStreamReader(EC2MD.getInputStream()));
    while ((inputLine = in.readLine()) != null) {
        EC2Id = inputLine;
    }
    in.close();
    return EC2Id;
}
Run Code Online (Sandbox Code Playgroud)

从这里,您可以执行以下操作以获取 IP 地址(在本例中为 privateIP)等信息:

try {
    myEC2Id = retrieveInstanceId();
} catch (IOException e1) {
    e1.printStackTrace(getErrorStream());
}
DescribeInstancesRequest describeInstanceRequest = new DescribeInstancesRequest().withInstanceIds(myEC2Id);
DescribeInstancesResult describeInstanceResult = ec2.describeInstances(describeInstanceRequest);
System.out.println(describeInstanceResult.getReservations().get(0).getInstances().get(0).getPrivateIPAddress());
Run Code Online (Sandbox Code Playgroud)

您还可以使用它来获取有关运行 Java 程序的当前实例的各种相关信息;只需.getPrivateIPAddress()为您寻找的信息替换为适当的 get 命令。可以在此处找到可用命令的列表。

编辑:对于那些由于“未知”网址而可能回避使用它的人;请参阅亚马逊关于该主题的文档,该文档直接指向同一个 URL;唯一的区别是他们是通过 cli 而不是在 Java 中完成的。http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html


sla*_*fer 3

我不是java人。但是,我的下面的 ruby​​ 代码确实根据您的需要打印了实例的Instance ID和 :Public IPrunning

ec2.describe_instances(
  filters:[
    {
      name: "instance-state-name",
      values: ["running"]
    }
  ]
).each do |resp|
  resp.reservations.each do |reservation|
    reservation.instances.each do |instance|
        puts instance.instance_id + " ---AND--- " + instance.public_ip_address
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

您所需要做的就是在 JAVA SDK 文档中查找相应的方法/调用。您应该查看的代码是:

  filters:[
    {
      name: "instance-state-name",
      values: ["running"]
    }
Run Code Online (Sandbox Code Playgroud)

在上面的块中,我仅过滤掉正在运行的实例。

resp.reservations.each do |reservation|
        reservation.instances.each do |instance|
            puts instance.instance_id + " ---AND--- " + instance.public_ip_address
Run Code Online (Sandbox Code Playgroud)

在上面的代码块中,我运行了 2 个for循环并instance.instance_id拉动instance.public_ip_address.

由于 JAVA SDK 和 Ruby SDK 都使用相同的 AWS EC2 API,因此 JAVA SDK 中必须有类似的设置。

另外,您的问题在某种意义上是模糊的,您是否从需要实例 ID 的实例运行 JAVA 代码?或者您是否从不同的实例运行 java 代码并想要提取所有正在运行的实例的实例 ID?

更新:

随着问题的变化更新答案:

AWS 在每个启动的实例上提供元数据服务。您可以在本地轮询元数据服务以查找所需的信息。

形成 bash 提示符,下面的命令提供了实例 ID 和实例的公共 IP 地址

$ curl -L http://169.254.169.254/latest/meta-data/instance-id

$ curl -L http://169.254.169.254/latest/meta-data/public-ipv4
Run Code Online (Sandbox Code Playgroud)

您需要弄清楚如何在 java 中从上述 URL 中提取数据。此时,您已经有了足够的信息,并且这个问题与 AWS 无关,因为现在这更多的是关于如何轮询上述 URL 的 JAVA 问题。