Thursday, September 15, 2016


Enable Authentication & Authorization on 

MongoDB Ops Manager


In this note, I will describe how to enable authentication and authorization on MongoDB Ops Manager cloud control env. 

My setup is as follows
3 node rerplicaset for Ops Manager Metadata Repository
3 node rerplicaset for Ops Manager Sync Store DB 
2 node for application servers
1 node for Backup Daemon 

At high level we need to do following. 

a. Create db user in rerplicaset with right roles.
b. Modify Ops manager config files with user details
c. Create key file on replicaset nodes and copy it on all nodes (assuming you are using single key file across all replica sets. If otherwise create multiple key files)
d. Modify mongod.conf file on all nodes of all replica sets and restart mongbdb in rolling fashion.


1.  create users on both replset(metadata and blockstore/syncstore)

db.createUser(
  {
    user: "opsmanager",
    pwd: "xxxxxxx",
    roles: [ { role: "root", db: "admin" } ]
  }
)
Make sure the data is replicated.

2. modify opsmanager config files with users details

#mongo.mongoUri=mongodb://username:password@memdb03.phx.aexp.com:27017,memdb02.phx.aexp.com:27017,memdb01.phx.aexp.com:27017

3. bounce all opsmanagers and backup daemon

pbrun /etc/init.d/mongodb-mms restart


Create key file on replicaset nodes -

1. create key file on replset , both

 openssl  rand -base64 755 > /etc/mongodb.key
 chown mongod:mongod /etc/mongodb.key
 chmod  400 /etc/mongodb.key

copy /etc/mongodb.key to all db instances in both repl set.

2.  modify mongb conf files for authrization and key file (secondary, secondary, primary)

 Go to the first secondary instance and change following in conf file. (Try to do it before hand for all replica sets, all nodes)

 security:
  authorization: enabled
  keyFile: /data/mongodb/pqmrsme001/mongodb.key
  
 bounce the mongodb instance and make sure its in sync with primary

 Go to second secondary perform the above change and then primary

 pbrun /etc/init.d/mongod restart


##After first/primary node restart

[root@lpdosput00250 ~]#  mongo --port 27017 --authenticationDatabase admin -u opsmanager -p xxxxxxx
MongoDB shell version: 3.2.1
MongoDB Enterprise rs0:RECOVERING> rs.status()
{
        "set" : "rs0",
        "date" : ISODate("2016-08-18T18:46:06.886Z"),
        "myState" : 3,
        "term" : NumberLong(141),
        "heartbeatIntervalMillis" : NumberLong(2000),
        "members" : [
                {
                        "_id" : 0,
                        "name" : "10.20.176.248:28017",
                        "health" : 1,
                        "state" : 3,
                        "stateStr" : "RECOVERING",    <-- Notice the change of state
                        "uptime" : 34,
                        "optime" : {
                                "ts" : Timestamp(1471545769, 1),
                                "t" : NumberLong(141)
                        },
                        "optimeDate" : ISODate("2016-08-18T18:42:49Z"),
                        "infoMessage" : "could not find member to sync from",
                        "configVersion" : 3,
                        "self" : true
                },
                {
                        "_id" : 1,
                        "name" : "10.20.176.248:28018",
                        "health" : 0,
                        "state" : 6,
                        "stateStr" : "(not reachable/healthy)", <-- Notice the change of state
                        "uptime" : 0,
                        "optime" : {
                                "ts" : Timestamp(0, 0),
                                "t" : NumberLong(-1)
                        },
                        "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
                        "lastHeartbeat" : ISODate("2016-08-18T18:46:03.207Z"),
                        "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
                        "pingMs" : NumberLong(0),
                        "authenticated" : false,
                        "configVersion" : -1
                },
                {
                        "_id" : 2,
                        "name" : "10.20.176.248:28019",
                        "health" : 0,
                        "state" : 6,
                        "stateStr" : "(not reachable/healthy)", <-- Notice the change of state
                        "uptime" : 0,
                        "optime" : {
                                "ts" : Timestamp(0, 0),
                                "t" : NumberLong(-1)
                        },
                        "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
                        "lastHeartbeat" : ISODate("2016-08-18T18:46:03.209Z"),
                        "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
                        "pingMs" : NumberLong(0),
                        "authenticated" : false,
                        "configVersion" : -1
                }
        ],
        "ok" : 1
}

