<p>I've used <a href="https://github.com/cvallance/mongo-k8s-sidecar" rel="nofollow noreferrer">mongo k8s sidecar</a> to provision a 3 member replica set mongo cluster on kubernetes. I need to expose mongodb service externally and hence created a LoadBalancer. </p>

<p>This is how the service looks like</p>

<pre><code>LoadBalancer Ingress:     xxx.yyy.elb.amazonaws.com
Port:                     &lt;unset&gt;  27017/TCP
TargetPort:               27017/TCP
NodePort:                 &lt;unset&gt;  30994/TCP
Endpoints:            100.14.1.3:27017,100.14.1.4:27017,100.14.2.5:27017
</code></pre>

<p>Trying to connect using mongodb shell 3.6 works fine
<code>mongo --host xxx.yyy.elb.amazonaws.com</code></p>

<p>But in the java client code I see the following exception.
<code>java.net.UnknownHostException: mongo-1.mongo.dev.svc.cluster.local</code></p>

<p>I can confirm that the mongo pods are up and running. I am able to connect to mongo from other pods within the cluster - just not able to reach it externally. </p>

<p>Few things I don't understand is whats exactly happening in the java client.</p>

<p>The java client (which uses spring-data-mongo for configuration) is being created as follows.</p>

<p><code>MongoClient mongoClient = new MongoClient( "xxx.yyy.elb.amazonaws.com" , 27017 );</code></p>

<p>The fullstack trace is as follows</p>

<p><code>Caused by: com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches com.mongodb.client.internal.MongoClientDelegate$1@161f6623. Client view of cluster state is {type=REPLICA_SET, servers=[{address=mongo-2.mongo.dev.svc.cluster.local:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: mongo-2.mongo.dev.svc.cluster.local}, caused by {java.net.UnknownHostException: mongo-2.mongo.dev.svc.cluster.local}}, {address=mongo-0.mongo.dev.svc.cluster.local:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: mongo-0.mongo.dev.svc.cluster.local}, caused by {java.net.UnknownHostException: mongo-0.mongo.dev.svc.cluster.local}}, {address=mongo-1.mongo.dev.svc.cluster.local:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: mongo-1.mongo.dev.svc.cluster.local}, caused by {java.net.UnknownHostException: mongo-1.mongo.dev.svc.cluster.local}}]
    at com.mongodb.internal.connection.BaseCluster.createTimeoutException(BaseCluster.java:401)
    at com.mongodb.internal.connection.BaseCluster.selectServer(BaseCluster.java:120)</code></p>

<p>Why is the mongoClient using the pod name , even though I've passed the loadbalancer address? How do I fix this?</p>

<p>Thanks in advance</p>

<p>You are getting an error for <code>mongo-1.mongo.dev.svc.cluster.local</code> and that's the internal endpoint within the cluster. In other words, that's how you would get to your Mongo instance from other pods in the cluster.</p>

<p>On the Java client, you need to use <code>xxx.yyy.elb.amazonaws.com:27017</code> as the Mongo endpoint configuration.</p>

<p>Something like this:</p>

<pre><code>MongoClient mongoClient = new MongoClient( "xxx.yyy.elb.amazonaws.com" , 27017 );
</code></pre>

<p>To give you an overview of the path, your Mongo instance is exposed through a <a href="https://kubernetes.io/docs/concepts/services-networking/#loadbalancer" rel="nofollow noreferrer">LoadBalancer</a> Kubernetes Service on port <code>27017</code>.</p>

<p>Then the traffic comes into the load balancer and from there gets forwarded to your endpoints <code>100.14.1.3:27017</code>, etc. </p>

<p>Then from there, they enter the Node on the NodePort <code>30994</code> on each node. </p>

<p>Then the nodes that have a pod running reply with an answer.</p>

<p>The Mongo process in the container itself runs on port <code>27017</code> so the moment the traffic gets to the node on port <code>30994</code> the container runtime forwards the traffic to your application in the container to <code>27017</code>.</p>
