【发布时间】:2016-08-26 21:25:01
【问题描述】:
我在一台机器上收到java.net.UnknownHostException: postgres-service,我可以在命令行上ping postgres-service。这是在 Kubernetes(更具体地说是 GKE)服务和 Docker 映像的上下文中。是不是 Java 需要安装额外的包(与 ping 相比)才能解析符号 IP 地址,例如 postgres-service?同时我猜答案是否定的,问题在于通过kube-dns 解决postgres-service 是这种特殊情况(见更新)。
更新 证据(包括下面的堆栈跟踪)表明,当 Tomcat 9 尝试使用 connectionURL="jdbc:postgresql://postgres-service/mydb" 设置 JDBC 领域时会触发异常。该 URL 在 Web 应用程序的上下文描述符中配置,该应用程序在派生自 tomcat:9 的 Docker 映像中运行。上下文描述符由配置为图像的ENTRYPOINT 的脚本生成,该脚本还启动Tomcat(就像原始的tomcat:9 一样),即Dockerfile 的最后几行如下所示:
COPY tomcat-entrypoint.sh /
ENTRYPOINT [ "/tomcat-entrypoint.sh" ]
CMD ["catalina.sh", "run"]
在使用kubectl exec -it <image> bash 进入shell 后,我可以ping postgres-service。可能是 Tomcat(当通过 Dockerfile 的 CMD 作为镜像的“单个进程”运行时,pid 为 1 时)看到的 DNS 配置与在其兄弟节点上运行的 bash 不同?实际的DNS configuration 使用kube-dns,从/etc/resonf.conf 可以明显看出。
org.postgresql.util.PSQLException: The connection attempt failed.
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:280)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66)
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:211)
at org.postgresql.Driver.makeConnection(Driver.java:407)
at org.postgresql.Driver.connect(Driver.java:275)
at org.apache.catalina.realm.JDBCRealm.open(JDBCRealm.java:661)
at org.apache.catalina.realm.JDBCRealm.startInternal(JDBCRealm.java:724)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5054)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:724)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:700)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:596)
at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1805)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.UnknownHostException: postgres-service
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.postgresql.core.PGStream.<init>(PGStream.java:64)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:150)
... 19 more
【问题讨论】:
-
这取决于您的名称解析配置。另外,什么代码触发了这个异常?
-
@fge 我在触发执行的代码中添加了更多信息。如果我没记错的话,名称解析配置是 Kubernetes 1.3 提供的。
-
您说在 /etc/resolv.conf 中有一个 kube-dns 条目;你能从你的虚拟机/容器/任何东西中解析这个服务器的地址吗?
-
@fge 是的,例如通过从另一个 pod 内部执行
ping postgres-service。 -
我不是在说这个,抱歉造成误解;我想知道您是否可以自行解析
kube-dns的地址。可能是ping程序和Java使用了不同的名称配置。
标签: java ubuntu docker dns kubernetes