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

时间:2014-04-15 11:05:39

标签: java amazon-web-services amazon-ec2 ip

我部署了AWS EC2实例,我需要查找其公共IP。但是,要知道我必须首先知道我的实例的实例ID。

目的:

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

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

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

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

7 个答案:

答案 0 :(得分:35)

我建议/建议使用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,但这里也包含了工作代码。

答案 1 :(得分:24)

你想要aws-java-sdk中的com.amazonaws.util.EC2MetadataUtils类。

答案 2 :(得分:3)

以下方法将返回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;唯一的区别是他们是通过cli而不是Java内部来做的。 http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

答案 3 :(得分:3)

回答最初的问题

  

我部署了一个AWS EC2实例,我需要找到它的公共IP。

您可以使用AWS API在Java中完成:

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

这将直接为您提供公共IP(如果存在)

答案 4 :(得分:2)

我不是一个java家伙。但是,我的以下ruby代码会根据您的需要打印Instance ID Public IP running个实例:

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"]
    }

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

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中必须有类似的设置。

另外,你的问题在某种意义上是模糊的,你是否需要从需要Instance id的实例运行JAVA代码?或者您是否从其他实例运行Java代码并想要拉出所有正在运行的实例的实例ID?

<强>更新

在问题发生变化时更新答案:

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

表单bash提示,下面的命令提供了instance-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

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

