Guide to Set up Replica Sets on MongoDB Servers

Published:13 June 2023 - 9 min. read

Arvid Larson Image

Arvid Larson

Read more tutorials by Arvid Larson!

Having a redundant and replicated database is crucial for applications nowadays. But how exactly? With a MongoDB Replica Set, data replication in your database works like a charm.

A MongoDB Replica Set ensures you always have backup data for your application, or you can use your backup data to recover when a problem arises. And this tutorial will walk you through deploying a MongoDB Replica Set with multiple MongoDB servers.

Get ready and start carrying out a high-availability setup for your data!

Prerequisites

This tutorial comprises hands-on demonstrations. To follow along, ensure you have the following:

  • Three Ubuntu Servers (each with MongoDB installed)- This tutorial uses Ubuntu 22.04 servers with the following details:
HostnameIP AddressFQDN
srv1192.168.5.35srv1.dblocal.lan
srv2192.168.5.36srv2.dblocal.lan
srv3192.168.5.37srv3.dblocal.lan
  • A non-root user with sudo/administrator privileges.

Configuring the /etc/hosts File for Servers to Communicate

Before diving into MongoDB, you must ensure your servers can connect and communicate with each other via fully qualified domain names (FQDNs). How?

You must configure the /etc/hosts file and set up FQDNs for each server.

To prepare your servers, configure the /etc/hosts file as follows:

1. Open a terminal on each server, and run the following hostnamectl commands on their corresponding servers.

These commands do not provide output but set up FQDN for each server.

# Run on srv1 - Setup fqdn to srv1.dblocal.lan
sudo hostnamectl set-hostname srv1.dblocal.lan

# Run on srv2 - Setup fqdn to srv2.dblocal.lan
sudo hostnamectl set-hostname srv2.dblocal.lan

# Run on srv3 - Setup fqdn to srv3.dblocal.lan
sudo hostnamectl set-hostname srv3.dblocal.lan

2. Next, open the /etc/hosts file on each server using your preferred text editor and populate the following configuration. This configuration ensures that each FQDN or hostname is pointed to the correct server IP address.

Replace the values in the configuration with your own accordingly, save the changes, and close the file.

192.168.5.35   srv1.dblocal.lan   srv1
192.168.5.36   srv2.dblocal.lan   srv2
192.168.5.37   srv3.dblocal.lan   srv3

3. Now, run the hostname command below on each server to verify the FQDNs

sudo hostname -f

If successful, you will see the following output for srv1. Similarly, the same output shows for srv2 (srv2.dblocal.lan) and srv3 (srv3.dblocal.lan).

Verifying the server FQDN
Verifying the server FQDN

4. Lastly, run the following statement in the srv1 server to verify that each FQDN points to the correct server IP address.

for i in srv1.dblocal.lan srv2.dblocal.lan srv3.dblocal.lan
do
  ping -c3 $i
done

If correctly configured, each server’s FQDN should point to the corresponding server IP address, as shown below:

Verifying each FQDN points to the correct server IP address
Verifying each FQDN points to the correct server IP address

Generating a Keyfile for MongoDB Authentication

With your servers able to communicate with each other, you are almost ready to deploy MongoDB Replica Sets. A MongoDB Replica Set can be deployed either without authentication or with authentication via keyfile or x.509 certificates.

💡 Note that keyfiles are best suited for testing or development environments. If you are working on environments, use x.509 certificates instead.

But for this tutorial, you must ensure authentication is enabled on your MongoDB Replica Set via keyfile for security reasons.

To generate a keyfile for MongoDB authentication:

1. On each server, execute the following command, which does not provide output but creates a new directory called /opt/.mongodb-keyfile/. This directory is where you will store your MongoDB Keyfile.

💡 Switching to the root user prevents permission-related errors, but it is optional. If you are uncomfortable using root, you can stick to your non-root user account. But remember, always append sudo on your commands.

# Switch to the root user
sudo su - root
# Create a directory for the keyfile
mkdir -p /opt/.mongodb-keyfile/

2. Next, switch to srv1, and run the openssl command below, which does not produce output to the terminal, to generate a new keyfile (/opt/.mongodb-keyfile/mongodb.key).

openssl rand -base64 756 > /opt/.mongodb-keyfile/mongodb.key

