Docker上的java.net.UnknownHostException

我正在尝试为ZooKeeper创builddocker容器并将其configuration为集群模式(完整的代码在这里和这里 )。

容器基于Alpine Linux(Docker Hub上的Alpine:3.2),但是我要描述的问题也是在官方Java容器(java:7)中发生的。

我使用以下命令启动集群:

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 

(他们可以在docker集线器上,你可以试试他们)。

如果我在启动第二个和第三个容器之前等待一段时间,那么主机名zk2zk3太晚(由docker),并且Java不能find它们:我得到java.net.UnknownHostException zk2zk3zk1的日志。

我在网上发现我需要禁用JVM DNScaching才能刷新主机名,所以我在Dockerfile中引入了以下命令来更新java.security设置:

 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 

它将DNS TTL属性( networkaddress.cache.ttl )设置为10秒。

variablesnetworkaddress.cache.negative.ttl已被设置为默认值( 10 )。

行为不会改变。 我反复得到了很多的java.net.UnknownHostException

什么可能是问题的原因?

在我的情况下(java应用程序在--network=none运行时出现java.net.UnknownHostException时失败),原因是我使用--network=none标志(通过dhcp和pipework获取ip / hostname)。 在这种情况下,docker不会自动添加到/etc/hosts条目中

127.0.0.1 15e326aecf84

getCanonicalHostName() Java函数抛出这个exception。

可能的解决scheme:

  • 通过--hosname=your-hostname.com docker run参数将主机名项添加到/etc/hosts文件--hosname=your-hostname.com
  • 切换到dockerpipe理的networkingconfiguration

我设法通过切换到Oracle JRE 8并在Dockerfile中使用以下hack来摆脱DNS问题:

 RUN echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf 

我在Docker Hub上创build了一个可用的Java 8 docker容器容器(代码位于github上 )。