Add hostname to monitor MongoDB Replica Set in Icinga2 - mongodb

I have a distributed Mongodb setup and I'm trying to configure it with Icinga2 using the following link as reference,
https://admin-docs.com/databases/mongodb/mongodb-administration/monitor-mongodb-using-icinga/
As mine is a distributed setup, Icinga should connect to Mongodb along with hostname parameter as,
mongo -h ipaddress
Without this, Icinga2 dashboard shows the following error for all the MongoDB monitoring services,
CRITICAL - Connection to Mongo server on 127.0.0.1:27017 has failed
How do I configure my Icinga2 setup to use hostname in the command?

Finally got it working, pretty simple, just had to set the variable value for mongodb_address using the following,
apply Service "Mongodb Connection" {
check_command = "mongodb"
command_endpoint = host.vars.client_endpoint
vars.mongodb_address = "$address$"
assign where host.vars.client_endpoint && host.vars.os == "MongoOnLinux"
}
Here, $address$ is in built variable for host IP Address

Related

Cannot connect to local mongodb from jupyter docker-stacks container

I am using the jupyter/scipy-notebook image and want to connect to a MongoDB that runs locally on MacOS (port-forwarded through K8). I cannot get this to work. I can connect from the docker to the host using "host.docker.internal" but cannot reach MongoDB.
I tried two different approaches
A. Using the network flag to avoid the issue entirely:
docker run --network="host" jupyter/scipy-notebook:b418b67c225b
Result: Cannot reach the notebook at all on localhost:8888
B. Running the image without the network flag and connect to "host.docker.internal" when using the MongoDB.
docker run -p 8888:8888 jupyter/scipy-notebook:b418b67c225b
client = MongoClient("mongodb://host.docker.internal:27017/?readPreference=primary&ssl=false")
db = client["foo"]
db.list_collection_names()
Result: Some kind of topology error:
ServerSelectionTimeoutError: Could not reach any servers in ........ [Errno -3] Temporary failure in name resolution')>]>
Any ideas?

mongodb dump fails with cannot unmarshal DNS message

