Installation and Configuration of a 3-Server MongoDB Cluster

Installation of MongoDB in 3 servers

Use the below steps to install MongoDB on all 3 RHEL 9 servers. 

Primary MongoDB hostname (Mongo1) = dbserver01
Secondary MongoDB hostname (Mongo2) = dbserver02
Third MongoDB hostname (Mongo3) = dbserver03

Note: MongoDB 5.0 and above do not support use of an IP address for the MongoDB replica set; use hostname for the replica set configurations.

To install MongoDB on the 3 servers, run the following commands on each server using the repository:

dnf module disable httpd -y
dnf module disable php -y 


cat <<EOF > /etc/yum.repos.d/filecloud-23.1.repo 
[filecloud-23.1] 
name=FileCloud 23.1 
baseurl=https://repo.filecloudlabs.com/yum/redhat/\$releasever/filecloud/23.1/x86_64/ 
gpgcheck=1 
enabled=1 
gpgkey=https://repo.filecloudlabs.com/static/pgp/filecloud.asc 
module_hotfixes=true 
EOF 


cat <<EOF > /etc/yum.repos.d/mongodb-org-6.0.repo 
[mongodb-org-6.0] 
name=MongoDB Repository 
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/6.0/x86_64/ 
gpgcheck=1 
enabled=1 
gpgkey=https://www.mongodb.org/static/pgp/server-6.0.asc 
EOF 


yum update -y 
yum install yum-utils -y
yum-config-manager --enable filecloud-23.1 
yum install mongodb-org -y

Setting up Replication

Edit mongo.conf at /etc/mongodb.conf in each DB node and enable DB replication. 

replication:
 replSetName: rs0


Important: Comment out (or remove) the bind directive and add the hostname (do this in all the db nodes).

bind_ip = dbserver01

After making the above changes, restart your MongoDB service.


Important Step : This applies to ONLY one node. Select a node (for example, Mongo1) and issue the following command. If you issue this in more than one system, the configuration will become invalid.

Connect to MongoDB:

mongosh --host dbserver01

Initialize the replica set:

rs.initiate() 
rs.add(‘hostname of 2nd MongoDB server’) 
rs.add(‘hostname of 3rd MongoDB server’)


In each of the three database server nodes, connect to mongo shell and enter rs.status() to see the actual value (one of the nodes should appear as Primary and the other two nodes should appear as Secondary).

mongosh --host dbserver01 
rs.status()


It should appear similar to:

