Схема резервирования биллинга

Сначала настройте репликацию, затем можно настроить автоматическое резервное переключение с помощью keepalived или использовать переключение вручную.

В этой инструкции:

  • master — основной используемый сервер с установкой биллинга. Для примера взят адрес 192.168.35.1 и интерфейс ens18.
  • backup — запасной сервер, используемый в случае недоступности master. Для примера взят адрес 192.168.35.2 и интерфейс ens18.

При реальной настройке ниже замените значения из примеров своими.

  1. Настроить репликацию БД типа master-master в MySQL
  2. Варианты резервного переключения: с помощью keepalived или вручную

Настроить репликацию БД типа master-master в MySQL

  1. Убедитесь, что на master включён firewall. Если включён, разрешите любые соединения к master, исходящие от IP-адреса backup к порту MySQL.

    По умолчанию используется порт 3306, если в ваших файлах конфигурации другой порт — укажите его. Пример:

    ufw allow from 192.168.35.2 to any port 3306
    

    ``

  2. Отредактируйте файл конфигурации MySQL на master.

    Укажите настройки, необходимые для репликации БД. Для этого откройте конфигурационный файл MySQL — как правило /etc/mysql/mysql.conf.d/mysqld.cnf. Путь может быть другим — это зависит от системы, версии MySQL и директории установки.

    В секции [mysqld] укажите параметры, необходимые для настройки репликации. Пример:

    [mysqld]
    server-id = 1
    bind-address = 192.168.35.1
    log_bin = /var/log/mysql/mysql-bin.log
    log_bin_index = /var/log/mysql/mysql-bin.log.index
    relay_log = /var/log/mysql/mysql-relay-bin
    relay_log_index = /var/log/mysql/mysql-relay-bin.index
    binlog_do_db = billing
    replicate-rewrite-db = backupbilling->billing
    auto_increment_increment = 2
    auto_increment_offset = 1
    binlog_expire_logs_seconds = 120
    max_binlog_size = 128M
    

    ``

    • server-id — идентификатор сервера, с помощью которого различаются узлы репликации. Это значение должно быть уникальным и не повторяться на остальных связанных серверах.

    • bind-address — IP-адрес master-сервера.

    • log_bin, log_bin_index — путь к bin-логам сервера. Master будет указывать в них произведённые изменения для использования backup-сервером.

    • relay_log, relay_log_index — путь к relay-логам сервера. Их заполняет backup для использования master-сервером.

    • binlog_do_db — название БД, которую требуется реплицировать. Необходимо указать ту БД, которую использует биллинг. Если реплицируемых БД несколько, повторить для каждой.

    • replicate-rewrite-db — указывает, из какой БД и в какую требуется реплицировать данные. Формат: <название БД backup-сервера>-><название БД master-сервера>. Этот параметр нужно указывать, только если названия БД на серверах отличаются!

    • auto_increment_increment, auto_increment_offset — правила выбора автоинкрементных идентификаторов: шаг и начальное значение. Позволяет избежать конфликтов автоматического инкремента.

      В примере выше указан шаг 2 (auto_increment_increment) и начальное значение 1 (auto_increment_offset) — идентификаторы будут генерироваться, начиная с 1 и прибавляя по 2 — 1, 3, 5, 7 и т.д.

    • binlog_expire_logs_seconds — время хранения bin-логов (в секундах). Эта настройка доступна в версиях MySQL 8.0+, на старых версиях используется параметр expire_logs_days — время хранения bin-логов (в днях);

    • max_binlog_size — максимально допустимый размер bin-лог файла. Минимальное значение — 4096 байт, максимальное — 1 ГБ. Если не указано значение, используется по умолчанию 1 ГБ. Максимальный размера кэша транзакций настраивается в опции max_binlog_cache_size.

    Если в файле конфигурации указаны настройки log_slave_updatesи log_replica_updates , у них должно быть значение ON.

  3. Создайте пользователя для репликации на master в консоли MySQL. Можно использовать существующего пользователя. При создании нового нужно выдать права, необходимые для репликации.

    Вместо replica укажите имя пользователя, вместо password — пароль пользователя.

    mysql> CREATE USER 'replica'@'%' IDENTIFIED BY 'password';
    mysql> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%';
    mysql> FLUSH PRIVILEGES;
    

    ``

  4. Перезапустите MySQL с новой конфигурацией на master.

    systemctl restart mysql
    

    ``

    Обратите внимание: в разных ОС команды могут отличаться. Для некоторых систем (например, старых версий CentOS) команда может выглядеть так:

    service mysqld restart
    

    ``

    Или так:

    /etc/init.d/mysqld.service restart
    

    ``

  5. Убедитесь, что на backup включён firewall. Разрешите любые соединения к backup, исходящие от IP-адреса master к порту MySQL. По умолчанию используется порт 3306, если в ваших файлах конфигурации другой порт — укажите его. Пример:

    ufw allow from 192.168.35.2 to any port 3306
    

    ``

  6. Скопируйте начальное состояние БД на backup.

    Если на backup-сервере ещё нет БД для LanBilling, а на master-сервере такая БД уже существует и содержит какую-то информацию, то на master нужно сделать дамп необходимой БД, скопировать его на backup, там создать новую БД и развернуть дамп.

    Это можно сделать следующими способами:

    • Создать дамп на master и скопировать. Настройка --routines указывает, что нужно копировать хранимые процедуры/функции. Пример:

      mysqldump -u root billing --routines > billing.sql
      scp billing.sql username@192.168.35.2:/tmp/
      
      
      
    • Создать БД на backup и развернуть дамп. Пример:

      mysql> CREATE DATABASE `billing` DEFAULT CHARSET UTF8;
      sudo mysql billing < /tmp/billing.sql
      
      
      

    Важно: на backup-сервере нужно активировать отдельную лицензию, чтобы избежать конфликтов при проверке оборудования на уже активной лицензии master. При любых изменениях, производимых в дальнейшем с опцией license на master- или backup- сервере, нужно вручную править эту настройку или исключить её из репликации — иначе синхронизация может её стереть изменения.

  7. Отредактируйте файл конфигурации MySQL на backup.

    Выполняется аналогично настройкам в кофигурации master-сервера — меняется идентификатор сервера, указывается адрес backup-сервера, другое название реплицируемой БД (если отличается) и обратный порядок БД в replicate-rewrite-db (если отличаются названия).

    В примере ниже для backup-сервера настройки автоинкремента auto_increment_increment и auto_increment_offset заданы так, чтобы значения выбирались в виде 2, 4, 6, 8,… и не пересекались с master.

    [mysqld]
    server-id = 2
    bind-address = 192.168.35.2
    log-bin = /var/log/mysql/mysql-bin.log
    log_bin_index = /var/log/mysql/mysql-bin.log.index
    relay_log = /var/log/mysql/mysql-relay-bin
    relay_log_index = /var/log/mysql/mysql-relay-bin.index
    binlog_do_db = backupbilling
    replicate-rewrite-db = billing->backupbilling
    auto_increment_increment = 2
    auto_increment_offset = 2
    binlog_expire_logs_seconds = 120
    max_binlog_size = 128M
    

    ``

  8. Создайте пользователя для репликации на backup в консоли MySQL.

    Аналогично созданию пользователя для репликации на master. Можно использовать существующего пользователя. При создании нового также выдайте права, необходимые для репликации.

    Вместо replica укажите имя пользователя, вместо password — пароль пользователя.

    mysql> CREATE USER 'replica'@'%' IDENTIFIED BY 'password';
    mysql> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%';
    mysql> FLUSH PRIVILEGES;
    

    ``

  9. Перезапустите MySQL с новой конфигурацией на backup.

    systemctl restart mysql
    

    ``

  10. Настройте репликацию.

    Если настройки, описанные выше, заданы правильно, то с помощью запроса на master-сервере вы получите сведения о последней позиции репликации. Далее вам потребуются значения File и Position.

    mysql> show master status;
    +------------------+----------+--------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+--------------+------------------+-------------------+
    | mysql-bin.000003 |      157 | billing      |                  |                   |
    +------------------+----------+--------------+------------------+-------------------+
    1 row in set (0,00 sec)
    

    На backup-сервере подключите репликацию. Адрес master, пользвателя, пароль замените на свои. В MASTER_LOG_FILE и MASTER_LOG_POS укажите значения File и Position, полученные на master-сервере.

    mysql> STOP SLAVE;
    mysql> CHANGE MASTER TO MASTER_HOST = '192.168.35.1', MASTER_USER = 'replica', MASTER_PASSWORD = 'password', MASTER_LOG_FILE = 'mysql-bin.000003', MASTER_LOG_POS = 157;
    mysql> START SLAVE;
    

    Примечание: в версиях MySQL 8.0+ команды START SLAVE и STOP SLAVE помечены устаревшими — вместо них рекомендуется использовать START REPLICA и STOP REPLICA соответственно.

    Узнайте статус на backup-сервере:

    mysql> show master status;
    +------------------+----------+---------------+------------------+-------------------+
    | File             | Position | Binlog_Do_DB  | Binlog_Ignore_DB | Executed_Gtid_Set |
    +------------------+----------+---------------+------------------+-------------------+
    | mysql-bin.000001 |      157 | backupbilling |                  |                   |
    +------------------+----------+---------------+------------------+-------------------+
    1 row in set (0,00 sec)
    

    На master-сервере настройте обратную репликацию. В MASTER_HOST укажите адрес backup.

    mysql> STOP SLAVE;
    mysql> CHANGE MASTER TO MASTER_HOST = '192.168.35.2', MASTER_USER = 'replica', MASTER_PASSWORD = 'password', MASTER_LOG_FILE = 'mysql-bin.000001', MASTER_LOG_POS = 157;
    mysql> START SLAVE;
    

    Чтобы проверить статус репликации, выполните запрос:

    mysql> show slave status\G;
    

    В Slave_IO_State указан текущий статус, в Last_IO_Error — последняя ошибка (если есть).

  11. В настройке database установки LBcore (файл billing.conf) укажите пользователя БД с адресом из bind_address. Такой пользователь должен иметь все права, необходимые для работы с БД биллинга.