I am using a mongo db server version MongoDB shell version v4.0.16 installed on a EC2 instance.
I am able to get into the instance using mongo command
mongo mongodb+srv://dxxxxxxx:xxxxxx[][]#cluster0-vxcen.gcp.mongodb.net
MongoDB shell version v4.0.16
connecting to: mongodb://cluster0-shard-00-02-vxcen.gcp.mongodb.net.:27017,cluster0-shard-00-01-vxcen.gcp.mongodb.net.:27017,cluster0-shard-00-00-vxcen.gcp.mongodb.net.:27017/?authSource=admin&gssapiServiceName=mongodb&replicaSet=Cluster0-shard-0&ssl=true
2020-03-05T09:02:45.265+0000 I NETWORK [js] Starting new replica set monitor for Cluster0-shard-0/cluster0-shard-00-02-vxcen.gcp.mongodb.net.:27017,cluster0-shard-00-01-vxcen.gcp.mongodb.net.:27017,cluster0-shard-00-00-vxcen.gcp.mongodb.net.:27017
2020-03-05T09:02:45.604+0000 I NETWORK [ReplicaSetMonitor-TaskExecutor] Successfully connected to cluster0-shard-00-00-vxcen.gcp.mongodb.net.:27017 (1 connections now open to cluster0-shard-00-00-vxcen.gcp.mongodb.net.:27017 with a 5 second timeout)
2020-03-05T09:02:45.607+0000 I NETWORK [js] Successfully connected to cluster0-shard-00-01-vxcen.gcp.mongodb.net.:27017 (1 connections now open to cluster0-shard-00-01-vxcen.gcp.mongodb.net.:27017 with a 5 second timeout)
2020-03-05T09:02:45.707+0000 I NETWORK [js] changing hosts to Cluster0-shard-0/cluster0-shard-00-00-vxcen.gcp.mongodb.net:27017,cluster0-shard-00-01-vxcen.gcp.mongodb.net:27017,cluster0-shard-00-02-vxcen.gcp.mongodb.net:27017 from Cluster0-shard-0/cluster0-shard-00-00-vxcen.gcp.mongodb.net.:27017,cluster0-shard-00-01-vxcen.gcp.mongodb.net.:27017,cluster0-shard-00-02-vxcen.gcp.mongodb.net.:27017
2020-03-05T09:02:46.010+0000 I NETWORK [js] Successfully connected to cluster0-shard-00-00-vxcen.gcp.mongodb.net:27017 (1 connections now open to cluster0-shard-00-00-vxcen.gcp.mongodb.net:27017 with a 5 second timeout)
2020-03-05T09:02:46.028+0000 I NETWORK [ReplicaSetMonitor-TaskExecutor] Successfully connected to cluster0-shard-00-01-vxcen.gcp.mongodb.net:27017 (1 connections now open to cluster0-shard-00-01-vxcen.gcp.mongodb.net:27017 with a 5 second timeout)
2020-03-05T09:02:46.439+0000 I NETWORK [js] Successfully connected to cluster0-shard-00-02-vxcen.gcp.mongodb.net:27017 (1 connections now open to cluster0-shard-00-02-vxcen.gcp.mongodb.net:27017 with a 5 second timeout)
Implicit session: session { "id" : UUID("1c7432d5-e09c-45f8-8d84-d47e4f572cbf") }
MongoDB server version: 4.2.3
WARNING: shell and server versions do not match
Error while trying to show server startup warnings: user is not allowed to do action [getLog] on [admin.]
MongoDB Enterprise Cluster0-shard-0:PRIMARY>
I am trying to connect to a mongo db Atlas to get the database using mongodump
mongodump --uri="mongodb+srv://dxxxxxxx:xxxxxx[][]#cluster0-vxcen.gcp.mongodb.net/xxxxxxxxxx"
I am facing issues with
error parsing command line options: error parsing uri (mongodb+srv://dxxxxxxx:xxxxxx[]#cluster0-vxcen.gcp.mongodb.net/xxxxxxxxxx): lookup cluster0-vxcen.gcp.mongodb.net on 127.0.0.53:53: cannot unmarshal DNS message
This is just a case of incompatible DNS server.
Locate /etc/resolv.conf file and replace the nameserver with 8.8.8.8, and everything should work just fine. If that does not work , try 1.1.1.1.
This issue is simmilar to the one reported here.
The fix for changing resolv.conf as above seems not to persist reboots.
The workaround proposed in the link above is either to use non srv url, or, a simpler way that and as far as I have seen survives reboots as well, is to remove the symlink /etc/resolve.conf and replace it with a static file containing the required DNS server.
Another option, found here
Suggests installing resolvconf (for Ubuntu apt install resolvconf), add the line nameserver 8.8.8.8 to /etc/resolvconf/resolv.conf.d/base, then run sudo resolvconf -u and to be sure service resolvconf restart.
To verify run systemd-resolve --status.
You should see on the first line your DNS server like here:
DNS Servers: 8.8.8.8
DNS Domain: sa-east-1.compute.internal
DNSSEC NTA: 10.in-addr.arpa
16.172.in-addr.arpa
Two solutions that worked for me:
Add nameserver with value 8.8.8.8 or 1.1.1.1 additionally to existing ones in /etc/resolve.conf file
Use connection string in format mongodb://{db}:{pass}#hostname1.mongodb.net,hostname2.mongodb.net,hostname3.mongodb.net/admin?authSource=admin&replicaSet={replicaSet}&readPreference=primary&ssl=true instead of mongodb+srv:// format
To get the formatted connection string, you can use db.getMongo() command on your cluster
In some causes, for example in environment where you can't change resolver you can use old style URL:
client = pymongo.MongoClient("mongodb://<username>:<password>#<cluster>...
After change URL generated by cloud.mongodb.com Atlas
in section Cluster -> Connect -> Choose a connection method -> Python - 3.4 or later
It finally started working.
My setup:
Ubuntu 18.04
Python 2.7.17 / 2.7.12
Pymongo 3.11.1
Google Cloud SDK 319.0.0
In my case, only MongoDB connections went wrong with my DNS server.
However, it worked with Google DNS 8.8.8.8, as suggested above.
The solution for me was to decrease the UDP max packet size (same as Google DNS)
cat /etc/bind/named.conf.options
options {
#...
listen-on { 127.0.0.1; };
allow-recursion { 127.0.0.1; ::1; };
edns-udp-size 512;
max-udp-size 512;
};

Why do I get an "message len 1347703880 is invalid. Min 16 Max: 48000000" error when trying to connect to an OKD pod running a simple mongo container?

I have created a Mongo container using only the base mongo:3.6.4 official docker image and deployed it to my OpenShift OKD cluster, but cannot connect to this MongoDB instance using a Mongo client from outside the cluster.
I can access the pod at http://mongodb.my.domain and successfully get the "It looks like you are trying to access MongoDB over HTTP on the native driver port." message.
When using the terminal on the pod I can successfully log-in using:
mongo "mongodb://mongoadmin:pass#localhost" --authenticationDatabase admin
But when trying to connect from outside OKD the connection fails.
My client needs to pass through a proxy before it can access the OKD pods and I do have a .der certificate file but am unsure if this is related to the issue.
Some commands I have tried:
mongo "mongodb://mongoadmin:pass#mongodb.my.domain:80" --authenticationDatabase admin
mongo --ssl "mongodb://mongoadmin:pass#mongodb.my.domain:80" --authenticationDatabase admin
I expected to be able to connect successfully but instead get this error message:
MongoDB shell version v3.4.20
connecting to: mongodb://mongoadmin:pass#mongodb.my.domain:80
2019-05-15T11:32:25.514+0100 I NETWORK [thread1] recv(): message len 1347703880 is invalid. Min 16 Max: 48000000
2019-05-15T11:32:25.514+0100 E QUERY [thread1] Error: network error while attempting to run command 'isMaster' on host 'mongodb.my.domain:80' :
connect#src/mongo/shell/mongo.js:240:13
#(connect):1:6
exception: connect failed
I am unsure if it an issue with how I am using my MongoDB client or potentially some proxy settings on my OKD cluster. Any help would be appreciated.
The problem here is that external OpenShift routes aren't great at handling database connections. When you attempt to connect to the Mongo pod via the route, the route will accept the connection and transmit your connection to the Mongo service. I believe this transmission wraps the connection in in a HTTP wrapper, which Mongo doesn't like to handle. The OKD documentation highlights that path based route traffic should be HTTP based, which will cause the connection to fail.
You can see evidence of this when trying to connect to a MongoDB database and it returns "It looks like you are trying to access MongoDB over HTTP on the native driver port." to the browser. The user relief.malone explains this and has proposed a couple of solutions / workarounds in their answer to this question.
To add to relief.malone's answer, I would suggest that you port forward from the MongoDB pod to your local machine for development/debugging. In production, you could deploy an application to OKD that references the MongoDB service via it's internal DNS name, which will look something like this: mongodb.project_namespace.svc:27017. This way you will avoid the route interfering with the connection.
The Openshift OKD documentation on port-forwarding isn't that informative, but, since oc runs the kubectl command under the hood, you can read this Kubernetes guide to get some more information

"Server Selection Timeout Error" MongoDB Go Driver with Docker

I'm working on a very basic (I thought) starter program in Go using MongoDB and Docker. Trying to get a handle on these before we start using them at work.
I've got my MongoDB running in a docker container, just using my local host, using the official Docker image. This is running fine, I can connect to it through MongoDB Compass and modify the DB.
My next task was to build a separate Docker container that is able to read and write to the DB. I'm using MongoDB-Go-Driver (https://godoc.org/github.com/mongodb/mongo-go-driver/mongo) for this as mgo is no longer kept up.
This is my code, I'm just following the numerous tutorials online to make a simple connection and then ping the DB to ensure connectivity.
client, err := mongo.Connect("mongodb://localhost:27017")
if err != nil {
log.Fatal("error ", err)
}
// Check the connection
err = client.Ping(context.TODO(), nil)
if err != nil {
log.Fatal("error2 ", err)
}
fmt.Println("Connected to MongoDB!")
It always fails on doing any operation on the DB (Find, FindOne, Ping, etc.) with error2 server selection timeout
This is my docker-compose file I'm running.
version: "3"
services:
datastore:
image: mongo
ports:
- "27017:27017"
networks:
- maccaptionNet
volumes:
- .:/go/src/maccaption_microservice/dbdata
jobservice:
image: jobservicemaccaption:1.0
networks:
- maccaptionNet
depends_on:
- "datastore"
networks:
maccaptionNet:
driver: bridge
I'm brand new to MongoDB and after hours of research haven't made any progress on this.
I've read through https://docs.mongodb.com/manual/core/read-preference-mechanics/
https://docs.mongodb.com/manual/replication/
Can anyone point me in the right direction for this? I haven't been able to find a lot on this specific issue.
Thanks!
When you running the service and mongodb in docker you can't use localhost since the service is in a different container than mongodb, and from docker point of view it's under a different ip address.
You can connect with the service name you specify in docker-compose datastore
mongo.Connect("mongodb://datastore:27017")
Edit:
from: https://docs.docker.com/compose/networking/
By default Compose sets up a single network for your app. Each
container for a service joins the default network and is both
reachable by other containers on that network, and discoverable by
them at a hostname identical to the container name
Meaning that if you run multiple containers via compose, you can access one container from the other by the container name,
Basically when docker-compose starts, it sets up the network, and each container in the compose joins the network under its container name. For a container's point if view, localhost is just the container itself, while he can search for other container's name and get back the container’s IP address.
Assuming that the docker is running on your localhost, you can set the name in etc/hosts file like this:
127.0.0.1 datastore
(if not just replace 127.0.0.1 with the docker ip)
And in the app you will connect with mongodb://datastore:27017
So you will be able to run the service both in the docker and from outside, if you'll decide to run only the db in docker
docker-compose start datastore
If you are connecting to one docker from another (like it is written in your docker-compose file, and using bridge network mode, you have to change your localhost to the hostname, like datastore
client, err := mongo.Connect("mongodb://datastore:27017")
When your go script uses localhost, it expects the database to located in the same docker
I think my answer might be unrelated but still, I was getting the same error and it was because my IP address was not listed in the IP whitelist tab in MongoDB atlas, so make sure you have your IP address there before trying to connect.
I had the same problem but found another way to address this issue. You can just pass network parameter while running docker image and this way docker points to correct localhost.
docker run --network="host" ....
Source for this solution
Somehow i've fix this problem in a different way: by changing ports from "27018:27017" to "27017:27017".
IDK why this helps. Maybe if Mongo sees not default port it thinks there are cluster of Mongo's nodes.
I got this problem when I tired to connect to
mongodb v4.0.10
with
pymongo==4.0.2 not worked
pymongo==3.12.3 worked
Check your packages
mongodb v5.0.2 works with pymongo==4.0.2

How can I conect a NodeJS app to a MongoDB running in a Docker container on AWS?

I am attempting to deploy my first MEAN stack application ('weatherapp') to production on AWS.
I deployed my NodeJS/Express/Angular app to AWS Elastic Beanstalk (preconfigured Linux machine running Node). This works fine and I can view the app in the browser.
Separately I created a docker container running MongoDB and deployed it to AWS / EC2 following the steps in this post:
https://blog.codeship.com/running-mean-web-application-docker-containers-aws/
My question is - how do I connect the two?
In my NodeJS app I was connecting to my local Mongo instance locally like this:
'mongodb://localhost:27017/weatherapp'
What steps can I take to find out what the connection string should be for my production Mongo instance on docker?
Thanks in advance!
The answer to this is two-fold. We need to set some options on the Docker side in the EC2 instance and then some security groups and configuration on the AWS side. First, we'll start on on the Docker container side.
Container
When you run the MongoDB container, you will want to do two things:
Persist the data to disk.
Open the MongoDB port to the container.
To persist the data to disk you will want to do something like -v /data/db:/data/db. This will make the MongoDB data available at /data/db on the host. This makes sure that an accidental deletion or upgrade of the container doesn't lose any data.
Next, we need to publish the MongoDB port so that applications external of Docker can connect to it. The default MongoDB port is 27017 so let's publish that using -p 27017:27017.
If your original command for starting MongoDB was:
docker run --name mymongodb -d mongo
Then the new one would be:
docker run --name mymongodb -d -p 27017:27017 -v /data/db:/data/db
AWS
Now, we need to edit the security group of your EC2 instance and configuration of Elastic Beanstalk.
Security Groups
First, take a look at your Security Groups in the EC2 console. You will have a group for the Elastic Beanstalk application named similar to awseb-e-xanf9hqrw3-stack-AWSEBSecurityGroup-1N2T1AI2H05I8 with a ID similar to sg-07fb8c43. We'll use this ID in the next step so copy it somewhere.
Now find the Security Group attached to your EC2 instance running the Docker container. You will need to add a new rule to this group allowing access to the MongoDB container. Edit the group and add a new inbound rule for:
Type: Custom TCP
Protocol TCP
Port range: 27017
Source: sg-07fb8c43
This will allow the Elastic Beanstalk EC2 instances (using sg-07fb8c43) to access the MongoDB port on your Docker EC2 instance.
Elastic IP
You'll likely want a more static IP address for your EC2 instance in case it reboots. Navigate to the Elastic IPs section of the EC2 console and allocate a new address to your Docker EC2 instance.
The new Elastic IP will be the address you use in your Elastic Beanstalk configuration to connect to MongoDB. If your address was 54.67.29.50 then your application would connect to mongodb://54.67.29.50:27017.
Elastic Beanstalk
Now, instead of hardcoded this address in your Node.js application, you should configure your application to pull the information from an environment variable. In your application, you should read the MongoDB URL from something like process.env.MONGO_URI. Then, in your Elastic Beanstalk application configuration, navigate to the Software Configuration and then down to Environment Properties. Here, you create a property name of MONGO_URI and the value as mongodb://54.67.29.50:27017. This will allow you to easily change the MongoDB instance should it ever change or if you launch multiple environments with different databases.