Feb 11, 2016

Deploying MongoDB Replica Sets with Docker



I recently set up a 3 Node MongoDB cluster replica set with each Node running MongoDB as a Docker image as the first step to get the same scenario working in Kubernetes. It wasn't very intuitive so I thought I'd write it up so that I could share the recipe.

I started by deploying 3 EC2 instances running Fedora 23 (ami-7b8afa11) and Docker 1.9.1 (the docker version that ships with F23). Make sure your security group has an inbound rule for TCP port 27017 as this is required for MongoDB

On each node, do the following:
1. docker pull mongo 
This pulls the official MongoDB image from the Docker Hub
2. mkdir /mnt/mongo 
This creates a directory on the Host which we will use to persist the Mongo container instances database state. This allows the container to be stopped and restarted without losing any data.
3. chcon -Rt svirt_sandbox_file_t /mnt/mongo
This sets the SELinux label so that the container has permission to access the /mnt/mongo directory on the host.
4. docker run --net=host -d -v /mnt/mongo:/data/db mongo --replSet rs0
This starts the Mongo instance in a replica set called rs0, mounts your /mnt/mongo directory from the host into the container and binds the host's IP to the container instance.

Designate one of your nodes to be your Replica Set Primary, and do the following on that node only:

1. Docker exec into the node: i.e. docker ps, get the container ID and exec in using that ID
[root@node-1] $ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED
85690249e5b3        mongo               "/entrypoint.sh --rep"   32 minutes ago

[root@node-1] $ docker exec -it 85690249e5b3 bash

root@ip-172-31-148-167:/# 
2. Run "mongo" at the container prompt
root@ip-172-31-148-167:/# mongo
MongoDB shell version: 3.2.1
connecting to: test
Welcome to the MongoDB shell.

3. Enter the following command to initiate the replica set
> rs.initiate()
{
 "info2" : "no configuration specified. Using a default configuration for the set",
 "me" : "ip-172-31-148-167.ec2.internal:27017",
 "ok" : 1
}

4. Enter the following to validate the replica set configuration
> rs.conf()

5. Then add the FQDNs of the other 2 EC2 Nodes that you started the MongoD Docker Image on:
> rs.add("ip-172-31-148-218.ec2.internal")
> rs.add("ip-172-31-159-148.ec2.internal")

6. Check the status of Replica Set
> rs.status()

7. Congrats. That's it. You can now import data and test your Replica Set. Keep in mind that only the Primary Node can handle writes but all the other members of the replica set (the secondary nodes) can do reads.

If you want to test the read functionality of the replica set on a secondary node, docker exec into the container on that node, run mongo at the prompt and run the command below before you attempt to run any queries (reads).
rs0:SECONDARY> rs.slaveOk()

No comments: