java.net.UnknownHostException 在 Docker

java.net.UnknownHostException on Docker

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

容器基于 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 上有,你可以试试)。

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

我在网上发现我需要禁用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 中使用以下 hack 设法摆脱了 DNS 问题:

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

我在 Docker Hub (the code is on github 上创建了一个工作 Java 8 docker 容器容器)。

在我的例子中,java 应用程序在 docker 中 运行 时失败并显示 java.net.UnknownHostException。原因是我使用了 --network=none docker 标志(通过 dhcp 和管道获取 ip/hostname)。在这种情况下,docker 不会像

一样自动添加到 /etc/hosts 条目

127.0.0.1 15e326aecf84

getCanonicalHostName() Java函数抛出了这个异常。

可能的解决方案:

  • 通过 docker run 参数 --hostname=your-hostname.com
  • 将主机名条目添加到 /etc/hosts 文件
  • 切换到 docker 托管网络配置