Pull to refresh

MongoDB Replica Set и OpLog на одном сервере

Reading time 5 min
Views 13K

Пример настройки MongoDB с закрытым доступом через сеть Интернет. В данной статье приведен пример разворачивания трех Replica Set и активацией OpLog на одном сервере. OpLog необходим "реактивным" приложениям, которые следят (слушают) за изменениями в MongoDB, например для приложений на основе Meteor (для отключения long-polling'а).


Не смотря на то что пример ниже ориентирован на работу в рамках одного сервера, в целях стабильности рекомендуем развернуть каждого члена Replica Set на отдельном сервере. Для этого необходимо изменить адреса членов Replica Set, передаваемые в метод rs.initiate({/*...*/}).


В конфигурации членов Replica Set в качестве движка БД используется wiredTiger, о преимуществах данного движка Вы можете прочитать в release notes.


Определения:


  • Пользователь admin — Пользователь с полными правами доступа (root) ко всем функциям и командам MongoDB;
  • appUser — Пользователь с ограниченными правами на чтение и запись (readWrite) только для БД приложения;
  • appDB — БД используемая для приложения;
  • Пользователь oplogger — Пользователь с правами на чтение (read) БД local, база в которой хранится OpLog;
  • Роль oplogger — Роль с правами на чтение (read) БД local;
  • <password> — Данный плейсхолдер необходимо заменить на пароль. Всегда указывается в двойных кавычках.

Примеры приведены для MongoDB >= 3.1, и Debian >= 7


  1. Выполните шаги указанные в инструкции по установке. В процессе установки автоматически будет создан системный пользователь mongodb, состоящий в группе mongodb
  2. Создайте и укажите права для директорий файлов БД:
    $ mkdir -p /data/mongos/one /data/mongos/two /data/mongos/three
    $ chmod 755 /data
    $ chown -R mongodb:mongodb /data/mongos
  3. Создайте и укажите права для директорий журнала MongoDB (логов):
    $ mkdir -p /var/log/mongodb/one /var/log/mongodb/two /var/log/mongodb/three
    $ chown -R mongodb:mongodb /var/log/mongodb
  4. Удалите сервис mongod:
    $ rm /etc/init.d/mongod
  5. Создайте конфигурационный файл MongoDB для первого члена Replica Set (nano /etc/mongod-one.conf):
    storage:
      dbPath: /data/mongos/one
      journal:
        enabled: true
      engine: wiredTiger
    systemLog:
      verbosity: 0
      traceAllExceptions: false
      destination: file
      logAppend: true
      path: /var/log/mongodb/one/mongod.log
    net:
      port: 27017
      bindIp: 0.0.0.0
    operationProfiling:
      slowOpThresholdMs: 2100
      mode: off
    replication:
      replSetName: rs0
  6. Создайте конфигурационный файл MongoDB для второго члена Replica Set (nano /etc/mongod-two.conf):
    storage:
      dbPath: /data/mongos/two
      journal:
        enabled: true
      engine: wiredTiger
    systemLog:
      verbosity: 0
      traceAllExceptions: false
      destination: file
      logAppend: true
      path: /var/log/mongodb/two/mongod.log
    net:
      port: 27018
      bindIp: 0.0.0.0
    operationProfiling:
      slowOpThresholdMs: 2100
      mode: off
    replication:
      replSetName: rs0
  7. Создайте конфигурационный файл MongoDB для третьего члена Replica Set (nano /etc/mongod-three.conf):
    storage:
      dbPath: /data/mongos/three
      journal:
          enabled: true
      engine: wiredTiger
    systemLog:
      verbosity: 0
      traceAllExceptions: false
      destination: file
      logAppend: true
      path: /var/log/mongodb/three/mongod.log
    net:
      port: 27019
      bindIp: 0.0.0.0
    operationProfiling:
      slowOpThresholdMs: 2100
      mode: off
    replication:
      replSetName: rs0
  8. Создайте и укажите права для файла с общим ключом аутентификации, данный ключ будут использовать члены Replica Set для коммуникации друг с другом:
    $ openssl rand -base64 741 > /data/mongos/key
    $ chown mongodb:mongodb /data/mongos/key
    $ chmod 400 /data/mongos/key
  9. Создайте Cron-файл для запуска MongoDB от имени пользователя mongodb (crontab -u mongodb -e):
    @reboot /usr/bin/mongod --config /etc/mongod-one.conf --fork
    @reboot /usr/bin/mongod --config /etc/mongod-two.conf --fork
    @reboot /usr/bin/mongod --config /etc/mongod-three.conf --fork
  10. Перезагрузите машину (сервер)
  11. Укажите конфигурацию для Replica Set, и инициируйте RS:
    // Mongo Shell:
    $ mongo
    var conf = {
      "_id" : "rs0",
      "members" : [
        {
          "_id" : 0,
          "host" : "127.0.0.1:27017"
        },
        {
          "_id" : 1,
          "host" : "127.0.0.1:27018"
        },
        {
          "_id" : 2,
          "host" : "127.0.0.1:27019"
        }
      ]
    }
    rs.initiate(conf)
  12. Создайте пользователя admin, с root правами (убедитесь что Вы вводите команды на PRIMARY члене Replica Set):
    // Mongo Shell:
    $ mongo --port 27017
    use admin
    db.createUser({user:"admin", pwd:<password>, roles:[{role:"root", db:"admin"}]})
  13. Обновите Cron-файл для запуска MongoDB с --auth флагом (crontab -u mongodb -e) это закроет MongoDB от неавторизованного доступа (прочтите статью по безопасности MongoDB для обеспечения надежной защиты):
    @reboot /usr/bin/mongod --config /etc/mongod-one.conf --auth --fork
    @reboot /usr/bin/mongod --config /etc/mongod-two.conf --auth --fork
    @reboot /usr/bin/mongod --config /etc/mongod-three.conf --auth --fork
  14. Укажите путь к общему ключу аутентификации для каждого члена Replica Set:
    # nano /etc/mongod-one.conf
    # nano /etc/mongod-two.conf
    # nano /etc/mongod-three.conf
    security:
      keyFile: /data/mongos/key
  15. Перезагрузите машину (сервер)
  16. Создайте пользователя с правами на чтение и запись readWrite для БД приложения (используйте данного пользователя для доступа к MongoDB, в коде Вашего приложения):
    // Mongo Shell:
    $ mongo -u "admin" -p <password> --authenticationDatabase "admin"
    use admin
    db.createUser({user:"appUser", pwd:<password>, roles:[{role:"readWrite", db:"appDB"}]})
  17. Создайте роль oplogger:
    // Mongo Shell:
    $ mongo -u "admin" -p <password> --authenticationDatabase "admin"
    use admin
    db.runCommand({createRole:"oplogger", privileges:[{resource: {db:"local", collection:"system.replset"}, actions: ["find"]}], roles:[{role:"read", db:"local"}]})
  18. Создайте пользователя oplogger, и присвойте ему роль oplogger:
    // Mongo Shell:
    $ mongo -u "admin" -p <password> --authenticationDatabase "admin"
    use admin
    // Для MongoDB 2.4
    db.createUser({user:"oplogger", pwd:<password>, roles:[], otherDBRoles:{local:["read"]}})
    // Для MongoDB >= 2.6
    db.createUser({user:"oplogger", pwd:<password>, roles:[{role: "read", db: "local"}]})
    db.runCommand({grantRolesToUser:"oplogger", roles:["oplogger"]})
  19. Убедитесь что все пользователи корректно созданы:
    // Mongo Shell:
    $ mongo -u "admin" -p <password> --authenticationDatabase "admin"
    use admin
    show users

С этого момента MongoDB доступна по публичному IP-адресу сервера (машины), так же как и на loopback и localhost.


Строки подключения:


  • Для приложения:
    mongodb://appUser:<password>@<PUBLIC_IP>:27017,<PUBLIC_IP>:27018,<PUBLIC_IP>:27019/appDB?authSource=admin&replicaSet=rs0
  • Для OpLog:
    mongodb://oplogger:<password>@<PUBLIC_IP>:27017,<PUBLIC_IP>:27018,<PUBLIC_IP>:27019/local?authSource=admin&replicaSet=rs0



Update:


Начиная с mongodb@2.2.0 (драйвер), необходимо использовать одинаковый IP-адрес / доменное имя как в строке подключения, так и в конфигурации Replica Set, см.: баг #NODE-746.


Данные нововведения в драйвере влекут ошибки: no valid replicaset members found и no primary found in replicaset.


Для удовлетворения новых требований — присвойте доменное имя хосту (серверу) где находится MongoDB, суб-домен так же подойдет. Представим что мы выбрали домен mongo.example.com.


На сервере MongoDB выполните:


// Mongo Shell:
$ mongo
var rsconf = rs.conf();
rsconf.members[0].host = 'mongo.example.com:27017';
rsconf.members[1].host = 'mongo.example.com:27018';
rsconf.members[2].host = 'mongo.example.com:27019';
rs.reconfig(rsconf);

Обновите строки подключения к базе:


  • Для приложения:
    mongodb://appUser:<password>@mongo.example.com:27017,mongo.example.com:27018,mongo.example.com:27019/appDB?authSource=admin&replicaSet=rs0
  • Для OpLog:
    mongodb://oplogger:<password>@mongo.example.com:27017,mongo.example.com:27018,mongo.example.com:27019/local?authSource=admin&replicaSet=rs0

Версия на Английском

Tags:
Hubs:
0
Comments 0
Comments Leave a comment

Articles