##After Secondary node restart -

MongoDB Enterprise rs0:SECONDARY> rs.status()
{
        "set" : "rs0",
        "date" : ISODate("2016-08-18T18:47:27.806Z"),
        "myState" : 2,
        "term" : NumberLong(141),
        "heartbeatIntervalMillis" : NumberLong(2000),
        "members" : [
                {
                        "_id" : 0,
                        "name" : "10.20.176.248:28017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "PRIMARY", <-- Notice the change of state
                        "uptime" : 10,
                        "optime" : {
                                "ts" : Timestamp(1471545769, 1),
                                "t" : NumberLong(141)
                        },
                        "optimeDate" : ISODate("2016-08-18T18:42:49Z"),
                        "lastHeartbeat" : ISODate("2016-08-18T18:47:27.724Z"),
                        "lastHeartbeatRecv" : ISODate("2016-08-18T18:47:24.382Z"),
                        "pingMs" : NumberLong(0),
                        "configVersion" : 3
                },
                {
                        "_id" : 1,
                        "name" : "10.20.176.248:28018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY", <-- Notice the change of state
                        "uptime" : 10,
                        "optime" : {
                                "ts" : Timestamp(1471545769, 1),
                                "t" : NumberLong(141)
                        },
                        "optimeDate" : ISODate("2016-08-18T18:42:49Z"),
                        "infoMessage" : "could not find member to sync from",
                        "configVersion" : 3,
                        "self" : true
                },
                {
                        "_id" : 2,
                        "name" : "10.20.176.248:28019",
                        "health" : 0,
                        "state" : 6,
                        "stateStr" : "(not reachable/healthy)", <-- Notice the change of state
                        "uptime" : 0,
                        "optime" : {
                                "ts" : Timestamp(0, 0),
                                "t" : NumberLong(-1)
                        },
                        "optimeDate" : ISODate("1970-01-01T00:00:00Z"),
                        "lastHeartbeat" : ISODate("2016-08-18T18:47:27.726Z"),
                        "lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
                        "pingMs" : NumberLong(0),
                        "authenticated" : false,
                        "configVersion" : -1
                }
        ],
        "ok" : 1
}


##After Secondary node restart -

MongoDB Enterprise rs0:SECONDARY> rs.status()
{
        "set" : "rs0",
        "date" : ISODate("2016-08-18T18:51:29.408Z"),
        "myState" : 2,
        "term" : NumberLong(143),
        "syncingTo" : "10.20.176.248:28018",
        "heartbeatIntervalMillis" : NumberLong(2000),
        "members" : [
                {
                        "_id" : 0,
                        "name" : "10.20.176.248:28017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY", <-- Notice the change of state
                        "uptime" : 9,
                        "optime" : {
                                "ts" : Timestamp(1471546211, 1),
                                "t" : NumberLong(143)
                        },
                        "optimeDate" : ISODate("2016-08-18T18:50:11Z"),
                        "lastHeartbeat" : ISODate("2016-08-18T18:51:25.260Z"),
                        "lastHeartbeatRecv" : ISODate("2016-08-18T18:51:29.261Z"),
                        "pingMs" : NumberLong(0),
                        "electionTime" : Timestamp(0, 0),
                        "electionDate" : ISODate("1970-01-01T00:00:00Z"),
                        "configVersion" : 3
                },
                {
                        "_id" : 1,
                        "name" : "10.20.176.248:28018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY", <-- Notice the change of state
                        "uptime" : 9,
                        "optime" : {
                                "ts" : Timestamp(1471546211, 1),
                                "t" : NumberLong(143)
                        },
                        "optimeDate" : ISODate("2016-08-18T18:50:11Z"),
                        "lastHeartbeat" : ISODate("2016-08-18T18:51:25.260Z"),
                        "lastHeartbeatRecv" : ISODate("2016-08-18T18:51:28.127Z"),
                        "pingMs" : NumberLong(0),
                        "syncingTo" : "10.20.176.248:28017",
                        "configVersion" : 3
                },
                {
                        "_id" : 2,
                        "name" : "10.20.176.248:28019",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY", <-- Notice the change of state
                        "uptime" : 10,
                        "optime" : {
                                "ts" : Timestamp(1471546211, 1),
                                "t" : NumberLong(143)
                        },
                        "optimeDate" : ISODate("2016-08-18T18:50:11Z"),
                        "syncingTo" : "10.20.176.248:28018",
                        "infoMessage" : "syncing from: 10.20.176.248:28018",
                        "configVersion" : 3,
                        "self" : true
                }
        ],
        "ok" : 1
}