3. Now, run the following commands to set up the proper permission (chmod) and ownership (chown) of the keyfile (/opt/.mongodb-keyfile/mongodb.key).

These commands do not provide output, but you will later distribute the keyfile to your other servers (srv2 and srv3) for authentication between MongoDB servers.

chmod 400 /opt/.mongodb-keyfile/mongodb.key
chown mongodb:mongodb /opt/.mongodb-keyfile/mongodb.key

4. Now, execute each scp command below to copy the keyfile (/opt/.mongodb-keyfile/mongodb.key) from the srv1 server to the srv2 and srv3 servers.

# Copy keyfile to srv2 target directory /opt/.mongodb-keyfile/
scp /opt/.mongodb-keyfile/mongodb.key [email protected]:/opt/.mongodb-keyfile/

# Copy keyfile to srv3 target directory /opt/.mongodb-keyfile/
scp /opt/.mongodb-keyfile/mongodb.key [email protected]:/opt/.mongodb-keyfile/

When prompted for the password, input the root password of the srv2 and srv3 servers.

Copying the keyfile from srv1 to srv2 and srv3
Copying the keyfile from srv1 to srv2 and srv3

5. Lastly, run the below commands on the srv2 and srv3 to ensure the keyfile (mongodb.key) is available on both servers.

# Change ownership of the keyfile
chown mongodb:mongodb /opt/.mongodb-keyfile/mongodb.key
# Verify the keyfile exists
ls -lah /opt/.mongodb-keyfile/mongodb.key
# Log out from the root user
exit

If all goes well, you will see the keyfile (/opt/.mongodb-keyfile/mongodb.key) on both servers, as shown below.

Verifying the keyfile in srv2
Verifying the keyfile in srv2
Verifying the keyfile in srv3
Verifying the keyfile in srv3

Deploying a MongoDB Replica Set via Keyfile Authentication

After successfully generating and distributing the keyfile to all available servers, it is finally time to deploy a MongoDB Replica Set via keyfile authentication. But first, you must stop the MongoDB service and configure MongoDB.

To deploy a MongoDB Replica Set:

1. Execute the systemctl command below on all servers to stop the MongoDB service (mongod).

sudo systemctl stop mongod

2. Next, open the default MongoDB configuration (/etc/mongod.conf) on each server, and add new configurations below, as follows:

  • Add the FQDN of the server to the bindIp option. This option makes MongoDB run on the system FQDN, pointing to the server’s local IP address (localhost).
  • Uncomment the security parameter and add the keyFile option to enable authentication via the keyfile /opt/.mongodb-keyfile/mongodb.key.
  • Uncomment the replication parameter and add the default replication name (replicaTestProd) via the replSetName option.
net:
  bindIp: localhost,FQDN
security:
  keyFile: /opt/.mongodb-keyfile/mongodb.key
replication:
  replSetName: replicaTestProd
Configuring the /etc/mongod.conf File
Configuring the /etc/mongod.conf File

3. With the MongoDB configured, run the systemctl command below on each server to start the MongoDB service.

This command does not provide output, but once the MongoDB service starts, you are ready to deploy a MongoDB Replica Set.

sudo systemctl start mongod

4. Now, run the below mongosh command on srv1 to connect to the MongoDB server. You will be deploying MongoDB Replica Set via the srv1 server.

mongosh
Connecting to the MongoDB server
Connecting to the MongoDB server

5. Once connected, execute the rs.initiate() query below to initiate MongoDB Replica Set.

This query deploys MongoDB Replica Set with three MongoDB servers: srv1.dblocal.lan:27017, srv2.dblocal.lan:27017, and srv3.dblocal.lan:27017.

rs.initiate(
  {
    _id : "replicaTestProd",
    members: [
      { _id : 0, host : "srv1.dblocal.lan:27017" },
      { _id : 1, host : "srv2.dblocal.lan:27017" },
      { _id : 2, host : "srv3.dblocal.lan:27017" }
    ]
  }
)

If the initialization is successful, you will see the { ok: 1 } message, as shown below.

Initializing MongoDB Replica Set via srv1
Initializing MongoDB Replica Set via srv1

6. Lastly, run the following query to verify MongoDB Replica Set status.

rs.status()

Notice that the prompt changed to replicaTestProd [direct: primary]. This prompt indicates the current server is the primary member of the MongoDB Replica Set.

