4

Using recent client libraries (pymongo 3.4, mongodb (nodejs) 2.2.27), I am having trouble connecting to my mongodb servers with replication. The replicaset configuration contains either the internal ips of the servers or the hostnames. I'm getting the following error:

pymongo.errors.ServerSelectionTimeoutError: mongodbdriver20151129-arbiter-1:27017: [Errno 8] nodename nor servname provided, or not known,mongodbdriver20151129-instance-1:27017: [Errno 8] nodename nor servname provided, or not known,mongodbdriver20151129-instance-2:27017: [Errno 8] nodename nor servname provided, or not known

or

pymongo.errors.ServerSelectionTimeoutError: 10.0.0.5:27017: timed out,10.0.0.6:27017: timed out,10.0.0.4:27017: timed out

I am currently working around it by changing the replicaset config to contain the external ips for the servers but I guess that would slow down the inter-server communication. How can I connect to my servers from an external location with the original rsconf?

[update] Note: I am trying to connect to the external ip of the servers and this worked fine when using pymongo 2.8 or mongodb (js) 2.1.4

[update] Follow this chat for more details/examples

njLT
  • 464
  • 6
  • 21
  • `10.x.x.x` is a "private IP range". I presume your replica set members are actually not on your local network, which would explain the time out errors. It would seem you either need public addresses or something along the lines of an SSH tunnel – Neil Lunn Aug 09 '17 at 09:02
  • for the same replica config, connecting via the older version of the libraries work. I am connecting to the external ip, eg `mongodb://13.85.**.***:27017/`, but the new libraries then try to connect to the hosts specified in the rsconfig instead of the ips specified. – njLT Aug 09 '17 at 10:04
  • This is by design. Unless both your "client application" and the "replica set members" are actually able to be on the same network ( at least with respect to routing rules ) then the external addresses are required for configuration between nodes. This has always been the case. What you specify in the "client connection" is merely a **seed list**. There is no such thing as specifying different internal and external usage. Never has been. – Neil Lunn Aug 09 '17 at 10:08
  • then why don't i get the error when using the older versions (of the client libraries) for the same replica set? – njLT Aug 09 '17 at 10:12
  • So where is this example? Either show an example that says otherwise or just accept that you are mistaken. Nothing here to show that would be the case, and all documentation I am aware of says otherwise. – Neil Lunn Aug 09 '17 at 10:15
  • I'll setup a demo replicaset and provide the details. We are currently using older libraries, mongoose 4.4.0, which works fine with our servers and on updating to mongoose 4.11.1 we get the error stated above - so I don't think I am mistaken, but I might not be conveying the issue correctly. – njLT Aug 09 '17 at 10:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/151480/discussion-between-njlt-and-neil-lunn). – njLT Aug 09 '17 at 10:39

1 Answers1

4

Later versions of all officially supported MongoDB drivers (including the node driver) follows the Server Discovery and Monitoring spec (SDAM), which mandates that all drivers to monitor all nodes in a replica set (see Monitoring).

The reason for this monitoring is to be able to discover the status of the whole replica set at all times, and reconnect to a new primary should the current primary goes offline for any reason. See What's the point of periodic monitoring

To be able to monitor all nodes in a replica set, the driver must have access to each of the replica set member. Since your replica set is defined using internal IPs inaccessible by the driver, the driver cannot connect to them. This is the reason for the error you're seeing.

There are a couple of ways to solve this issue:

  1. Use IP addresses or hostnames for the replica set configuration that are accessible by the driver (recommended).
  2. Connect to one of the nodes without specifying a replica set, essentially treating the node as a standalone (not recommended).

If the older driver can connect without complaint, then either the driver is very outdated or doesn't follow the proper SDAM spec and should not be used, since its behaviour cannot be guaranteed. MongoDB publishes the SDAM spec and mandates all drivers to follow it for a good reason.

kevinadi
  • 13,365
  • 3
  • 33
  • 49
  • I am using the public ip in the rsconfig for new deployments. Is it possible to still get the servers to communicate with themselves using the internal IP? Updating /etc/hosts works for hostnames, but then I would have to purchase a domain, right? – njLT Aug 10 '17 at 08:27
  • I'm not sure I understand. If each server has a public and private IP, it shouldn't matter which IP you use since both point to the same server. Another thing you can do is to put the application _inside_ the private network (so it can connect to the replica set using private IPs) and access the application using the public IP from outside via public-facing API. The drawback is you have to design the API, but this would be more secure since your database is inaccessible from the internet. – kevinadi Aug 11 '17 at 00:21