防火墙后的 Mongo 副本集

防火墙后的 Mongo 副本集

假设您在由 3 个节点组成的网络中运行当前版本 (3.2) 的 MongoDB 作为副本集:

mongo1.local
mongo2.local
mongoarbiter.local

现在这些节点应该可以通过公共互联网访问(通过 FW 限制)。mongo1 和 mongo2 将在防火墙上获得 VIP 和一些有效的 A 记录:

mongo1.example.com
mongo2.example.com

仲裁者没有被暴露。

现在,如果您通过连接字符串传递外部 DNS 名称,某些客户端实现就可以正常工作(python)。但是其他客户端实现(Java)将无法连接,因为副本集只知道其内部名称。客户端将解析 rs 提供的节点列表,注意它所连接的外部名称不在列表中,并且会失败:

Monitor thread successfully connected to server with description ServerDescription{address=mongo1.example.com:27017, type=REPLICA_SET_PRIMARY, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 0, 14]}, minWireVersion=0, maxWireVersion=3, maxDocumentSize=16777216, roundTripTimeNanos=5305689, setName='mongo-rs', canonicalAddress=mongo1.local:27017, hosts=[mongo2.local:27017, mongo1.local:27017], passives=[], arbiters=[mongo3.local:27017], primary='mongo1.local:27017', tagSet=TagSet{[]}, electionId=5821da77ccc118202cd2b75d, setVersion=3}

除了在客户端系统上弄乱 /etc/hosts 之外,还有其他解决方案吗?

顺便说一句:这可以解决 js 客户端库的问题,但看起来也有点脏:

replSet.connectWithNoPrimary

答案1

官方 MongoDB 驱动程序实现服务器发现和监控 (SDAM)规范,可在 GitHub 上的mongodb/specifications存储库。SDAM 规范更详细地说明了驱动程序的预期行为和基本原理。

目前的预期是客户端将始终使用副本集配置中列出的主机名,而不是连接字符串中提供的种子列表。这样做的主要动机是根据商定的副本集配置(包括主机名和端口)启用自动故障转移和重新配置。

除了在客户端系统上弄乱 /etc/hosts 之外,还有其他解决方案吗?

如果您不需要故障转移,则可以连接到单个服务器,而不是使用副本集连接。独立/直接连接不应实现任何服务器发现。

但是,如果您要连接到独立服务器以外的任何设备,那么除了调整主机名解析以匹配副本集配置或扩展网络边界(例如使用 VPN)之外,目前没有其他解决方法。

值得点赞/关注的相关功能建议是:SERVER-1889:支持客户端和复制流量使用不同的网络/网卡. 这可以将副本集的内部网络通信与客户端连接分开。

答案2

如果你设置了一个分片集群,那么你就可以直接连接到蒙戈斯过程,并让其担心副本集中节点的内部/外部主机名。

如果你将副本集作为分片集群,那么所有客户端连接都应该经过蒙戈斯服务器。mongos 维护其与副本集中节点的连接(可以使用内部名称 mongo1.local 等进行连接);客户端仅连接到 mongos,可以使用其喜欢的任何名称进行连接 - 它不必与内部使用的主机名匹配。

因此,即使您不想使用分片进行数据扩展,它也可能有助于避免通过外部主机名寻址副本集的问题?

相关内容