通过 Java 获取 EC2 实例的实例 ID
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23081848/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get instance-id of EC2 instance via Java
提问by Flame_Phoenix
I have an AWS EC2 instance deployed, and I need to find out its public IP. Howver, to know that I must first know the instance-id of my instance.
我部署了一个 AWS EC2 实例,我需要找出它的公共 IP。但是,要知道我必须首先知道我的实例的实例 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 或实例 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 方法,但这不是我想要的,我想要一个只返回实例 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. So I assume that my first step would be to know who I am, and then to ask for my public IP address.
在这段代码中,我有一个包含所有活动实例的实例 ID 的数组,但我不知道它们是否是“我”。所以我假设我的第一步是知道我是谁,然后询问我的公共 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?
我可以对以前的方法做一些改变来给我我想要的吗?有没有更有效的方法来做到这一点?
采纳答案by slayedbylucifer
I am not a java guy. However, my below ruby code does print the Instance ID
and Public IP
of the running
instances as you needed:
我不是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
All you need to do is find out respective Methods/calls in JAVA SDK documentation. 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 runninginstances.
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
.
As JAVA SDK and Ruby SDK are both hitting the same AWS EC2 APIs, there must be similar settings in JAVA SDK.
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 中必须有类似的设置。
Also, Your question is vague in the sense, are you running the JAVA code from the instance whose Instance id is needed? OR Are you running the java code from a different instance and want to pull the instance-ids of all the running instances?
此外,您的问题在某种意义上是模糊的,您是否从需要实例 ID 的实例运行 JAVA 代码?或者您是否正在从不同的实例运行 java 代码并想要提取所有正在运行的实例的实例 ID?
UPDATE:
更新:
Updating the answers as the question has changed:
随着问题的变化更新答案:
AWS provides meta-data service on each instance that is launched. You can poll the meta-data service locallyto find out the needed information.
AWS 在每个启动的实例上提供元数据服务。您可以在本地轮询元数据服务以找出所需的信息。
Form bash promp, below command provided the instance-id and the public IP address of the instance
表单 bash promp,下面的命令提供了实例的实例 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. 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.
您需要弄清楚如何从 java 中的上述 URL 中提取数据。在这一点上,你有足够的信息,这个问题与 AWS 无关,因为现在这更像是一个关于如何轮询 URL 的 JAVA 问题。
回答by Julio Faerman
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
回答by DGolberg
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; just replace .getPrivateIPAddress()
with the appropriate get command for the info you seek. List of available commands can can be found here.
您还可以使用它来获取有关运行 Java 程序的当前实例的各种相关信息;只需.getPrivateIPAddress()
为您寻找的信息替换为适当的 get 命令。可以在此处找到可用命令的列表。
Edit: For those that might shy away from using this due to the "unknown" URL; see Amazon's documentation on the topic, which points directly to this same URL; the only difference being they're doing it via cli rather than inside Java. http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
编辑:对于那些由于“未知”网址而可能回避使用它的人;请参阅亚马逊关于该主题的文档,该文档直接指向同一个 URL;唯一的区别是他们是通过 cli 而不是在 Java 中完成的。http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
回答by heldeen
You want the com.amazonaws.util.EC2MetadataUtilsclass from the aws-java-sdk.
您需要来自 aws-java-sdk的com.amazonaws.util.EC2MetadataUtils类。
回答by knalli
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. But in the nutshell, that's it.
除非 Java8 可用,否则这将需要更多的样板代码。但简而言之,就是这样。
https://stackoverflow.com/a/30317951/525238has already mentioned the EC2MetadataUtils, but this here includes working code also.
https://stackoverflow.com/a/30317951/525238已经提到了 EC2MetadataUtils,但这也包括工作代码。
回答by Max Dor
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
回答by Filipe Luchini
I was needing to do many operations with 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:
我需要使用 Amazon EC2 执行许多操作。然后我为这个操作实现了一个实用程序类。也许它对到达这里的人有用。我使用 AWS SDK for java version 2 实现。操作是:
- 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:
凭据.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/