Варианты резервного переключения

Настроить резервное переключение с помощью keepalived

Если биллинг на master-сервере по какой-то причине станет недоступен, можно автоматически переключаться на backup-сервер. Для этого используется инструмент keepalived, работающий по протоколу VRRP.

  1. Установите keepalived и на master-, и backup- сервере.

    • Debian/Ubuntu:

      apt install keepalived
      
      
      
    • CentOS:

      yum install keepalived
      
      
      

    Также можно собрать keepalived из исходных файлов (подробнее — в документации keepalived).

  2. Создайте скрипт, который будет сигнализировать об изменении состояния установок биллинга.

    Создайте /etc/keepalived/state-notifier.sh на master- и backup- серверах:

    #!/bin/sh
    umask -S u=rwx,g=rx,o=rx
    exec echo "[$(date -Iseconds)]" "$0" "$@" >>"/var/run/keepalived.$1.$2.state"
    

    ``

    Скрипты должны иметь достаточные права для выполнения утилитой:

    chmod 755 /etc/keepalived/state-notifier.sh
    

    ``

  3. Создайте скрипт, выполняющий подготовку при смене состояния узла.

    На backup-сервере создайте два скрипта, которые будут выполняться, когда сервер получит статус основного или когда вернётся в статус резервного.

    Примеры:

    • /etc/keepalived/run_on_master.sh

      #!/bin/sh
      logger -t Keepalived_vrrp "launching resources on switching to master mode..."
      systemctl start lbcore
      systemctl start lbarcd
      systemctl start lbircd
      logger -t Keepalived_vrrp "launching resources complete"
      
      
      
    • /etc/keepalived/run_on_backup.sh

      #!/bin/sh
      logger -t Keepalived_vrrp "stopping resources on switching to master mode..."
      systemctl stop lbircd
      systemctl stop lbarcd
      systemctl stop lbcore
      logger -t Keepalived_vrrp "stopping resources complete"
      
      
      

    Скрипты должны иметь достаточные права для выполнения утилитой.

    Отредактируйте содержимое этих скриптов в соответствии с установленными компонентами и модулями биллинга, которые требуется запускать/останавливать при изменении статуса backup-сервера!

    Примечание: при необходимости на master-сервере можно создать схожие скрипты, если требуется выполнять какие-то действия при потере им статуса основного или при возвращении этого статуса.

    Для некоторых систем, не использующих systemctl (например, старых версий CentOS), следует заменить команды на аналогичные (здесь и далее).

  4. Создайте скрипты для проверки активности узла. Они будут проверять, корректно ли работает узел.

    Скрипт должен возвращать:

    • 0 — если узел полностью работоспособен (т.е. готов работать в качестве основного),
    • ненулевой код — если есть проблемы.

    На master-сервере следует проверять:

    • находится ли биллинг и его компоненты в рабочем состоянии (например, есть ли с ними связь, запущены ли процессы и т.п.),
    • есть ли связь с каким-то устойчивым внешним узлом.

    На backup-сервере следует проверять только связь с устойчивым внешним узлом, т.к. биллинг и его компоненты будут запущены только при получении статуса основного узла.

    Устойчивый внешний узел следует проверять для того, чтобы не возникла ситуация работы одновременно двух мастеров (напр., master-сервер отключился, основным запустился backup, связь между master и backup нарушилась, после этого master запустился, и два сервера стали работать независимо друг от друга, не зная об этом — при синхронизации БД могут возникнуть проблемы).

    В примерах ниже в качестве устойчивого узла проверяется сервер лицензирования, и на backup-сервере проверяется доступность LBcore (можно проверять другие модули или сервисы дополнительно).

    • На master-сервере — скрипт /etc/keepalived/check_con.conf

      #!/bin/sh
      /usr/bin/ping -c1 lic.lanbilling.ru > /dev/null && /bin/nc -z -w 2 127.0.0.1 1502 && exit 0 || exit 1
      
      
      
    • На backup-сервере — скрипт /etc/keepalived/check_con.conf

      #!/bin/sh
      /usr/bin/ping -c1 lic.lanbilling.ru > /dev/null && exit 0 || exit 1
      
      
      
  5. Настройте keepalived.

    На master-сервере создайте (если ещё не создан) и отредактируйте конфигурационный файл /etc/keepalived/keepalived.conf:

    global_defs {
    	enable_script_security
    }
    
    vrrp_script lbcore_check {
    	script /etc/keepalived/check_con.sh
    	interval 10
    	user root
    }
    
    vrrp_instance lbcore_balancer {
    	state MASTER
    	interface ens18
    	virtual_router_id 5
    	priority 100
    	advert_int 1
    	notify /etc/keepalived/state-notifier.sh root
    	authentication {
    		auth_type PASS
    		auth_pass 111111
    	}
    	virtual_ipaddress {
    		192.168.49.50
    	}
    	track_script {
    		lbcore_check
    	}
    }
    

    ``

    • global_defs — раздел глобальных настроек:
      • enable_script_security — разрешает использование скриптов. Без этой опции невозможно настроить скрипты проверки состояния.
    • vrrp_script — раздел с описанием проверки сервиса. Название «lbcore_check» можно изменить на любое удобное.
      • script — путь к исполняемому скрипту, который должен выполнять проверку доступности биллинга. Например, использовать netcat для проверки соединения и т.п. Скрипт должен возвращать 0, если биллинг и сеть работает, и другой код, если нет.
      • interval — периодичность проверки (в секундах).
      • user — пользователь, от лица которого выполняется скрипт.
    • vrrp_instance — раздел настроек экземпляра сервиса. Название «lbcore_balancer» можно заменить на своё.
      • state — начальное состояние узла. Может принимать значения MASTER или BACKUP. В случае, когда в конфигурации указана опция nopreempt (см. ниже), может быть только BACKUP. Укажите на master-сервере MASTER.
      • interface — название сетевого интерфейса, на который будет добавлен виртуальный адрес, когда сервер становится основным.
      • virtual_router_id — идентификатор VRRP (от 1 до 255). У всех узлов это значение должно быть одинаковым.
      • priority — приоритет выбора данного экземпляра в качестве основного. Основным назначается активный сервер, у которого значение параметра priority выше. Если у нескольких серверов priority одинаковый, то выбирается из них случайным образом.
      • advert_int — время (в секундах), с которой основной сервер должен сообщать о себе другим узлам. Если за данное время он не успеет отправить широковещательный сигнал, начнутся выборы другого основного сервера.
      • notify — скрипт, который будет вызываться при каждом изменении состояния сервера (в описываемом случае это скрипт из п. 2), и имя пользователя, от которого он будет выполняться.
      • authentication — опции авторизации. Включает auth_type (тип проверки, рекомендуется PASS — пароль) и auth_pass (значение проверочной строки — пароль не более 8 символов).
      • virtual_ipaddress — блок, задающий виртуальный IP-адрес.
      • track_script — блок, в котором указывается скрипт, проверяющий работоспособность сервиса. Укажите название раздела vrrp_script.

    Примечания:

    • В разделе vrrp_script может быть указана опция fall — количество срабатываний скрипта с ненулевым кодом, после которого начнётся выбор нового мастера. Опция может помочь в случаях «ложного» срабатывания проверочного скрипта (например, когда он не успевает отдать 0 из-за таймаута).

    • В разделе vrrp_instance может быть указана опция nopreempt. В этом случае у всех узлов в конфигурации начальное состояние state должно иметь значение BACKUP.

      Если такая опция указана, то при восстановлении работы прежнего основного сервера он не будет забирать управление на себя, т.е. работа всегда будет продолжаться на текущем выбранном узле, пока он доступен.

      В данном случае рассматривается пример, когда есть приоритетный master-сервер, который должен использоваться всегда, когда доступен, поэтому nopreempt не нужно указывать.

    • Если на master-сервере требуется выполнять какие-то скрипты при возвращении статуса основного или при потере статуса (см. п.3), то их нужно указывать вместе с пользователем, от лица которого они будут выполняться. Это нужно указать в разделе vrrp_instance в настройках:

      • notify_master — выполнится при получении статуса MASTER,
      • notify_backup — выполнится при получении статуса BACKUP,
      • notify_fault — выполнится при получении состояния FAULT.

      Пример:

      notify_master /etc/keepalived/run_on_master.sh root
      notify_backup /etc/keepalived/run_on_backup.sh root
      notify_backup /etc/keepalived/run_on_fault.sh root
      
      
      Обратите внимание**: `notify_master` выполнится также при первоначальном запуске keepalived на master-сервере.
      
      
    • При составлении скрипта для vrrp_script важно учитывать не только проверку доступности биллинга на этом сервере, но и проверку доступности сети (какого-то внешнего устойчивого узла) — если этого не сделать, то может сложиться ситуация, когда связь между master- и backup- серверами пропадёт, master восстановит работу биллинга, и образуется два основных сервера, действующих одновременно и независимо друг от друга.

    На backup-сервере создайте (если ещё не создан) и отредактируйте конфигурационный файл /etc/keepalived/keepalived.conf:

    global_defs {
    	enable_script_security
    }
    
    vrrp_script lbcore_check {
    	script /etc/keepalived/check_con.sh
    	interval 10
    	user root
    }
    
    vrrp_instance lbcore_balancer {
    	state BACKUP
    	interface ens18
    	virtual_router_id 5
    	priority 50
    	preempt_delay 30
    	advert_int 1
    	notify /etc/keepalived/state-notifier.sh root
    	notify_master /etc/keepalived/run_on_master.sh root
    	notify_backup /etc/keepalived/run_on_backup.sh root
    	authentication {
    		auth_type PASS
    		auth_pass 111111
    	}
    	virtual_ipaddress {
    		192.168.49.50
    	}
    	track_script {
    		lbcore_check
    	}
    }
    

    ``

    Настройки схожи с теми, что указывались на master-сервере.

    Меняется только статус узла BACKUP. Приоритет выставляется ниже, чем на master. Название раздела vrrp_instance и виртуальный адрес указываются те же, что и на master.

    В раздел vrrp_instance добавляется настройка preempt_delay — время (в секундах), после которого сервер с более высоким приоритетом заберет обратно себе роль мастера (если он активен). Если настроен параметр nopreempt, то этот параметр задавать не нужно.

    В notify_master и notify_backup обязательно укажите скрипты, выполняемые при сменах статуса (п.3).

  6. Запустите keepalived.

    Включите автозапуск сервиса и запустите его сначала на master-сервере, затем на backup:

    systemctl enable keepalived
    systemctl start keepalived
    

    ``

    Проверьте статус:

    systemctl status keepalived
    

    ``

    Если всё выполнено верно, то на master-сервере вы увидите дополнительный виртуальный адрес (ip a) при работающем биллинге.

    Если при запуске keepalived произошла ошибка, её можно увидеть, например, в логе, как и смены статусов узлов.

    journalctl -u keepalived -f
    

    ``

    Таким же образом настройте дополнительные backup-узлы, если нужно.

Переключение вручную с помощью скриптов

  1. На master-сервере запустите биллинг с необходимыми компонентами.

  2. На backup-сервере установите такой же набор модулей биллинга, но не запускайте.

  3. На backup-сервере добавьте скрипты следующего вида:

    • start_lb.sh

      #!/bin/sh
      systemctl start lbcore
      systemctl start lbarcd
      systemctl start lbircd
      
      
      
    • stop_lb.sh

      #!/bin/sh
      systemctl stop lbircd
      systemctl stop lbarcd
      systemctl stop lbcore
      
      
      

    В этих скриптах перечислите набор сервисов и действий для активации/деактивации биллинга.

    Примечание: если вы работаете с ОС, которая не использует systemctl (например, старая версия CentOS), используйте команды, подходящие для этой ОС.

Выполнение скриптов

При отказе master-сервера выполните скрипт start_lb.sh на backup-сервере.

Перед восстановлением работы master выполните stop_lb.sh на backup-сервере.