简体   繁体   English

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

[英]Get instance-id of EC2 instance via Java

I have an AWS EC2 instance deployed, and I need to find out its public IP. 我部署了一个AWS EC2实例,我需要找到它的公共IP。 Howver, to know that I must first know the instance-id of my instance. 但是,要知道我必须首先知道我的实例的实例ID。

Objective: 目的:

  • I have a Java code running in my instance, and I want that code figure out the current IP or Instance-ID of the instance where it is being run. 我在我的实例中运行了一个Java代码,我希望该代码能够找出运行它的实例的当前IP或Instance-ID。

After reading Amazon documentation I came up with a Java method that returns the IP of all instances, but this is not what I want , I want a method that returns only the instance-id or the public IP address of the running instance. 在阅读了亚马逊文档后,我想出了一个返回所有实例的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;
    }

In this code I have an array with the instance-ids of all active instances, but I do not know if they are "me" or not. 在这段代码中,我有一个包含所有活动实例的instance-id的数组,但我不知道它们是否是“我”。 So I assume that my first step would be to know who I am, and then to ask for my public IP address. 所以我假设我的第一步是知道我是谁,然后要求我的公共IP地址。

Is there a change I can do to the previous method to give me what I want? 我可以对之前的方法做些改变,给我想要的东西吗? Is there a more efficient way of doing it? 有没有更有效的方法呢?

I would suggest/recommend the usage of the AWS SDK for Java. 我建议/建议使用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);

Unless Java8 is available, this will need more boilercode. 除非Java8可用,否则这将需要更多的锅炉代码。 But in the nutshell, that's it. 但简而言之,就是这样。

https://stackoverflow.com/a/30317951/525238 has already mentioned the EC2MetadataUtils, but this here includes working code also. https://stackoverflow.com/a/30317951/525238已经提到了EC2MetadataUtils,但这里也包含了工作代码。

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

The following method will return the EC2 Instance ID. 以下方法将返回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;
}

From here, you can then do the following to get information such as the IP address (in this example, the privateIP): 从这里,您可以执行以下操作以获取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());

You can also use this to get all kinds of relevant information about the current instance the Java program is running on; 您还可以使用它来获取有关运行Java程序的当前实例的各种相关信息; just replace .getPrivateIPAddress() with the appropriate get command for the info you seek. 只需用您要搜索的信息的相应get命令替换.getPrivateIPAddress() List of available commands can can be found here . 可以在此处找到可用命令列表。

Edit: For those that might shy away from using this due to the "unknown" URL; 编辑:对于那些由于“未知”URL而可能不愿意使用它的人; see Amazon's documentation on the topic, which points directly to this same URL; 请参阅亚马逊关于该主题的文档,该文档直接指向同一个URL; the only difference being they're doing it via cli rather than inside Java. 唯一的区别是他们是通过cli而不是Java内部来做的。 http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

To answer the initial question of 回答最初的问题

I have an AWS EC2 instance deployed, and I need to find out its public IP. 我部署了一个AWS EC2实例,我需要找到它的公共IP。

You can do in Java using the AWS API: 您可以使用AWS API在Java中执行以下操作:

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

This will directly give you the public IP if one exists 这将直接为您提供公共IP(如果存在)

I am not a java guy. 我不是一个java家伙。 However, my below ruby code does print the Instance ID and Public IP of the running instances as you needed: 但是,我的下面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
 
  

All you need to do is find out respective Methods/calls in JAVA SDK documentation. 您需要做的就是在JAVA SDK文档中找到相应的方法/调用。 The code that you should be looking at is: 您应该关注的代码是:

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

In above block, I am filtering out only the running instances. 在上面的块中,我只过滤掉 正在运行的实例。

AND

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

In above code block, I am running 2 for loops and pulling instance.instance_id as well as instance.public_ip_address . 在上面的代码块中,我运行2 for loops并拉动 instance.instance_id以及 instance.public_ip_address

As JAVA SDK and Ruby SDK are both hitting the same AWS EC2 APIs, there must be similar settings in JAVA SDK. 由于JAVA SDK和Ruby SDK都在使用相同的AWS EC2 API,因此JAVA SDK中必须有类似的设置。

Also, Your question is vague in the sense, are you running the JAVA code from the instance whose Instance id is needed? 此外, 您的问题在某种意义上是模糊的,您是否从需要实例ID的实例运行JAVA代码? OR Are you running the java code from a different instance and want to pull the instance-ids of all the running instances? 或者您是否从其他实例运行Java代码并想要拉出所有正在运行的实例的实例ID?

UPDATE: 更新:

Updating the answers as the question has changed: 在问题发生变化时更新答案:

AWS provides meta-data service on each instance that is launched. AWS为每个启动的实例提供元数据服务。 You can poll the meta-data service locally to find out the needed information. 您可以在本地轮询元数据服务以找出所需的信息。

Form bash promp, below command provided the instance-id and the public IP address of the instance 表单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 

You need to figure out how you will pull data from above URLs in java. 您需要弄清楚如何从java中的上述URL中提取数据。 At this point , you have enough information and this question is irrelevant with respect to AWS because now this is more of a JAVA question on how to poll above URLs. 此时,您有足够的信息,这个问题与AWS无关,因为现在这更像是一个关于如何轮询上述URL的JAVA问题。

You could use the metadata service to fetch this using HTTP: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html 您可以使用元数据服务使用HTTP获取此信息: http//docs.aws.amazon.com/AWSEC2/latest/UserGuide/AESDG-chapter-instancedata.html

ex: 例如:

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

I was needing to do many operations with Amazon EC2. 我需要使用Amazon EC2进行许多操作。 Then I implemented an utility class for this operations. 然后我为这个操作实现了一个实用程序类。 Maybe it can be util to someone that arrive here. 也许它可以用于到达这里的人。 I implemented using AWS SDK for java version 2. The operations are: 我使用适用于Java版本2的AWS SDK实现。操作是:

  • Create machine; 创造机器;
  • Start machine; 启动机器;
  • Stop machine; 停机;
  • Reboot machine; 重启机器;
  • Delete machine (Terminate); 删除机器(终止);
  • Describe machine; 描述机器;
  • Get Public IP from machine; 从机器获取公共IP;

AmazonEC2 class : 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 class: 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 class: 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: credentials.profiles:

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

I hope help o/ 我希望有帮助o /

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM