2014-04-15 166 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,如果存在一個