I am trying to create docker containers for ZooKeeper and configure them in cluster mode (full code is here and here).
Containers are based on Alpine Linux (alpine:3.2 on Docker Hub), but the problem that I'm going to describe happens also with the official Java container (java:7).
I use the following commands to start the cluster:
docker run -d -h zk1 --name zk1 dockmob/zookeeper -s zk1,zk2,zk3
# wait some time ...
docker run -d -h zk2 --name zk2 dockmob/zookeeper -s zk1,zk2,zk3
docker run -d -h zk3 --name zk3 dockmob/zookeeper -s zk1,zk2,zk3
(They are available on docker hub, you can try them).
If I wait some time before starting the second and third containers, then the host names zk2
and zk3
are put in /etc/hosts
too late (by docker), and Java is unable to find them: I get java.net.UnknownHostException
in the logs of zk1
for both zk2
and zk3
.
I found on the web that I need to disable JVM DNS cache in order to refresh the host names, so I introduced the following command in the Dockerfile
in order to update the java.security
settings:
RUN grep '^networkaddress.cache.ttl=' /usr/lib/jvm/java-1.7-openjdk/jre/lib/security/java.security || echo 'networkaddress.cache.ttl=10' >> /usr/lib/jvm/java-1.7-openjdk/jre/lib/security/java.security
It sets the DNS TTL property (networkaddress.cache.ttl
) to 10
seconds.
The variable networkaddress.cache.negative.ttl
is already set to its default value (10
).
The behavior does not change. I get lots of java.net.UnknownHostException
repeatedly.
What can be the cause of the problem?
In my case the java application was failing with java.net.UnknownHostException
when running in docker. The reason was that I used --network=none
docker flag (getting ip/hostname via dhcp and pipework). In this case, docker does not add automatically to /etc/hosts
entry like
127.0.0.1 15e326aecf84
And getCanonicalHostName()
Java function threw this exception.
Possible solutions:
/etc/hosts
file via docker run
parameter --hostname=your-hostname.com
I managed to get rid of the DNS issues by switching to Oracle JRE 8 and using the following hack in the Dockerfile:
RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
I created a working Java 8 docker container container on Docker Hub (the code is on github).
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