At the top, the output displays information about your MongoDB Replica Set with the name replicaTestProd.

Checking the status of the MongoDB Replica Set (replicaTestProd)
Checking the status of the MongoDB Replica Set (replicaTestProd)

Further, you will see the details of srv1.dblocal.lan as a PRIMARY member on the MongoDB Replica Set with the status of health: 1.

Checking status of PRIMARY member (srv1.dblocal.lan) MongoDB Replica Set
Checking status of PRIMARY member (srv1.dblocal.lan) MongoDB Replica Set

In the latter part, you will see both srv2.dblocal.lan and srv3.dblocal.lan servers are used as SECONDARY members of the MongoDB Replica Set with the status of health: 1.

Checking the status of SECONDARY members of MongoDB Replica Set (srv2.dblocal.lan and srv3.dblocal.lan)
Checking the status of SECONDARY members of MongoDB Replica Set (srv2.dblocal.lan and srv3.dblocal.lan)

Creating MongoDB Administrator and ClusterAdmin Users

Great! You have successfully deployed a MongoDB Replica Set. But how will you manage your deployment? In this example, you will create a MongoDB administrator user and MongoDB ClusterAdmin with different roles assigned.

To create MongoDB users, follow the steps below:

1. Execute the mongosh command below on srv1 to connect to the MongoDB server.

mongosh
Connecting to the MongoDB server on srv1
Connecting to the MongoDB server on srv1

2. Once connected, run the following queries to switch to the admin database and create a new MongoDB administrator user named myAdmin (arbitrary).

The MongoDB administrator user must have at least the userAdminAnyDatabase role within the admin database. This role allows the myAdmin user to have the userAdmin role on any databases on the MongoDB server except the local and config databases.

use admin
db.createUser(
  {
    user: "myAdmin",
    pwd: passwordPrompt(),
    roles: [
      { role: "userAdminAnyDatabase", db: "admin" },
      { role: "readWriteAnyDatabase", db: "admin" }
    ]
  }
)

When prompted, provide a password for the myAdmin user. If successful, the output displays the ok: 1 message.

Creating a MongoDB administrator user
Creating a MongoDB administrator user

3. With a MongoDB admin user created, run the following query to authenticate to the MongoDB via the newly-created user (myAdmin).

db.auth("myAdmin", passwordPrompt())

Input the password when prompted; output { ok: 1 } will be shown if authentication is successful.

Authenticating as MongoDB administrator user myAdmin
Authenticating as MongoDB administrator user myAdmin

4. Next, run the below query to create a new user called ClusterAdminBob to use as the ClusterAdmin in MongoDB Replica Set.

The clusterAdmin role is the highest privilege in the MongoDB cluster. This role combines multiple roles, such as clusterManager, clusterMonitor, and hostManager.

db.createUser(
  {
    user: "ClusterAdminBob",
    pwd: passwordPrompt(),
    roles: [ { role: "clusterAdmin", db: "admin" } ]
  }
)

Input a new password for the ClusterAdmin when prompted. If successful, you will see the ok: 1 output as below.

Creating a MongoDB ClusterAdmin user ClusterAdminBob
Creating a MongoDB ClusterAdmin user ClusterAdminBob

5. Now, run the following query to verify all available users on your MongoDB server.

db.system.users.find()

Below, you can see both myAdmin and ClusterAdminBob users available on your MongoDB server.

Checking the list of users in MongoDB
Checking the list of users in MongoDB

6. After verifying the users, run the mongosh command below on srv2 and srv3 to connect to the MongoDB server on both servers and switch (use) to the admin database.

mongosh
use admin
Connecting to the MongoDB server on srv2 and switching to the admin database
Connecting to the MongoDB server on srv2 and switching to the admin database
Connecting to the MongoDB server on srv3 and switching to the admin database
Connecting to the MongoDB server on srv3 and switching to the admin database

7. Switch to the srv2 server, and run the following query to authenticate as the MongoDB administrator user (myAdmin).

db.auth("myAdmin", passwordPrompt())

Provide the password for the MondoDB administrator user when prompted. If the authentication is successful, the output shows the { ok: 1 } message, as shown below.

Authenticating as MongoDB administrator on srv2
Authenticating as MongoDB administrator on srv2

8. Lastly, switch to the srv3 server, and run the query below to authenticate as the MongoDB ClusterAdmin user (ClusterAdminBob).

