Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Docker上的java.net.UnknownHostException_Java_Dns_Docker - Fatal编程技术网

Docker上的java.net.UnknownHostException

Docker上的java.net.UnknownHostException,java,dns,docker,Java,Dns,Docker,我正在尝试为ZooKeeper创建docker容器,并在集群模式下配置它们(完整代码为和) 容器基于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 do

我正在尝试为ZooKeeper创建docker容器,并在集群模式下配置它们(完整代码为和)

容器基于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 hub上提供,您可以试用)

如果在启动第二个和第三个容器之前等待一段时间,那么主机名
zk2
zk3
被放入
/etc/hosts
太晚了(docker),Java无法找到它们:我在
zk1
的日志中为
zk2
zk3
找到了
Java.net.UnknownHostException

我在web上发现需要禁用JVM DNS缓存以刷新主机名,因此我在
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

变量
networkaddress.cache.negative.ttl
已设置为其默认值(
10

行为没有改变。我反复得到很多
java.net.UnknownHostException


问题的原因是什么?

我通过切换到Oracle JRE 8并在Dockerfile中使用以下黑客程序,成功地解决了DNS问题:

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

我在上创建了一个工作的Java 8 docker容器(代码处于打开状态)。

在我的例子中,Java应用程序在docker中运行时出现了
Java.net.UnknownHostException
故障。原因是我使用了
--network=none
docker标志(通过dhcp和管道获取ip/主机名)。在这种情况下,docker不会像这样自动添加到
/etc/hosts
条目中

127.0.0.1 15e326aecf84

getCanonicalHostName()
Java函数引发了此异常

可能的解决办法:

  • 通过
    docker run
    参数
    --hostname=your hostname.com
  • 切换到docker管理的网络配置

如果我没有弄错这种情况:您的第一个命令将引入一个新的docker实例,其主机名为zk1,并指示它与zk2和zk3组成一个集群。。。然后。。。如果通过执行第2行和第3行创建zk2和zk3的速度不够快,那么第1行将失败,因为无法找到下两个集群成员的主机。这就是你正在经历的吗?几乎是。第一个节点不断尝试联系zk2和zk3,但java网络堆栈始终使用关于它们的旧信息(即它们不存在)。新容器创建后会放入/etc/hosts,但java似乎忽略了该文件。最终目的是允许在运行时将容器附加到ZooKeeper集群。我引入了延迟来开始测试这种情况。我明白了。我认为你的想法是正确的,但是你使用了错误的变量。由于最初DNS解析失败,您应该禁用负缓存。检查此变量的当前值(相同的java.security文件):networkaddress.cache.negative.ttl。默认情况下,它可能在10上,但如果不是,则值得将其设置为较低的数字。您是对的,但我检查了
networkaddress.cache.negative.ttl,并将其显式设置为默认值(10)。