I am trying to bring a Java app up inside of an AWS ECS container and Java is unable to lookup the hostname.
ECS sets the hostname and sets up /etc/hosts and /etc/resolv.conf correctly. If I do nslookup `hostname` I get resolution just fine. I can also resolve that against the name server set in /etc/resolv.conf
But if I start the java application that attempts to resolve the hostname I get an exception that indicated that the hostname cannot be resolved.
java -version output:
bash# java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
So I wrote a small test program:
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.PrintWriter;
import java.io.StringWriter;
public class DomainResolutionTest {
public static void main(String[] args) {
try {
InetAddress ip = InetAddress.getLocalHost();
System.out.println(ip.toString());
}catch (UnknownHostException uhx) {
System.out.println("ERROR: " + uhx.getMessage() + "\n" + getStackTrace(uhx));
Throwable cause = uhx.getCause();
if (cause != null) System.out.println("CAUSE: " + cause.getMessage());
}
}
public static String getStackTrace(Throwable t)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
t.printStackTrace(pw);
pw.flush();
sw.flush();
return sw.toString();
}
}
Which throws the following error when the hostname is 'f17a0bdca449':
ERROR: f17a0bdca449: f17a0bdca449: unknown error
java.net.UnknownHostException: f17a0bdca449: f17a0bdca449: unknown error
at java.net.InetAddress.getLocalHost(InetAddress.java:1484)
at DomainResolutionTest.main(DomainResolutionTest.java:11)
Caused by: java.net.UnknownHostException: f17a0bdca449: unknown error
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:907)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1302)
at java.net.InetAddress.getLocalHost(InetAddress.java:1479)
... 1 more
CAUSE: f17a0bdca449: unknown error
If I switch java to use the ipv4 stack using -Djava.net.preferIPv4Stack=true I get:
$> java -Djava.net.preferIPv4Stack=true DomainResolutionTest
ERROR: f17a0bdca449: f17a0bdca449: unknown error
java.net.UnknownHostException: f17a0bdca449: f17a0bdca449: unknown error
at java.net.InetAddress.getLocalHost(InetAddress.java:1484)
at DomainResolutionTest.main(DomainResolutionTest.java:11)
Caused by: java.net.UnknownHostException: f17a0bdca449: unknown error
at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:907)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1302)
at java.net.InetAddress.getLocalHost(InetAddress.java:1479)
... 1 more
CAUSE: f17a0bdca449: unknown error
If I force it to use the sun implementation and specify NAMESERVER and SEARCH_DOMAIN I STILL get the same thing:
$> export NAMESERVER=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
$> export SEARCH_DOMAIN=$(cat /etc/resolv.conf | grep search | awk '{print $2}')
$> java -Dsun.net.spi.nameservice.provider.1=dns,sun -Dsun.net.spi.nameservice.nameservers=${NAMESERVER} -Dsun.net.spi.nameservice.domain=${SEARCH_DOMAIN} -Djava.net.preferIPv4Stack=true DomainResolutionTest
ERROR: f17a0bdca449: DNS name not found [response code 3]
java.net.UnknownHostException: f17a0bdca449: DNS name not found [response code 3]
at java.net.InetAddress.getLocalHost(InetAddress.java:1484)
at DomainResolutionTest.main(DomainResolutionTest.java:11)
Caused by: java.net.UnknownHostException: DNS name not found [response code 3]
at sun.net.spi.nameservice.dns.DNSNameService.resolve(DNSNameService.java:180)
at sun.net.spi.nameservice.dns.DNSNameService.lookupAllHostAddr(DNSNameService.java:351)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1302)
at java.net.InetAddress.getLocalHost(InetAddress.java:1479)
... 1 more
CAUSE: DNS name not found [response code 3]
I am at my wits end. Any suggestions?
The host information you are getting is hostname of the docker container. This problem is not unique to ecs, this is true to any java application running within docker container.
With ECS you do not have the option of injecting the hostname as a runtime config.
A better solution when running in AWS environment will be to use AWS metadata service to get the hostname.
A http GET request to the AWS metadata service, should get you the details of the host.
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html
In case you have java aws sdk included in your application, you can leverage the following class http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/util/EC2MetadataUtils.InstanceInfo.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With