db.auth("ClusterAdminBob", passwordPrompt())

Similar to srv2, provide the password for the ClusterAdmin user when prompted. and you will see the { ok: 1 } message.

Authenticating as MongoDB ClusterAdmin on srv3
Authenticating as MongoDB ClusterAdmin on srv3

Creating Data Replication in MongoDB Replica Set

Following this tutorial, you have successfully deployed the MongoDB Replica Set and created a MongoDB administrator and ClusterAdmin. With everything in place, you must verify if data replication in MongoDB Replica Set works.

You will create a new database and user, insert data from the srv1 server, and verify the data from the srv2 and srv3 servers.

To create data replication in MongoDB Replica Set:

1. Run the below command to connect to the MongoDB server on srv1.

mongosh
Connecting to the MongoDB server on srv1
Connecting to the MongoDB server on srv1

2. Next, run the following queries to switch (use) to the admin database and authenticate as an administrator user (myAdmin).

use admin
db.auth("myAdmin", passwordPrompt())

Input the password for the myAdmin user when prompted.

Authenticating as MongoDB administrator user

3. Once authenticated, execute the below queries to perform the following:

  • Create, and switch to the new database (use) called Books.
  • Create a user (db.createUser) named testuser.
  • Set read and write permissions (readWrite) to the Books database.
use Books
db.createUser(
  {
    user: "testuser",
    pwd:  passwordPrompt(),
    roles: [ { role: "readWrite", db: "Books" } ]
  }
)
Creating a new database (Book) and user (testuser)
Creating a new database (Book) and user (testuser)

4. Now, run the following queries to create a new collection called Novels and insert new data into the collection (db.collection,insertMany).

db.createCollection("Novels")
db.Novels.insertMany([
   {
      title: "Yellowface",
      genres: [ "Fiction", "Mystery", "Thriller" ],
      year: 2023
    },
    {
      title: "The House Witch",
      genres: [ "Fantasy", "Magic", "Mystery" ],
      year: 2022
    }
])
Creating a new collection (Novels) and inserting new data
Creating a new collection (Novels) and inserting new data

5. After inserting data, run the mongosh command below on both srv2 and srv3 to connect to the MongoDB server.

mongosh
Connecting to MongoDB server on srv2
Connecting to MongoDB server on srv2
Connecting to MongoDB server on srv3
Connecting to MongoDB server on srv3

6. Next, run these queries below to switch (use) to the database Books and authenticate (db.auth) as testuser.

💡 Note: You must run all queries from steps six to eight on both the srv2 and srv3 servers to test data replication.

use Books
db.auth("testuser", passwordPrompt())
Creating and switching to the Books database and authenticating as testuser on srv2
Creating and switching to the Books database and authenticating as testuser on srv2
Creating and switching to Books database and authenticating as testuser on srv3
Creating and switching to Books database and authenticating as testuser on srv3

7. Once authenticated, run the following query to enable READ operations on MongoDB SECONDARY members. This query allows both srv2 and srv3 servers to read data on MongoDB.

db.getMongo().setSecondaryOk()
Enabling READ operations on MongoDB SECONDARY members on srv2
Enabling READ operations on MongoDB SECONDARY members on srv2
Enabling READ operations on MongoDB SECONDARY members on srv3
Enabling READ operations on MongoDB SECONDARY members on srv3

8. Lastly, run the query below to verify (find) available data on the Novels collection.

db.Novels.find( {} )

If MongoDB replication is successful, you will see your data from the Novels collection on the srv2 and srv3 servers, as shown below.

Reading data from the Novels collection on srv2
Reading data from the Novels collection on srv2
Reading data from the Novels collection on srv2
Reading data from the Novels collection on srv2

Conclusion

Great job! You have successfully deployed a MongoDB Replica Set with keyfile authentication on three Ubuntu servers. Moreover, you learned to create a MongoDB administrator and ClusterAdmin users with different assigned roles.

At this point, data replication is within your reach, and you are more confident now in securing your data as you take advantage of MongoDB Replica Sets.

Now, what’s the next step? Why not discover more about MongoDB Replica Sets, and upgrade your current Keyfile authentication to x.509 Certificate?

Hate ads? Want to support the writer? Get many of our tutorials packaged as an ATA Guidebook.

Explore ATA Guidebooks

Looks like you're offline!