2014-04-15 121 views
8

我部署了一个AWS EC2实例,并且需要查找其公有IP。不管怎样,要知道我必须首先知道我的实例的实例ID。通过Java获取EC2实例的实例ID

目的:

  • 我在我的实例中运行的Java代码,我想代码弄清楚它正在运行的实例的当前IP或实例-ID。

阅读亚马逊的文档后,我想出了一个返回所有实例,的IP Java方法,但是这不是我想要的,我想这仅返回实例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; 
    } 

在这段代码中我有所有活动实例的实例ID的数组,但我不知道他们是否是“我”与否。所以我认为我的第一步是要知道我是谁,然后询问我的公共IP地址。

有没有可以改变我以前的方法给我想要的东西?有没有更有效的方法呢?

+2

这里的解决方案:http://codeflex.co/java -get-ec2-private-public-ip-and-instance-id/ –

回答

3

我不是一个Java的家伙。然而,我在下面的Ruby代码不会打印 running实例的 Instance IDPublic IP,你需要:

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 

所有你需要做的是找出相应的方法/ JAVA SDK文档中调用。你应该看的是代码:

filters:[ 
    { 
     name: "instance-state-name", 
     values: ["running"] 
    } 

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

AND

resp.reservations.each do |reservation| 
     reservation.instances.each do |instance| 
      puts instance.instance_id + " ---AND--- " + instance.public_ip_address 

在上面的代码块,我运行2个for环和牵引instance.instance_id以及instance.public_ip_address

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

另外, 您的问题在含义上是含糊不清的,您是否从需要实例id的实例运行JAVA代码?或者你是否正在运行来自其他实例的java代码,并且想要提取所有正在运行的实例的实例id?

UPDATE:

更新答案的问题发生了变化:

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

形式的bash promp,以下命令提供的实例ID和实例

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

$ curl -L http://169.254.169.254/latest/meta-data/public-ipv4 

你需要弄清楚你将如何从上面在java中的URL中提取数据的公网IP地址。在这一点上,你有足够的信息,这个问题与AWS无关,因为现在这更像是一个关于如何轮询上述URL的JAVA问题。

+0

该代码为我提供了所有正在运行的实例的IP和ID,因此它完全符合我的代码所做的事情。这不是我想要的,但我想要的是我的实例的公共IP或实例ID,所以我可以识别它。 –

+0

我编辑我的问题要尽可能清楚。我希望现在各种模糊不见了! –

+0

@Flame_Phoenix,查看更新。 – slayedbylucifer

1

您可以使用元数据服务来获取这种使用HTTP: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html

例如:

GET http://169.254.169.254/latest/meta-data/instance-id 
+0

这不使用Java SDK,它不是我正在寻找的解决方案,它解决了我所面临的任何问题。 Sry基因。 –

+1

看来你的答案毕竟是正确的。这是解决此问题的唯一方法,因为AWS EC2 API不以任何其他方式支持此功能。荣誉++先生。 –

2

以下方法将返回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; 
} 

从这里,你就可以执行以下操作来获得信息,如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()); 

你也可以用它来获得各种Java程序正在运行的当前实例的相关信息;只需用适当的get命令替换.getPrivateIPAddress()即可获取您要查找的信息。可用命令列表可以找到here

编辑:对于那些可能因使用“未知”URL而避而远之的人;请参阅Amazon关于该主题的文档,该文档直接指向此相同的URL;唯一的区别是他们通过cli而不是Java内部进行。 http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

25

我会建议/推荐使用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); 

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

https://stackoverflow.com/a/30317951/525238已经提到了EC2MetadataUtils,但是这里也包括工作代码。

+0

谢谢。完美的答案。 – Anuj

2

要回答的

最初的问题我有一个AWS EC2实例部署,我需要找出它的公网IP。

您可以使用AWS API在Java中做到:

EC2MetadataUtils.getData("/latest/meta-data/public-ipv4"); 

这将直接给你的公网IP,如果存在一个