After you make this change, one has to enable the password for oplog store database so that ops manager can login 
and write oplog from replica sets to oplog store database.

From OpsMgr:  Click 'Admin' in upper right, then the 'Backup' tab, then the 'Oplog Storage' sub-tab and fill in username and password fields.

Once that is done, restart the opsmanager and backup daemon servers.

If you miss the above, you will see following error on Ops manager system warnings.

com.xgen.svc.brs.web.res.BackupConfigurationResource.updateReplicaSetConfiguration(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,boolean,java.lang.String,java.util.List,java.lang.String,java.lang.String,java.lang.String) - msg: { "serverUsed" : "memdb05:27017" , "ok" : 0.0 , "errmsg" : "not authorized on 570d36d634fc72f8790f2e63 to execute command { createIndexes: \"oplog_pdmcl101\", indexes: [ { name: \"groupId_1_rsId_1_valid_1_end_1__id_1\", ns: \"570d36d634fc72f8790f2e63.oplog_pdmcl101\", background: true, key: { groupId: 1, rsId: 1, valid: 1, end: 1, _id: 1 } } ] }" , "code" : 13} com.mongodb.CommandFailureException { "serverUsed" : "memdb05:27017" , "ok" : 0.0 , "errmsg" : "not authorized on 570d36d634fc72f8790f2e63 to execute command { createIndexes: \"oplog_pdmcl101\", indexes: [ { name: \"groupId_1_rsId_1_valid_1_end_1__id_1\", ns: \"570d36d634fc72f8790f2e63.oplog_pdmcl101\", background: true, key: { groupId: 1, rsId: 1, valid: 1, end: 1, _id: 1 } } ] }" , "code" : 13} 

Also remember that if you have monitoring and backup agents running on backup daemon, they dont need bounce coz monitoring agent does not need to talk with Meta data DB as it check the target db status and ask the opsmanager to write details to Metadata DB.

MongoDB Start Up Issues & Warnings


While taking backup of MongoDB using Ops Manager cloud control, we came across various warnings at different stages. 
following are the warnings that one may come across during start of the Head DB.


WARNING: soft rlimits too low. rlimits set to 4096 processes, 64000 files.

##Pls create following file if not already present.

 cat /etc/security/limits.d/90-nproc.conf
* soft nproc 64000
* hard nproc 64000

Make sure to reboot the system after the change.


As we are using Data Domain to store snapshots and SAN for Head DB, another error we faced was following.

unable to create or lock mongod.lock file

Here the issue was with the options we used to mount the file system.so we changed the options to include following.

nolock, noatime, nointr

There were also some more warnings regarding NUMACTL not installed. 
one way is to install the numactl on backup daemon server with the help of SA. 
OR 
we can disable it using Ops Manager UI as follows.

Non-Uniform Memory Access (NUMA) Settings

Key - mongodb.disable.numa
Value Type: boolean

To disable NUMA for the head databases:

1.Click the Admin link, then the General tab, then the Ops Manager Config page, and then the Custom section.
2.Add mongodb.disable.numa as a Key and set its Value to true.
3.Click Save.