答案 5 :(得分: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

答案 6 :(得分:0)

我需要使用Amazon EC2进行许多操作。然后,我为此操作实现了一个实用程序类。也许对到达这里的人有用。我使用适用于Java版本2的AWS开发工具包实现了。操作是:

  • 创建机器;
  • 启动机器;
  • 停止机器;
  • 重新启动计算机;
  • 删除机器(终止);
  • 描述机器;
  • 从计算机获取公共IP;

AmazonEC2类

import govbr.cloud.management.api.CloudManagementException;
import govbr.cloud.management.api.CloudServerMachine;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.core.exception.SdkClientException;
import software.amazon.awssdk.core.exception.SdkServiceException;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesResponse;
import software.amazon.awssdk.services.ec2.model.Ec2Exception;
import software.amazon.awssdk.services.ec2.model.Instance;
import software.amazon.awssdk.services.ec2.model.InstanceNetworkInterface;
import software.amazon.awssdk.services.ec2.model.InstanceType;
import software.amazon.awssdk.services.ec2.model.RebootInstancesRequest;
import software.amazon.awssdk.services.ec2.model.Reservation;
import software.amazon.awssdk.services.ec2.model.RunInstancesRequest;
import software.amazon.awssdk.services.ec2.model.RunInstancesResponse;
import software.amazon.awssdk.services.ec2.model.StartInstancesRequest;
import software.amazon.awssdk.services.ec2.model.StopInstancesRequest;
import software.amazon.awssdk.services.ec2.model.TerminateInstancesRequest;


public class AmazonEC2 {

    private final static String EC2_MESSAGE_ERROR = "A error occurred on the     Ec2.";
    private final static String CLIENT_MESSAGE_ERROR = "A error occurred in client side.";
    private final static String SERVER_MESSAGE_ERROR = "A error occurred in Amazon server.";
    private final static String UNEXPECTED_MESSAGE_ERROR = "Unexpected error occurred.";


    private Ec2Client buildDefaultEc2() {

        AwsCredentialsProvider credentials = AmazonCredentials.loadCredentialsFromFile();

        Ec2Client ec2 = Ec2Client.builder()
                .region(Region.SA_EAST_1)
                .credentialsProvider(credentials)                            
                .build();

        return ec2;
    }

    public String createMachine(String name, String amazonMachineId) 
                        throws CloudManagementException {
        try {
            if(amazonMachineId == null) {
                amazonMachineId = "ami-07b14488da8ea02a0";              
            }       

            Ec2Client ec2 = buildDefaultEc2();           

            RunInstancesRequest request = RunInstancesRequest.builder()
                    .imageId(amazonMachineId)
                    .instanceType(InstanceType.T1_MICRO)
                    .maxCount(1)
                    .minCount(1)
                    .build();

            RunInstancesResponse response = ec2.runInstances(request);

            Instance instance = null;

            if (response.reservation().instances().size() > 0) {
                instance = response.reservation().instances().get(0);
            }

            if(instance != null) {
                System.out.println("Machine created! Machine identifier: " 
                                    + instance.instanceId());
                return instance.instanceId();
            }

            return null;

        } catch (Ec2Exception e) {          
            throw new CloudManagementException(EC2_MESSAGE_ERROR, e);   
        } catch (SdkClientException e) {
            throw new CloudManagementException(CLIENT_MESSAGE_ERROR, e);            
        } catch (SdkServiceException e) {
            throw new CloudManagementException(SERVER_MESSAGE_ERROR, e);            
        } catch (Exception e) {
            throw new CloudManagementException(UNEXPECTED_MESSAGE_ERROR, e);            
        }       
    }

    public void startMachine(String instanceId) {
        try {

            Ec2Client ec2 = buildDefaultEc2();
            StartInstancesRequest request = StartInstancesRequest.builder()
                                             .instanceIds(instanceId).build();
            ec2.startInstances(request);

        } catch (Ec2Exception e) {          
            throw new CloudManagementException(EC2_MESSAGE_ERROR, e);   
        } catch (SdkClientException e) {
            throw new CloudManagementException(CLIENT_MESSAGE_ERROR, e);            
        } catch (SdkServiceException e) {
            throw new CloudManagementException(SERVER_MESSAGE_ERROR, e);            
        } catch (Exception e) {
            throw new CloudManagementException(UNEXPECTED_MESSAGE_ERROR, e);            
        }   
    }

    public void stopMachine(String instanceId) {
        try {

            Ec2Client ec2 = buildDefaultEc2();
            StopInstancesRequest request = StopInstancesRequest.builder()
                                              .instanceIds(instanceId).build();
            ec2.stopInstances(request);

        } catch (Ec2Exception e) {          
            throw new CloudManagementException(EC2_MESSAGE_ERROR, e);   
        } catch (SdkClientException e) {
            throw new CloudManagementException(CLIENT_MESSAGE_ERROR, e);            
        } catch (SdkServiceException e) {
            throw new CloudManagementException(SERVER_MESSAGE_ERROR, e);            
        } catch (Exception e) {
            throw new CloudManagementException(UNEXPECTED_MESSAGE_ERROR, e);            
        }   
    }

    public void rebootMachine(String instanceId) {
        try {

            Ec2Client ec2 = buildDefaultEc2();
            RebootInstancesRequest request = RebootInstancesRequest.builder()
                                              .instanceIds(instanceId).build();
            ec2.rebootInstances(request);

        } catch (Ec2Exception e) {          
            throw new CloudManagementException(EC2_MESSAGE_ERROR, e);   
        } catch (SdkClientException e) {
            throw new CloudManagementException(CLIENT_MESSAGE_ERROR, e);            
        } catch (SdkServiceException e) {
            throw new CloudManagementException(SERVER_MESSAGE_ERROR, e);            
        } catch (Exception e) {
            throw new CloudManagementException(UNEXPECTED_MESSAGE_ERROR, e);            
        }   
    }

    public void destroyMachine(String instanceId) {
        try {

            Ec2Client ec2 = buildDefaultEc2();
            TerminateInstancesRequest request = TerminateInstancesRequest.builder()
       .instanceIds(instanceId).build();
            ec2.terminateInstances(request);

        } catch (Ec2Exception e) {          
            throw new CloudManagementException(EC2_MESSAGE_ERROR, e);   
        } catch (SdkClientException e) {
            throw new CloudManagementException(CLIENT_MESSAGE_ERROR, e);            
        } catch (SdkServiceException e) {
            throw new CloudManagementException(SERVER_MESSAGE_ERROR, e);            
        } catch (Exception e) {
            throw new CloudManagementException(UNEXPECTED_MESSAGE_ERROR, e);            
        }   
    }

    public String getPublicIpAddress(String instanceId) throws CloudManagementException {
        try {

            Ec2Client ec2 = buildDefaultEc2();

            boolean done = false;

            DescribeInstancesRequest request = DescribeInstancesRequest.builder().build();

            while(!done) {
                DescribeInstancesResponse response = ec2.describeInstances(request);

                for(Reservation reservation : response.reservations()) {
                    for(Instance instance : reservation.instances()) {
                        if(instance.instanceId().equals(instanceId)) {
                            if(instance.networkInterfaces().size() > 0) {
                                InstanceNetworkInterface networkInterface = 
                                           instance.networkInterfaces().get(0);
                                String publicIp = networkInterface
                                                     .association().publicIp();
                                System.out.println("Machine found. Machine with Id " 
                                                   + instanceId 
                                                   + " has the follow public IP: " 
                                                   + publicIp);
                                return publicIp;
                            }                           
                        }
                    }
                }

                if(response.nextToken() == null) {
                    done = true;
                }
            }

            return null;

        } catch (Ec2Exception e) {          
            throw new CloudManagementException(EC2_MESSAGE_ERROR, e);   
        } catch (SdkClientException e) {
            throw new CloudManagementException(CLIENT_MESSAGE_ERROR, e);            
        } catch (SdkServiceException e) {
            throw new CloudManagementException(SERVER_MESSAGE_ERROR, e);            
        } catch (Exception e) {
            throw new CloudManagementException(UNEXPECTED_MESSAGE_ERROR, e);            
        }   
    }

    public String describeMachine(String instanceId) {
        try {

            Ec2Client ec2 = buildDefaultEc2();          

            boolean done = false;

            DescribeInstancesRequest request = DescribeInstancesRequest.builder().build();

            while(!done) {
                DescribeInstancesResponse response = ec2.describeInstances(request);

                for(Reservation reservation : response.reservations()) {
                    for(Instance instance : reservation.instances()) {
                        if(instance.instanceId().equals(instanceId)) {                          
                            return "Found reservation with id " +
                                    instance.instanceId() +
                                    ", AMI " + instance.imageId() + 
                                    ", type " + instance.instanceType() + 
                                    ", state " + instance.state().name() + 
                                    "and monitoring state" + 
                                    instance.monitoring().state();                          
                        }
                    }
                }

                if(response.nextToken() == null) {
                    done = true;
                }
            }

            return null;

        } catch (Ec2Exception e) {          
            throw new CloudManagementException(EC2_MESSAGE_ERROR, e);   
        } catch (SdkClientException e) {
            throw new CloudManagementException(CLIENT_MESSAGE_ERROR, e);            
        } catch (SdkServiceException e) {
            throw new CloudManagementException(SERVER_MESSAGE_ERROR, e);            
        } catch (Exception e) {
            throw new CloudManagementException(UNEXPECTED_MESSAGE_ERROR, e);            
        }   
    }

}

AmazonCredentials类:

import java.io.InputStream;

import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.profiles.ProfileFile;
import software.amazon.awssdk.profiles.ProfileFile.Type;

public class AmazonCredentials {


public static AwsCredentialsProvider loadCredentialsFromFile() {
    InputStream profileInput = ClassLoader.getSystemResourceAsStream("credentials.profiles");

    ProfileFile profileFile = ProfileFile.builder()
            .content(profileInput)
            .type(Type.CREDENTIALS)
            .build();

    AwsCredentialsProvider profileProvider = ProfileCredentialsProvider.builder()
            .profileFile(profileFile)
            .build();

    return profileProvider;
}

}

CloudManagementException类:

public class CloudManagementException extends RuntimeException {

private static final long serialVersionUID = 1L;


public CloudManagementException(String message) {
    super(message);
}

public CloudManagementException(String message, Throwable cause) {
    super(message, cause);
}

}

credentials.profiles:

[default]
aws_access_key_id={your access key id here}
aws_secret_access_key={your secret access key here}

希望对您有帮助