rs.status() 
{
 set: 'rs0',
 date: ISODate("2023-07-31T13:25:38.677Z"),
 myState: 1,
 term: Long("4"),
 syncSourceHost: '',
 syncSourceId: -1,
 heartbeatIntervalMillis: Long("2000"),
 majorityVoteCount: 2,
 writeMajorityCount: 2,
 votingMembersCount: 3,
 writableVotingMembersCount: 3,
 optimes: {
 lastCommittedOpTime: { ts: Timestamp({ t: 1690809937, i: 1 }), t: Long("4") },
 lastCommittedWallTime: ISODate("2023-07-31T13:25:37.356Z"),
 readConcernMajorityOpTime: { ts: Timestamp({ t: 1690809937, i: 1 }), t: Long("4") },
 appliedOpTime: { ts: Timestamp({ t: 1690809937, i: 1 }), t: Long("4") },
 durableOpTime: { ts: Timestamp({ t: 1690809937, i: 1 }), t: Long("4") },
 lastAppliedWallTime: ISODate("2023-07-31T13:25:37.356Z"),
 lastDurableWallTime: ISODate("2023-07-31T13:25:37.356Z")
 },
 lastStableRecoveryTimestamp: Timestamp({ t: 1690809904, i: 4 }),
 electionCandidateMetrics: {
 lastElectionReason: 'electionTimeout',
 lastElectionDate: ISODate("2023-07-28T12:25:28.403Z"),
 electionTerm: Long("4"),
 lastCommittedOpTimeAtElection: { ts: Timestamp({ t: 0, i: 0 }), t: Long("-1") },
 lastSeenOpTimeAtElection: { ts: Timestamp({ t: 1690547080, i: 1 }), t: Long("3") },
 numVotesNeeded: 2,
 priorityAtElection: 1,
 electionTimeoutMillis: Long("10000"),
 numCatchUpOps: Long("0"),
 newTermStartDate: ISODate("2023-07-28T12:25:28.411Z"),
 wMajorityWriteAvailabilityDate: ISODate("2023-07-28T12:25:28.890Z")
 }, 
 members: [ 
  {
   _id: 0,
 name: 'dbserver01:27017',
 health: 1,
 state: 2,
 stateStr: 'SECONDARY',
 uptime: 262817,
 optime: { ts: Timestamp({ t: 1690809937, i: 1 }), t: Long("4") },
 optimeDurable: { ts: Timestamp({ t: 1690809937, i: 1 }), t: Long("4") },
 optimeDate: ISODate("2023-07-31T13:25:37.000Z"),
 optimeDurableDate: ISODate("2023-07-31T13:25:37.000Z"),
 lastAppliedWallTime: ISODate("2023-07-31T13:25:37.356Z"),
 lastDurableWallTime: ISODate("2023-07-31T13:25:37.356Z"),
 lastHeartbeat: ISODate("2023-07-31T13:25:38.622Z"),
 lastHeartbeatRecv: ISODate("2023-07-31T13:25:38.623Z"),
 pingMs: Long("0"),
 lastHeartbeatMessage: '',
 syncSourceHost: 'ip-172-31-48-61.us-west-2.compute.internal:27017',
 syncSourceId: 2,
 infoMessage: '',
 configVersion: 5,
 configTerm: 4
 },
 {
  _id: 1,
  name: 'dbserver02:27017',
  health: 1,
  state: 2,
  stateStr: 'SECONDARY',
  uptime: 262815,
  optime: { ts: Timestamp({ t: 1690809937, i: 1 }), t: Long("4") },
  optimeDurable: { ts: Timestamp({ t: 1690809937, i: 1 }), t: Long("4") },
  optimeDate: ISODate("2023-07-31T13:25:37.000Z"),
  optimeDurableDate: ISODate("2023-07-31T13:25:37.000Z"),
  lastAppliedWallTime: ISODate("2023-07-31T13:25:37.356Z"),
  lastDurableWallTime: ISODate("2023-07-31T13:25:37.356Z"),
  lastHeartbeat: ISODate("2023-07-31T13:25:38.315Z"),
  lastHeartbeatRecv: ISODate("2023-07-31T13:25:38.624Z"),
  pingMs: Long("0"),
  lastHeartbeatMessage: '',
  syncSourceHost: dbserver03:27017',
  syncSourceId: 2,
  infoMessage: '',
  configVersion: 5,
  configTerm: 4
 },
 { 
  _id: 2, 
  name: 'dbserver03:27017',
  health: 1, 
  state: 1,
  stateStr: 'PRIMARY',
  uptime: 262827,
  optime: { ts: Timestamp({ t: 1690809937, i: 1 }), t: Long("4") },
  optimeDate: ISODate("2023-07-31T13:25:37.000Z"),
  lastAppliedWallTime: ISODate("2023-07-31T13:25:37.356Z"),
  lastDurableWallTime: ISODate("2023-07-31T13:25:37.356Z"),
  syncSourceHost: '',
  syncSourceId: -1,
  infoMessage: '',
  electionTime: Timestamp({ t: 1690547128, i: 1 }),
  electionDate: ISODate("2023-07-28T12:25:28.000Z"),
  configVersion: 5,
  configTerm: 4, 
  self: true, 
  lastHeartbeatMessage: '' 
 } 
],
ok: 1,
'$clusterTime': {
  clusterTime: Timestamp({ t: 1690809937, i: 1 }),
  signature: {
   hash: Binary(Buffer.from("0b64957b79301df817a21a81d8b5fdcf26ae3849", "hex"), 0),
   keyId: Long("7258553339363721222")
  }
 },
 operationTime: Timestamp({ t: 1690809937, i: 1 })
 }

Enable MongoDB Cluster Authentication

You can find more details on setting up MongoDB authentication here

Sample MongoDB configuration file:

# mongod.conf

# for documentation of all options, see:
#   http://docs.mongodb.org/manual/reference/configuration-options/


# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log


# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb
  journal:
    enabled: true
#  engine:
#  wiredTiger:  


# how the process runs
processManagement:
 timeZoneInfo: /usr/share/zoneinfo


# network interfaces
net:
  port: 27017
  bindIp: dbserver01 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.   

security:
  keyFile: /etc/mongodb-keyfile

#operationProfiling:

replication:
 replSetName: rs0

#sharding:

## Enterprise-Only Options:

#auditLog:

#snmp: