I am receiving an java.net.UnknownHostException: postgres-service
on a machine where I can ping postgres-service
on the command line. This is in the context of Kubernetes (more specifically GKE) services and Docker images. Could it be that Java requires additional packages (in comparison to ping
) to be installed before it can resolve symbolic IP addresses such as postgres-service
? I meanwhile guess the answer is no, and that the problem lies with resolving postgres-service
via kube-dns
is this particular situation (see UPDATE).
UPDATE The evidence (including the stacktrace below) suggests that the exception is triggered when Tomcat 9 tries to set-up a JDBC realm with connectionURL="jdbc:postgresql://postgres-service/mydb"
. The URL is configured in the context descriptor of a web app, which runs inside a Docker image derived from tomcat:9
. The context descriptor is generated by a script configured as the image's ENTRYPOINT
, which also starts Tomcat (just like the original tomcat:9
does), i.e. the last few lines of the Dockerfile
look as follows:
COPY tomcat-entrypoint.sh /
ENTRYPOINT [ "/tomcat-entrypoint.sh" ]
CMD ["catalina.sh", "run"]
I can ping postgres-service
after entering a shell with kubectl exec -it <image> bash
. Could it be that Tomcat (when run as the image's "single process" with pid 1 by way of the Dockerfile's CMD
) sees a different DNS configuration than bash
that runs at its sibling? The actual DNS configuration employs kube-dns
, as is apparent from /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
I had been using a VM instance without scope compute-rw
for development so far (see here). I've now recreated it including that scope and rebuilt all relevant Docker images there. Apparently this has resolved the issue.
UPDATE There was also a second issue in that I had clusterIP: None
as part of the service specification of postgres-service
(now gone). It beats me why I was still able to ping postgres-service
from another pod in the same cluster.