外部连接到Kubernetes中的Mongodb集群

时间:2019-01-07 20:30:36

标签: java mongodb kubernetes

我已经使用mongo k8s sidecar在kubernetes上设置了3个成员副本集mongo集群。我需要在外部公开mongodb服务,因此创建了LoadBalancer。

这是服务的外观

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

尝试使用mongodb shell 3.6正常连接 mongo --host xxx.yyy.elb.amazonaws.com

但是在Java客户端代码中,我看到以下异常。 java.net.UnknownHostException: mongo-1.mongo.dev.svc.cluster.local

我可以确认mongo pod已启动并正在运行。我能够从集群中的其他Pod连接到mongo-只是无法从外部访问它。

我不明白的是Java客户端中到底发生了什么。

如下创建Java客户端(使用spring-data-mongo进行配置)。

MongoClient mongoClient = new MongoClient( "xxx.yyy.elb.amazonaws.com" , 27017 );

全栈跟踪如下

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)

即使我已通过负载均衡器地址,为什么mongoClient仍使用pod名称?我该如何解决?

预先感谢

1 个答案:

答案 0 :(得分:2)

您遇到mongo-1.mongo.dev.svc.cluster.local的错误,这是群集内的内部端点。换句话说,这就是从集群中的其他Pod进入Mongo实例的方式。

在Java客户端上,您需要使用xxx.yyy.elb.amazonaws.com:27017作为Mongo端点配置。

类似这样的东西:

MongoClient mongoClient = new MongoClient( "xxx.yyy.elb.amazonaws.com" , 27017 );

为了给您提供路径概述,您的Mongo实例通过27017端口上的LoadBalancer Kubernetes服务公开。

然后,流量进入负载均衡器,并从那里转发到端点100.14.1.3:27017等。

然后从那里,它们在每个节点的NodePort 30994上进入Node。

然后有运行pod的节点回答一个答案。

容器本身的Mongo进程在端口27017上运行,因此,当流量到达端口30994上的节点时,容器运行时会将流量转发到容器中的应用程序到{{1 }}。