Premise
When installing mongos (not mongod) on CentOS 6 using the RPMs provided in MongoDB’s repository, no startup/service/init.d scripts are created, or really anything for that matter, to aid in managing mongos as a service. All the RPM provides is the binary.
If you want to treat mongos as a service, there are quite a few steps to follow beyond just setting up a script in init.d:
- mongos YAML configuration file
- mongos sysconfig service overrides
- SELinux port definition
- a user to run mongos
Most of the time there are many mongos processes distributed within a MongoDB cluster. Configuring each of these can be a hassle, let alone installing and managing them, unless you use an automation tool.
Be sure to read “Install MongoDB on Red Hat Enterprise or CentOS Linux” first.
mongos Service Scripts
Below are the 3 files I use when preparing a mongos cluster:
- The init.d service script for managing the mongos process
- A base mongos configuration file in YAML
- An automation script to prepare the CentOS 6 environment for mongos
/etc/init.d/mongos
The following init.d script has been retooled from the stock MongoDB 3.0 mongod for mongos. Watch out for the subtle differences.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
#!/bin/bash # mongos - Startup script for mongos # chkconfig: 35 85 15 # description: Mongo is a scalable, document-oriented database. # processname: mongos # config: /etc/mongos.conf # pidfile: /var/run/mongodb/mongos.pid . /etc/rc.d/init.d/functions # things from mongos.conf get there by mongos reading it # NOTE: if you change any OPTIONS here, you get what you pay for: # this script assumes all options are in the config file. CONFIGFILE="/etc/mongos.conf" OPTIONS=" -f $CONFIGFILE" SYSCONFIG="/etc/sysconfig/mongos" LOCKFILE="/var/lock/subsys/mongos" PIDFILEPATH=`awk -F'[:=]' -v IGNORECASE=1 '/^[[:blank:]]*(processManagement\.)?pidfilepath[[:blank:]]*[:=][[:blank:]]*/{print $2}' "$CONFIGFILE" | tr -d "[:blank:]\"'"` mongos=${MONGOS-/usr/bin/mongos} MONGO_USER=mongod MONGO_GROUP=mongod if [ -f "$SYSCONFIG" ]; then . "$SYSCONFIG" fi PIDDIR=`dirname $PIDFILEPATH` # Handle NUMA access to CPUs (SERVER-3574) # This verifies the existence of numactl as well as testing that the command works NUMACTL_ARGS="--interleave=all" if which numactl >/dev/null 2>/dev/null && numactl $NUMACTL_ARGS ls / >/dev/null 2>/dev/null then NUMACTL="numactl $NUMACTL_ARGS" else NUMACTL="" fi start() { # Make sure the default pidfile directory exists if [ ! -d $PIDDIR ]; then install -d -m 0755 -o $MONGO_USER -g $MONGO_GROUP $PIDDIR fi # Recommended ulimit values for mongod or mongos # See http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings # ulimit -f unlimited ulimit -t unlimited ulimit -v unlimited ulimit -n 64000 ulimit -m unlimited ulimit -u 32000 echo -n $"Starting mongos: " daemon --user "$MONGO_USER" --check $mongos "$NUMACTL $mongos $OPTIONS >/dev/null 2>&1" RETVAL=$? echo [ $RETVAL -eq 0 ] && touch "$LOCKFILE" } stop() { echo -n $"Stopping mongos: " mongo_killproc "$PIDFILEPATH" $mongos RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f "$LOCKFILE" } restart () { stop start } # Send TERM signal to process and wait up to 300 seconds for process to go away. # If process is still alive after 300 seconds, send KILL signal. # Built-in killproc() (found in /etc/init.d/functions) is on certain versions of Linux # where it sleeps for the full $delay seconds if process does not respond fast enough to # the initial TERM signal. mongo_killproc() { local pid_file=$1 local procname=$2 local -i delay=300 local -i duration=10 local pid=`pidofproc -p "${pid_file}" ${procname}` kill -TERM $pid >/dev/null 2>&1 usleep 100000 local -i x=0 while [ $x -le $delay ] && checkpid $pid; do sleep $duration x=$(( $x + $duration)) done kill -KILL $pid >/dev/null 2>&1 usleep 100000 rm -f "${pid_file}" checkpid $pid local RC=$? [ "$RC" -eq 0 ] && failure "${procname} shutdown" || success "${procname} shutdown" RC=$((! $RC)) return $RC } RETVAL=0 case "$1" in start) start ;; stop) stop ;; restart|reload|force-reload) restart ;; condrestart) [ -f "$LOCKFILE" ] && restart || : ;; status) status $mongos RETVAL=$? ;; *) echo "Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}" RETVAL=1 esac exit $RETVAL |
/etc/mongos.conf Base YAML Configuration
Be sure to set sharding.configDB appropriately.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# mongos base config in YAML systemLog: destination: "file" path: "/var/log/mongodb/mongos.log" logAppend: true processManagement: fork: true pidFilePath: "/var/run/mongodb/mongos.pid" net: bindIp: "0.0.0.0" port: 27017 sharding: configDB: "localhost:27019" |
Post-Install Environment Setup
Provided mongodb-org-mongos has already been installed, the following script will do most of the legwork to get the CentOS 6 environment up and running. Note: The script is pulling the configuration file and service file dependencies from a web server using wget; this should be tailored. It performs the following:
- Add a mongod user (yes, with a d) with the same settings that would be supplied from mongodb-org-server.
- Add a placeholder file for sysconfig.
- Add the mongos.conf file with the base configuration noted in previous (wget).
- Add the init.d service script (wget).
- If SELinux is enabled, set the contexts for the files created in previous, and add the port definition via semanage. Note that it will automatically install the required tools to perform this task if required.
- Add and enable the new mongos service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#!/bin/bash append='[mongos-prep] '; SYSCONFIG_FILE="/etc/sysconfig/mongos"; ETCCONFIG_FILE="/etc/mongos.conf"; INITD_FILE="/etc/init.d/mongos"; LOGDIR_PATH="/var/log/mongodb"; INITD_DOWNLOAD="http://host.tld/path/to/init.d/mongos"; ETCCONFIG_DOWNLOAD="http://host.tld/path/to/mongos.conf"; echo "${append}Adding mongod user"; useradd -l -M -r -U -s /bin/false -d /var/lib/mongo mongod; echo "${append}Adding sysconfig file"; echo '# TODO: add relevant configuration stuff here.' >> "${SYSCONFIG_FILE}"; chmod 0644 "${SYSCONFIG_FILE}"; echo "${append}Downloading and installing init.d script..."; wget "${INITD_DOWNLOAD}" -O "${INITD_FILE}"; chmod 0755 "${INITD_FILE}"; echo "${append}Adding regular config file ${ETCCONFIG_FILE}"; wget "${ETCCONFIG_DOWNLOAD}" -O "${ETCCONFIG_FILE}"; chmod 0644 "${ETCCONFIG_FILE}"; echo "${append}Preparing log directory"; mkdir -p "${LOGDIR_PATH}"; if selinuxenabled; then echo "${append}SELinux enabled, checking checking required tools..."; if ! hash restorecon 2>/dev/null; then echo "${append}restorecon missing, installing policycoreutils..."; sleep 2; yum -y install policycoreutils; fi; if ! hash semanage 2>/dev/null; then echo "${append}semanage missing, installing policycoreutils-python..."; sleep 2; yum -y install policycoreutils-python; fi; echo "${append}Restoring SELinux contexts"; restorecon -F "${INITD_FILE}"; restorecon -F "${SYSCONFIG_FILE}"; restorecon -F "${ETCCONFIG_FILE}"; restorecon -F "${LOGDIR_PATH}"; echo "${append}Adding port definition mongod_port_t on tcp/27017 to SELinux port, this will take a while..."; semanage port -a -t mongod_port_t -p tcp 27017; echo "${append}Adding file contexts..."; semanage fcontext -a -t mongod_initrc_exec_t '/etc/rc\.d/init\.d/mongos'; semanage fcontext -a -t mongod_exec_t '/usr/bin/mongos'; fi; echo "${append}Adding and enabling mongos in the startup config"; chkconfig --add mongos; chkconfig mongos on; echo "${append}complete."; |
SELinux and MongoDB
The automation script above does not add all of the required SELinux policies required for mongos. Install the mongodb-org package to initialize all of the policies; it can be removed later if need be while keeping these policies intact. Finding the script used by MongoDB (or making one up) is a task for another day. A policy dump from semanage is as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
semanage port -l | grep mongo mongod_port_t tcp 27017, 27017-27019, 28017-28019 semanage fcontext -l | grep mongo /etc/rc\.d/init\.d/mongod regular file system_u:object_r:mongod_initrc_exec_t:s0 /usr/bin/mongod regular file system_u:object_r:mongod_exec_t:s0 /usr/share/aeolus-conductor/dbomatic/dbomatic regular file system_u:object_r:mongod_exec_t:s0 /var/lib/mongodb(/.*)? all files system_u:object_r:mongod_var_lib_t:s0 /var/log/mongodb(/.*)? all files system_u:object_r:mongod_log_t:s0 /var/run/aeolus/dbomatic\.pid regular file system_u:object_r:mongod_var_run_t:s0 /var/run/mongodb(/.*)? all files system_u:object_r:mongod_var_run_t:s0 semanage permissive -l | grep mongo mongo_t |