Дерево страниц
Перейти к концу метаданных
Переход к началу метаданных

Общие сведения

Резервирование контроллеров SoftWLC необходимо для синхронизации критичных для работы системы файлов (настройки, файлы прошивок, выгрузки данных), баз данных MySQL, баз данных MongoDB, а также DHCP серверов. Такая схема обеспечивает доступность услуг и и актуальные данные на обоих контроллерах при выходе одного из строя, недоступности сети, проблем с электропитанием.

Настройка резервирования контроллеров SoftWLC состоит из следующих этапов:

  • установка и настройка keepalived (выполняется по схеме master-slave)
  • настройка rsync
  • настройка репликации MySQL (осуществляется путём встречной репликации по принципу master-master)
  • настройка replicaSet MongoDB (репликация осуществляется объединением 3 узлов в Replica Set)
  • настройка работы Eltex-PCRF в режиме кластера
  • изменение конфигурации модулей системы для работы с виртуальным IP


В примерах конфигурации в данном разделе для простоты ip-адреса будут указываться как <ip_server1>, <ip_server2> и <virtual_ip>, где:

  • <ip_server1> - реальный ip-адрес первого сервера
  • <ip_server2> - реальный ip-адрес второго сервера
  • <virtual_ip> - виртуальный ip-адрес

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

Синхронизация токенов сервиса eltex-doors

Описание 

После развертывания серверов SoftWLC, на них необходимо синхронизировать токены сервиса eltex-doors. Токены с сервера Primary копируются на потенциальный Secondary с заменой, затем перезапускаются зависящие от них сервисы и повторно генерируются записи в БД.

В данной документации все данные по контроллеру SoftWLC располагаются в директории /home/tester/docker. При расположении контроллера в другой директории изменить путь в ниже перечисленных командах.


Порядок действий

Удалите содержимое папки "/home/tester/docker/data/eltex-doors/etc/eltex-doors/keys" на сервере Slave (файлы private.pem и public.pem).

# На сервере SLAVE
tester@slave:~/docker$ cd /home/tester/docker/data/eltex-doors/etc/eltex-doors/keys
tester@slave:~/docker/data/eltex-doors/etc/eltex-doors/keys$ sudo rm private.pem public.pem 

Скопируйте содержимое папки "/etc/eltex-doors/keys/" с сервера Master на сервер Slave (файлы private.pem и public.pem).

# На сервере MASTER, выполнять от пользователя root
root@master:/home/tester/docker/data/eltex-doors/etc/eltex-doors/keys# scp private.pem public.pem tester@<ip_slave>:

#На сервере slave
tester@slave:~$ sudo cp private.pem public.pem docker/data/eltex-doors/etc/eltex-doors/keys/

На обоих серверах удалите из целевой БД в MySQL записи о токенах сервиса eltex-doors командой:

docker exec -it eltex-mysql mysql -uroot -proot -e "delete from eltex_doors.auth_token;"

Перезапустите на сервере Slave следующие сервисы:  

sudo ./eltex-softwlc-helper-docker_1.30.sh --recreate-service eltex-disconnect-service
sudo ./eltex-softwlc-helper-docker_1.30.sh --recreate-service eltex-doors
sudo ./eltex-softwlc-helper-docker_1.30.sh --recreate-service eltex-johnny
sudo ./eltex-softwlc-helper-docker_1.30.sh --recreate-service eltex-portal
sudo ./eltex-softwlc-helper-docker_1.30.sh --recreate-service eltex-portal-constructor

На обоих серверах удалите из целевой БД в MySQL записи о токенах сервиса eltex-doors командой:

Перейдите к веб-интерфейсу личного кабинета на каждом сервере, адрес "http://<ip-адрес сервера>:8080/wifi-cab", внутри личного кабинета перейдите во вкладку "Сервисы и тарифы". Редактировать ничего не требуется, при переходе в указанный раздел ЛК -  записи об удаленных на шаге "3" токенах сгенерируются в БД повторно.

Установка и настройка keepalived

Описание пакета

Пакет keepalived - это open source программное обеспечение, предназначенное для обеспечения функций высокой надежности (high availabilitty) и балансировки нагрузки (load-balancing). За первую функцию отвечает реализация протокола VRRP, а вторая основывается на модуле ядра Linux Vitrual Server (IPVS). Keepalived не разрабатывается сотрудниками Eltex и не включает доработок, за исключением конфигурации. Keepalived используется для организации резервирования контроллеров SoftWLC, при этом используется только функционал VRRP.

Установка keepalived

Для установки пакета, необходимо загрузить его на сервер и выполнить следующую команду (установка должна производиться от имени суперпользователя root на обоих серверах):

sudo apt update
sudo apt install keepalived

После установки необходимо добавить демона Keepalived в автозагрузку и запустить его:

sudo systemctl enable keepalived
sudo systemctl start keepalived


Основной файл конфигурации

На обоих серверах в файле /etc/keepalived/keepalived.conf меняем следующие параметры: 

<interface> - наименование сетевого интерфейса (свой для каждого сервера) аналогично записи (eth1);

<virtual_ip> - виртуальный ip-адрес (с указанием префикса) аналогично записи (100.111.195.202 /24);

<ip_адрес другого сервера> - ip-адрес другого сервера аналогично записи (100.111.195.200);

/etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
  script_user root
  enable_script_security
}
vrrp_script check_network {
  script "/etc/keepalived/check_ping.sh"
  interval 5
  weight 50
  fall 3
  rise 3
  init_fail
  user root
}

vrrp_instance VI_SWLC {
  state BACKUP
  interface <interface>
  virtual_router_id 1
  track_script {
    check_network
  }
  track_interface {
    <interface> weight 50
  }
  priority 150
  advert_int 1
  nopreempt # Uncomment and comment "nopreempt" if preemption needed
  #preempt_delay 180
  authentication {
    auth_type PASS
    auth_pass eltex
  }
  virtual_ipaddress {
    <virtual_ip> dev <interface> label <interface>:VIP
  }

  notify_master "/etc/keepalived/keep_notify.sh master" 
  notify_backup "/etc/keepalived/keep_notify.sh backup" 
  notify_fault "/etc/keepalived/keep_notify.sh fault"
  unicast_peer {
        <ip_адрес_другого_сервера>
    }
}

Тест-скрипт

Скрипт пингует шлюз по умолчанию и возвращает код результата. Таким образом, при успешном выполнении скрипта, гарантируется, что SoftWLC достижим для внешних клиентов. 

В текущей реализации на обоих серверах, в качестве тестового скрипта, предлагается использовать следующий:

/etc/keepalived/check_ping.sh
#!/bin/bash

# host to ping
# there - default gw
HOST=<default_gw_ip>
# -q quiet
# -c nb of pings to perform
ping -q -c5 $HOST > /dev/null

# $? var keeping result of execution
# previous command
if [ $? -eq 0 ]
    then
        echo `date +"%T %F"` "OK gw reachable"
        EXIT_CODE=0
    else
        echo `date +"%T %F"` "ERROR gw unreacheble!"
        EXIT_CODE=1
fi

exit $EXIT_CODE

где <default_gw_ip> - шлюз по умолчанию для этого сервера аналогично записи (100.10.194.1);.

Конфигурация смены роли

При смене состояния сервера, выполняется скрипт keep_notify.sh, где <mysql_user> и <mysql_password> - логин и пароль от БД MySQL (по умолчанию root/root).

/etc/keepalived/keep_notify.sh
#!/bin/bash

MYSQL_USER="root"
MYSQL_PASSWORD="root"

mongo_set_role() {
    local role="$1"
    if [[ "$(which mongo)" ]]; then
        docker exec eltex-mongo mongo --quiet --eval "var role=\"$role\"" admin /etc/keepalived/mongo_switch.js
        # Uncomment if using mongodb auth
        #mongo -u<username> -p<password> --quiet --eval "var role=\"$role\"" admin /etc/keepalived/mongo_switch.js
    fi
}

if ! lockfile-create --use-pid -r 5 /tmp/keep.mode.lock; then
    echo "Unable to lock"
    echo "Unable to lock" > /tmp/keep.mode.lock.fail
    exit 0
fi

case "$1" in
    master)
    #  ems_reload_all
    echo "MASTER" > /tmp/keep.mode

    mongo_set_role master
    docker container restart eltex-ems-core
    #sudo docker container restart tomcat8 не понимаю что надо стопать
    docker container restart eltex-ngw

    # рестарт слейва MySQL чтобы при восстановлении связи - сразу получить изменения,
    # а не ждать периодического heartbeat от второго сервера
    docker exec eltex-mysql mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "stop slave"
    docker exec eltex-mysql mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "start slave"
  ;;
 backup)
    echo "BACKUP" > /tmp/keep.mode
    mongo_set_role slave
    docker container restart eltex-mongo
    docker container stop eltex-ems-core
    docker container stop eltex-ngw
    docker exec eltex-mysql mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "stop slave"
    docker exec eltex-mysql mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "start slave"
 ;;
 fault)
    echo "FAULT" > /tmp/keep.mode
    mongo_set_role slave

    docker container restart eltex-mongo
 ;;
 *)
    echo "Usage: $0 {master|backup|fault}"
    exit 1
esac

lockfile-remove /tmp/keep.mode.lock;

exit 0

Для того, чтобы скрипты работали корректно, необходимо назначить права на их исполнение:

sudo chmod +x /etc/keepalived/check_ping.sh
sudo chmod +x /etc/keepalived/keep_notify.sh

Для работы вышеупомянутых скриптов необходимо установить на оба хоста пакет lockfile-progs

sudo apt update
sudo apt install lockfile-progs

Выделение лога в отдельный файл

По умолчанию keepalived записывает лог в файл /var/log/syslog . Для удобства отладки, мониторинга и контроля работы keepalived, можно настроить ведение собственного, отдельного лог-файла.

Ниже приведен пример настройки rsyslog:

sudo nano -w /etc/rsyslog.d/10-keepalived.conf

Добавьте в файл 10-keepalived.conf следующее:

/etc/rsyslog.d/10-keepalived.conf
if $programname contains 'Keepalived' then /var/log/keepalived.log
if $programname contains 'Keepalived' then ~

Затем, нужно перезапустить rsyslog командой:

sudo service rsyslog restart

Теперь сообщения от демона keepalived попадут только в лог-файл /var/log/keepalived.log и не попадут в /var/log/syslog .

Способ запуска/остановки keepalived

Для запуска сервиса воспользуйтесь командой:

sudo service keepalived start

Остановка сервиса:

sudo service keepalived stop

Проверить состояние сервиса можно командой:

sudo service keepalived status

На одном из серверов, при корректной настройке, должен отображаться интерфейс с виртуальным ip.

Для проверки работы сервиса keepalived, отключите сервер, у которого в интерфейсах присутствует virtual_ip. Virtual_ip должен появиться на втором сервере. 

Настройка rsync

Rsync в схеме резервирования отвечает за синхронизацию служебных файлов, сервисов Eltex-EMS и Eltex-APB, а также файлов прошивок, шаблонов конфигурации, выгрузок конфигураций точек. Rsync представляет собой клиент серверное ПО. В данной схеме master-сервер выступает в роли клиента и синхронизирует каталоги slave-сервера с локальными.

Конфигурация сервера rsync

Для активации сервера rsync, необходимо на каждом сервере в файле /etc/default/rsync установить значение:
RSYNC_ENABLE=true

Создать файл ,. Листинг файла приведен ниже.

hosts allow = <ip_другого_сервера> <virtual ip>

Запись hosts allow = <ip_другого_сервера> <virtual ip> в конфигурации встречается в 5 местах, не забудьте исправить все значения!
/etc/rsyncd.conf
[ems-conf]
path = <директория SoftWLC>/data/eltex-ems/usr/lib/eltex-ems/conf/
use chroot = no
max connections = 2
lock file = /var/lock/rsyncd
read only = no
list = no
uid = root
auth users = backup
secrets file = /etc/rsyncd.secrets
strict modes = yes
# IP-адрес сервера, который будет иметь доступ к ресурсу, т.е. адрес второго сервера в паре
hosts allow = <ip_server2> <virtual_ip>
ignore errors = no
ignore nonreadable = yes
transfer logging = no
timeout = 60
refuse options = checksum dry-run
dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz

[ems-tftp]
path = <директория SoftWLC>/volumes/eltex-ems/tftpboot
use chroot = no
max connections = 2
lock file = /var/lock/rsyncd.tftp
read only = no
list = no
uid = root
auth users = backup
secrets file = /etc/rsyncd.secrets
strict modes = yes
hosts allow = <ip_server2> <virtual_ip>
ignore errors = no
ignore nonreadable = yes
transfer logging = no
timeout = 60
refuse options = checksum dry-run
dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz

[ems-wp]
path = <директория SoftWLC>/volumes/eltex-ems/var/ems-data/WP
use chroot = no
max connections = 2
lock file = /var/lock/rsyncd.ems-wp
read only = no
list = no
uid = root
auth users = backup
secrets file = /etc/rsyncd.secrets
strict modes = yes
hosts allow = <ip_server2> <virtual_ip>
ignore errors = no
ignore nonreadable = yes
transfer logging = no
timeout = 60
refuse options = checksum dry-run
dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz

[radius-nbi-certs]
path = <директория SoftWLC>/volumes/eltex-radius-nbi/var/lib/eltex-radius-nbi
use chroot = no
max connections = 2
lock file = /var/lock/rsyncd.radius
read only = no
list = no
uid = root
auth users = backup
secrets file = /etc/rsyncd.secrets
strict modes = yes
hosts allow = <ip_server2> <virtual_ip>
ignore errors = no
ignore nonreadable = yes
transfer logging = no
timeout = 60
refuse options = checksum dry-run
dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz

[radius-certs]
path = <директория SoftWLC>/data/eltex-radius/etc/eltex-radius/certs
use chroot = no
max connections = 2
lock file = /var/lock/rsyncd.radius
read only = no
list = no
uid = root
auth users = backup
secrets file = /etc/rsyncd.secrets
strict modes = yes
hosts allow = <ip_server2> <virtual_ip>
ignore errors = no
ignore nonreadable = yes
transfer logging = no
timeout = 60
refuse options = checksum dry-run
dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz

Для аутентификации, необходимо настроить пользователя rsync, для этого, на каждом сервере создайте файлы /etc/rsyncd.secrets, в которых необходимо указать пароль.

/etc/rsyncd.secrets
backup:rspasswd

Назначить права доступа к файлам, выполнив на обоих серверах:

sudo chmod 600 /etc/rsyncd.secrets

Настройка запуска синхронизации
Создайте файлы /etc/rsync_client.secrets, в которых укажите пароль:                           

echo "rspasswd" | sudo tee /etc/rsync_client.secrets && sudo chmod 600 /etc/rsync_client.secrets

Способ запуска/остановки

Для запуска сервиса используется команда:

sudo service rsync start

Для остановки сервиса используется команда:

sudo service rsync stop

Для проверки — запущен ли сервис в данный момент, используется команда:

sudo service rsync status

Конфигурация скрипта для  eltex-ems

Операцию синхронизации файлов осуществляет задача cron, в которой выполняется скрипт rsync_ems_backup.sh. Скрипт запускает rsync клиент и синхронизирует локальные директории с директориями на втором (backup) сервере. Синхронизация запускается только в случае, если сервер в состоянии master. 

Необходимо создать данный файл в директории, где расположен скрипт для запуска softwlc в docker, например "/home/tester/docker", а также выдать ему права на исполнение (chmod +x rsync_ems_backup.sh)

В строках 6,8,10 необходимо указать директорию, где находится скрипт для запуска softwlc в docker
В 13 строке заменить HOST  на ip-адрес другого сервера (Пример: HOST=100.111.195.201)

rsync_ems_backup.sh
#!/bin/bash

LOCKFILE="/run/lock/rsync_ems_backup"

# when using docker, specify the path: <directory where docker is deployed>/data/eltex-ems/usr/lib/eltex-ems/conf/
EMS_CONF="<Директория с SoftWLC>/data/eltex-ems/usr/lib/eltex-ems/conf/"
# when using docker, specify the path: <directory where docker is deployed>/volumes/eltex-ems/tftpboot/
EMS_TFTP="<Директория с SoftWLC>/volumes/eltex-ems/tftpboot/"
# when using docker, specify the path: <directory where docker is deployed>/volumes/eltex-ems/var/ems-data/WP/
EMS_WP="<Директория с SoftWLC>/volumes/eltex-ems/var/ems-data/WP/"

# IP address backup server
HOST=<ip адрес второго сервера>
# Check if we're root
if [ `whoami` != "root" ]
    then
    echo "This script should be run by root."
    exit 1
fi

# Check and create lock file
if ! lockfile-create --use-pid -r 0 $LOCKFILE &> /dev/null ; then
    echo "Backup is already running"
    exit 0
fi

FOLDER="/tmp/rsync"
if [ ! -d "$FOLDER" ]
then
    mkdir $FOLDER
fi

# Check - if we're master - try to perform backup to slave
SRVMODE=`cat /tmp/keep.mode`
if [ "$SRVMODE" == "MASTER" ]
    then
    rsync -urlogtp --delete-after --password-file=/etc/rsync_client.secrets $EMS_CONF backup@$HOST::ems-conf > /tmp/rsync/rsync_ems_conf.log 2>&1
    echo $? >> /tmp/rsync/rsync_ems_conf_result.log
    rsync -urlogtp --delete-after --password-file=/etc/rsync_client.secrets $EMS_TFTP backup@$HOST::ems-tftp > /tmp/rsync/rsync_ems_tftpboot.log 2>&1
    echo $? >> /tmp/rsync/rsync_ems_tftpboot_result.log
    rsync -urlogtp --delete-after --password-file=/etc/rsync_client.secrets $EMS_WP backup@$HOST::ems-wp > /tmp/rsync/rsync_ems_wp.log 2>&1
    echo $? >> /tmp/rsync/rsync_ems_wp_result.log
else
    echo "Not master. No action will be performed."
fi

lockfile-remove $LOCKFILE

Конфигурация скрипта для  eltex-radius/eltex-radius-nbi

Сервис eltex-radius-nbi генерирует для каждой из нод свой собственный CA и серверный сертификат, после чего копирует их в eltex-radius:

  • <директория SoftWLC>/volumes/eltex-radius-nbi/var/lib/eltex-radius-nbi/wireless-ca.crt     →     <директория SoftWLC>/data/eltex-radius/etc/eltex-radius/certs/ca/local.pem
  • <директория SoftWLC>/volumes/eltex-radius-nbi/var/lib/eltex-radius-nbi/certificates/server.crt     →     <директория SoftWLC>/data/eltex-radius/etc/eltex-radius/certs/server.crt
  • <директория SoftWLC>/volumes/eltex-radius-nbi/var/lib/eltex-radius-nbi/certificates/server.crt     →     <директория SoftWLC>/data/eltex-radius/etc/eltex-radius/certs/server.key

На основании wireless-ca.crt буду генерироваться клиентские сертификаты (создаются через ЛК) в директории /var/lib/eltex-radius-nbi/certificates/
При создании сертификата пользователя через ЛК он будет сгенерирован на только ноде, на которой сейчас вы находитесь и на основании его собственного wireless-ca.crt.
Поэтому при переходе мастерства вторая нода не будет ничего знать о клиентских сертификатах.

Обязательно убедитесь, что в файле <директория SoftWLC>/environment-overrides/eltex-radius-nbi.env в переменной TOMCAT_HOST установлен ваш виртуальный ip-адрес


Чтобы это исправить нужно:

  1. Выбираем ноду, которая будет владеть актуальными данными, например первую ноду
  2. Добавить ip-адрес второго хоста в переменную окружения 

    echo "export SLAVE_HOST="YOUR_IP"" | sudo tee /etc/environment && source /etc/environment
  3. Создайте в директории SoftWLC файл rsync_radius_cert_synchronization.sh и выдайте права на его выполнение (chmod +x rsync_radius_cert_synchronization.sh)

  4.  rsync_radius_cert_synchronization.sh
    #!/bin/bash
    # You mustn't change this script. After new installation it will be replaced.
    
    LOCKFILE="/run/lock/rsync_radius_cert_synchronization"
    
    # when using docker, specify the path: <directory where docker is deployed>/volumes/eltex-radius-nbi/var/lib/eltex-radius-nbi/
    RADIUS_NBI_CERTS="/home/tester/docker/volumes/eltex-radius-nbi/var/lib/eltex-radius-nbi/"
    # when using docker, specify the path: <directory where docker is deployed>/data/eltex-radius/etc/eltex-radius/certs/
    RADIUS_CERTS="/home/tester/docker/data/eltex-radius/etc/eltex-radius/certs/"
    
    # IP address server for synchronization.
    # Please before all define SLAVE_HOST for your environment.
    SLAVE_HOST=${SLAVE_HOST:-SLAVE_HOST_DEFAULT}
    # Check if we're root
    if [ `whoami` != "root" ]
        then
        echo "This script should be run by root."
        exit 1
    fi
    
    # Check and create lock file
    if ! lockfile-create --use-pid -r 0 $LOCKFILE &> /dev/null ; then
        echo "Backup is already running"
        exit 0
    fi
    
    # Check - if we're master - try to perform backup to slave
    SRVMODE=`cat /tmp/keep.mode`
    if [ "$SRVMODE" == "MASTER" ]
        then
        rsync -urlogtp --password-file=/etc/rsync_client.secrets $RADIUS_NBI_CERTS backup@$SLAVE_HOST::radius-nbi-certs > /tmp/rsync_radius_nbi_certs.log 2>&1
        echo $? >> /tmp/rsync_radius_nbi_certs.log
        rsync -urlogtp --password-file=/etc/rsync_client.secrets $RADIUS_CERTS backup@$SLAVE_HOST::radius-certs > /tmp/rsync_radius_certs.log 2>&1
        echo $? >> /tmp/rsync_radius_certs.log
    else
        echo "Not master. No action will be performed."
    fi
    
    lockfile-remove $LOCKFILE
    
    
  5.  Запустить команды с выбранной вами ноды в статусе "MASTER"
    sudo rsync -rlogtp --delete-after --password-file=/etc/rsync_client.secrets <директория SoftWLC>/volumes/eltex-radius-nbi/var/lib/eltex-radius-nbi/ backup@$SLAVE_HOST::radius-nbi-certs > /tmp/rsync_radius_nbi_certs.log 2>&1

    sudo rsync -rlogtp --delete-after --password-file=/etc/rsync_client.secrets <директория SoftWLC>/data/eltex-radius/etc/eltex-radius/certs/ backup@$SLAVE_HOST::radius-certs > /tmp/rsync_radius_certs.log 2>&1

    эти команды синхронизируют данные с вашей второстепенной нодой

  6.  убедитесь, что файлы в директориях /var/lib/eltex-radius-nbi/ и /etc/eltex-radius/certs/ совпадают
  7.  выполнить команду на двух нодах
    sudo ./eltex-softwlc-helper-docker_1.30.sh --recreate-service eltex-radius


Статус можно проверить в файле /tmp/keep.mode

Настройка cron


Cоздать задачу в cron на обоих серверах, для запуска синхронизации раз в минуту:

sudo crontab -l | { cat; echo "*/1 * * * * <Директория SoftWLC>/rsync_ems_backup.sh"; } | sudo crontab
sudo crontab -l | { cat; echo "*/1 * * * * <Директория SoftWLC>/rsync_radius_cert_synchronization.sh"; } | sudo crontab

Проверяем список задач:

sudo crontab -l
*/1 * * * * <Директория SoftWLC>/rsync_ems_backup.sh
*/1 * * * * <Директория SoftWLC>/rsync_radius_cert_synchronization.sh

Если задача не добавилась или случайно добавилась несколько раз - редактируем список вручную:

sudo crontab -e

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.tiny
  3. /usr/bin/code
  4. /bin/ed

Choose 1-4 [1]: 1                                 # выбираем в каком редакторе открыть

Проверить работу rsync можно в EMS. Во вкладке "Информация"-Состояние системы резервирования-Rsync service. 

На обоих серверах должна быть запись такого типа:

OK. Успешная синхронизация файлов из директории: /usr/lib/eltex-ems/conf/* 
OK. Успешная синхронизация файлов из директории: /tftpboot/* 
OK. Успешная синхронизация файлов из директории: /var/ems-data/WP/*

Настройка репликации MySQL

Резервирование данных, хранящихся СУБД MySQL, осуществляется путём встречной репликации по принципу master-master (ведущий-ведущий). То есть, каждый из серверов одновременно является и master и slave. При такой схеме работы, все изменения в БД на одном сервере записываются в специальный бинарный лог, который в реальном времени вычитывает второй сервер и применяет изменения. Второй сервер реплицирует данные с первого, а первый со второго. Это позволяет получить актуальную копию БД на двух хостах одновременно. При разрыве связи, изменения накапливаются, после восстановления происходит синхронизация.

Перенос дампа данных и перенос на второй сервер

При настройке резервирования в процессе эксплуатации (то есть если в MySQL на действующем сервере уже имеются данные), необходимо перенести эти данные на второй сервер. Это можно сделать при помощи утилиты mysqldump.

Для этого, необходимо на первом сервере заблокировать таблицы, снять дамп, разблокировать таблицы и скопировать получившийся файл на второй сервер:

1) sudo docker exec -it eltex-mysql bash
2) mysql -uroot -proot -e "FLUSH TABLES WITH READ LOCK;"
2) mysqldump -uroot -proot --databases ELTEX_PORTAL eltex_alert eltex_auth_service eltex_bruce eltex_doors eltex_ems eltex_jobs eltex_ngw eltex_ont radius wireless eltex_pcrf  eltex_wids eltex_ott eltex_sorm2 eltex_jerry eltex_wifi_customer_cab > mysqldump_master.sql
3) mysql -uroot -proot -e "UNLOCK TABLES;"
4) scp mysqldump_master.sql <username>@<ip_server2>:/home/<username>/

Затем, развернуть dump на втором сервере:

1) sudo docker cp /home/<username>/mysqldump_master.sql eltex-mysql:/
2) sudo docker exec -it eltex-mysql
3) mysql -uroot -proot < /home/<username>/mysqldump_master.sql

Конфигурация MySQL

Конфигурация самого демона mysqld заключается в настройке параметров ведения бинарных логов. Обозначения первый сервер и второй сервер далее условны, и применяются лишь для обозначения различий в конфигурации серверов.

Необходимо скопировать конфигураионный файл mysql из контейнера в рабочую директорию softwlc на каждом хосте:

docker cp eltex-mysql:/etc/mysql/mysql.conf.d/mysqld.cnf <директория SoftWLC>/

В секции [mysqld] файла конфигурации /etc/mysql/mysql.conf.d/mysqld.cnf произвести следующие изменения:

Указать server-id. Для серверов необходимо задать уникальные идентификаторы, к примеру, для первого:

 /etc/mysql/mysql.conf.d/mysqld.cnf
server-id = 1

для второго:

/etc/mysql/mysql.conf.d/mysqld.cnf
server-id = 2

Включить бинарные логи на обоих серверах:

/etc/mysql/mysql.conf.d/mysqld.cnf
log_bin = /var/log/mysql/mysql-bin.log

указать параметры auto_increment_increment (шаг приращения) и auto_increment_offset (стартовую точку).

Для первого сервера:

/etc/mysql/mysql.conf.d/mysqld.cnf
auto_increment_increment= 2
auto_increment_offset = 1

Для второго сервера:

/etc/mysql/mysql.conf.d/mysqld.cnf
auto_increment_increment= 2
auto_increment_offset = 2

На обоих серверах: указать базы, для которых будут вестись логи:

/etc/mysql/mysql.conf.d/mysqld.cnf
binlog-do-db = eltex_alert
binlog-do-db = eltex_ems
binlog-do-db = wireless
binlog-do-db = radius
binlog-do-db = eltex_auth_service
binlog-do-db = ELTEX_PORTAL
binlog-do-db = eltex_doors
binlog-do-db = eltex_ngw
binlog-do-db = eltex_bruce
binlog-do-db = eltex_jobs
binlog-do-db = eltex_ont
binlog-do-db = eltex_pcrf
binlog-do-db = eltex_wids
binlog-do-db = eltex_wifi_customer_cab
binlog-do-db = eltex_sorm2
binlog-do-db = eltex_ott
binlog-do-db = eltex_jerry

yказать базы, для которых не будут вестись логи:

/etc/mysql/mysql.conf.d/mysqld.cnf
binlog-ignore-db = mysql
binlog-ignore-db = Syslog
binlog-ignore-db = performance_schema
binlog-ignore-db = information_schema

Необходимо привести раздел docker-compose.yml о контейнере eltex-mysql к следующему виду:

  eltex-mysql:
    container_name: eltex-mysql
    image: ${ELTEX_HUB}/eltex-mysql:${SWLC_VERSION}
    restart: unless-stopped
    networks:
      - swlc_innernet
    ports:
      # replication
      - "33061:33061/tcp" 
      - "3306:3306/tcp" 
    env_file:
      - environment/eltex-mysql.env
      - environment-overrides/eltex-mysql.env
    environment:
      # Настройки таймзоны
      - TZ=${TZ}
    volumes:
      - ./volumes/mysql/datadir:/var/lib/mysql
      - ./mysqld.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf:ro


Перезапустить сервис mysql на каждом сервер и создать БД для репликации:

sudo docker compose down eltex-mysql
sudo docker compose up -d eltex-mysql

Создание учетных записей

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

Создать в консоли MySQL(sudo docker exec -it eltex-mysql mysql -uroot -proot) учетную запись для репликации на первом сервере:

Выполнять из mysql-client ((sudo docker exec -it eltex-mysql mysql -uroot -proot)
GRANT SELECT, SUPER, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replication'@'<ip_server2>' IDENTIFIED BY 'password';
GRANT SELECT, SUPER, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replication'@'172.30.0.1' IDENTIFIED BY 'password'; #необходимо для проверки состояния репликации из EMS
FLUSH PRIVILEGES;

Создать в консоли MySQL учетную запись для репликации на втором сервере:

Выполнять из mysql-client (sudo docker exec -it eltex-mysql mysql -uroot -proot)
GRANT SELECT, SUPER, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replication'@'172.30.0.1' IDENTIFIED BY 'password';
GRANT SELECT, SUPER, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replication'@'<ip_server2>' IDENTIFIED BY 'password'; #необходимо для проверки состояния репликации из EMS
FLUSH PRIVILEGES;

Адрес 172.30.0.1 задается параметрами подсети в файле docker-compose.yml по умолчанию. При необходимости этот параметр можно изменить.

Привилегия SELECT необходима для работы проверки репликации из GUI EMS

Выдача прав сервисным пользователям

Открыть <Директория SoftWLC>/data/eltex-ems/usr/lib/eltex-ems/conf/config.txt, посмотреть какие username / password используются (по умолчанию - javauser / javapassword)

Выдаем им права на внешний доступ на обоих серверах:

Выполнять из mysql-client (sudo docker exec -it eltex-mysql mysql -uroot -proot)
GRANT ALL PRIVILEGES ON *.* TO 'javauser'@'%' IDENTIFIED BY 'javapassword';
GRANT ALL PRIVILEGES ON eltex_auth_service.* TO 'javauser'@'%'; 
GRANT ALL PRIVILEGES ON `radius`.* TO 'javauser'@'%';             
GRANT ALL PRIVILEGES ON `wireless`.* TO 'javauser'@'%';           
GRANT ALL PRIVILEGES ON `Syslog`.* TO 'javauser'@'%';             
GRANT ALL PRIVILEGES ON `eltex_doors`.* TO 'javauser'@'%';        
GRANT ALL PRIVILEGES ON `eltex_ngw`.* TO 'javauser'@'%';          
GRANT ALL PRIVILEGES ON `ELTEX_PORTAL`.* TO 'javauser'@'%';       
GRANT ALL PRIVILEGES ON `eltex_ems`.* TO 'javauser'@'%';          
GRANT ALL PRIVILEGES ON `eltex_alert`.* TO 'javauser'@'%';        
GRANT ALL PRIVILEGES ON `eltex_auth_service`.* TO 'javauser'@'%';
GRANT ALL PRIVILEGES ON `eltex_bruce`.* TO 'javauser'@'%';
GRANT ALL PRIVILEGES ON `eltex_pcrf`.* TO 'javauser'@'%';
GRANT ALL PRIVILEGES ON `eltex_wids`.* TO 'javauser'@'%';
GRANT ALL PRIVILEGES ON `eltex_sorm2`.* TO 'javauser'@'%';
GRANT ALL PRIVILEGES ON `eltex_jerry`.* TO 'javauser'@'%';
GRANT ALL PRIVILEGES ON `eltex_ott`.* TO 'javauser'@'%';
GRANT ALL PRIVILEGES ON `eltex_wifi_customer_cab`.* TO 'javauser'@'%';
GRANT ALL PRIVILEGES ON `eltex_jobs`.* TO 'javauser'@'%';
FLUSH PRIVILEGES;

Включение репликации

Запуск репликации на втором сервере

На первом сервере, в консоли MySQL(sudo docker exec -it eltex-mysql mysql -uroot -proot), выполнить команду show master status и проанализировать полученные значения:

Выполнять из mysql-client (sudo docker exec -it eltex-mysql mysql -uroot -proot)
show master status \G

*************************** 1. row ***************************
            File: mysql-bin.000001
        Position: 00000107
    Binlog_Do_DB: eltex_alert,eltex_ems,wireless,radius,eltex_auth_service,ELTEX_PORTAL,eltex_doors,eltex_ngw,eltex_bruce,eltex_jobs,eltex_ont,eltex_pcrf,eltex_wids,eltex_wifi_customer_cab,
eltex_sorm2,eltex_ott,eltex_jerry
Binlog_Ignore_DB: mysql,Syslog,performance_schema,information_schema
1 row in set (0.00 sec)

Запомнить параметры File и Position.

Настроить и запустить репликацию второго сервера с первого (выполнить действия на втором сервере):

Выполнять из mysql-client (sudo docker exec -it eltex-mysql mysql -uroot -proot)
STOP SLAVE;
CHANGE MASTER TO MASTER_HOST='<ip_server1>', MASTER_USER='replication', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=107;
START SLAVE;

где,

MASTER_LOG_FILE='mysql-bin.000001' – указать значение File, полученное на первом сервере;
MASTER_LOG_POS=107 – указать значение Position, полученное на первом сервере.

Проверить состояние репликации на втором сервере:

Выполнять из mysql-client (sudo docker exec -it eltex-mysql mysql -uroot -proot)
show slave status \G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: <ip_server1>
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 107
               Relay_Log_File: mysqld-relay-bin.000001
                Relay_Log_Pos: 107
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 107
              Relay_Log_Space: 107
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2
1 row in set (0.00 sec)

Если параметры Slave_IO_Running и Slave_SQL_Running имеют значение «Yes», репликация успешно запустилась.

Запуск репликации на первом сервере

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

Выполнять из mysql-client (sudo docker exec -it eltex-mysql mysql -uroot -proot)
show master status \G

*************************** 1. row ***************************
            File: mysql-bin.000001
        Position: 00000107
    Binlog_Do_DB: eltex_alert,eltex_ems,wireless,radius,eltex_auth_service,ELTEX_PORTAL,eltex_doors,eltex_ngw,eltex_bruce,eltex_jobs,eltex_ont,eltex_pcrf,eltex_wids,eltex_wifi_customer_cab,
eltex_sorm2,eltex_ott,eltex_jerry
Binlog_Ignore_DB: mysql,Syslog,performance_schema,information_schema
1 row in set (0.00 sec)

Настроить и запустить репликацию первого сервера со второго (выполнять действия на первом сервере):

Выполнять из mysql-client (sudo docker exec -it eltex-mysql mysql -uroot -proot)
STOP SLAVE;
CHANGE MASTER TO MASTER_HOST='<ip_server2>', MASTER_USER='replication', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=107;
START SLAVE;

Проверить состояние репликации на первом севере:

Выполнять из mysql-client (sudo docker exec -it eltex-mysql mysql -uroot -proot)
show slave status \G
*************************** 1. row *************************** 
               Slave_IO_State: Waiting for master to send event
                  Master_Host: <ip_server2>
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 107
               Relay_Log_File: mysqld-relay-bin.000001
                Relay_Log_Pos: 107
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...

Если параметры Slave_IO_Running и Slave_SQL_Running имеют значение «Yes», значения Master_Log_File и Read_Master_Log_Pos репликация выполняется в обе стороны.

Проверка репликации из EMS-GUI

Состояние репликации MySQL можно контролировать из GUI EMS. Для этого, необходимо отредактировать конфигурационный файл check-ems-replication.conf в директории SoftWLC. Изменения необходимо внести на обоих серверах.

<Директория SoftWLC>/check-ems-replication.conf
# Включить("Yes") / Выключить("No") проверку репликации
ENABLE_REPLICATION="Yes"

# Адрес первого хоста репликации
HOST1=<ip_server1>
# Адрес второго хоста репликации
HOST2=<ip_server2>
 

# параметры доступа к mysql серверу
#  mysql пользователь
USER="replication"
#  mysql пароль
PASSWORD="password"

где,

ENABLE_REPLICATION - включена ли проверка репликации (установить в "Yes");
HOST1, HOST2 - ip-адреса серверов;
USER, PASSWORD - логин/пароль учетной записи, для работы репликации.

После сохранения изменений, состояние репликации можно отслеживать в GUI EMS в разделе Информация → Состояние системы резервирования → MySQL.

Настройка MongoDB

В MongoDB репликация осуществляется объединением нескольких (в типовой конфигурации - 3) узлов в Replica Set. Replica Set состоит из одного primary узла и нескольких secondary. Для упрощения предлагаем схему:

  • Primary — основной сервер mongoDB.
  • Secondary — точные копии баз(ы) данных с real-time синхронизацией.
  • Arbiter — сервер отвечает только за выборы преемника, сам стать преемником он не может, поэтому рекомендуется отдавать под арбитра минимальные ресурсы, SoftWLC на  аrbiter устанавливать не требуется.

Минимальные характеристики для mongo-db arbiter:

  • vCore: 1, 64-bit x86 CPUs
  • vRAM: 2 ГБ
  • vHDD: 20Гб

Примечание

Для корректной работы репликации необходимо, чтобы версии MongoDB совпадали на всех хостах.

​Все операции по изменению данных выполняются только на primary. При этом MongoDB автоматически выполняет failover и смену primary на живой узел, если текущий primary выйдет из строя. Но это требует 3+ узлов в replica set.

При конфигурации по умолчанию Replica Set из двух узлов полностью выходит из строя при отказе одного из них (даже secondary).

Установка mongodb на arbiter

Для запуска Arbiter на 3-м хосте можно воспользоваться образом eltex-mongo. Создадим папку и необходимые файлы для этого. Для запуска контейнера с арбитром необходим установленный docker  и docker compose на хосте.

mkdir mongo
cd mongo
touch docker-compose.yml
touch .env
docker-compose.yml
version: "3"
services:
  eltex-mongo:
    container_name: eltex-mongo
    image: ${ELTEX_HUB}/eltex-mongo:${SWLC_VERSION}
    ports:
      - "27017:27017/tcp"
      - "27017:27017/udp"
    restart: unless-stopped
    volumes:
      - ./volumes/mongo/data/db:/data/db
      - ./volumes/mongo/data/configdb:/data/configdb
      - ./volumes/mongo/etc/mongo:/etc/mongo
    command: mongod --bind_ip_all --replSet TEST
.env
ELTEX_HUB=hub.eltex-co.ru/softwlc
SWLC_VERSION=1.30

Также, к данному виду docker-compose.yml необходимо привести и остальные хосты, на которых запущена MongoDB, песле чего перезапустить контейнер командой:

sudo docker compose down eltex-mongo
sudo docker compose up -d eltex-mongo


Настройка replicaSet

На первом узле зайти в консоль MongoDB:

sudo docker exec -it eltex-mongo mongo

Создать конфигурацию replica set:

mongo
rs.initiate(
   {
      _id: "replica_set_name",
      version: 1,
      members: [
         { _id: 0, host : "ip_mongo_primary:27017" },
         { _id: 1, host : "ip_mongo_secondary:27017" }
      ]
   }
)

Добавить в Replica Set узел Arbiter (на PRIMARY):

mongo
rs.add("<ip_server>:27017",true) 

Через некоторое время, приглашение shell должно смениться на такое:

mongo
replica_set_name:PRIMARY>

Посмотреть конфигурацию Replica Set можно командой:

mongo
rs.config()

Для проверки состояния Replica Set, выполните в консоли MongoDB команду rs.status().

Добавление/удаление/изменение узлов в Replica Set

Настройку узлов в Replica Set можно выполнять только на PRIMARY.

Добавить в Replica Set узел Secondary (на PRIMARY):

mongo
rs.add("<ip_server>:27017")

Если MongoDB отвечает на эту команду ошибкой, возможно, нет связи со вторым узлом (или там прописан bindIp: 127.0.0.1), или там не настроен блок replication.
На втором узле приглашение консоли управления MongoDB должно смениться на:

mongo
mongo
replica_set_name:SECONDARY>

Добавить в Replica Set узел Arbiter:

mongo
rs.add("<ip_server>:27017",true)

Удалить  узел из Replica Set (выполнять на PRIMARY):

mongo
rs.remove("<ip_server>:27017")

Для корректировки адреса сервера выполнить следующее:

mongo
cfg = rs.conf()
cfg.members[<индекс>].host = "<ip_server>:27017"
rs.reconfig(cfg)
Для проверки работоспособности репликации, отключите PRIMARY сервер, сервер, который был SECONDARY, перейдет в статус PRIMARY


Работа Eltex-PCRF в режиме кластера

Настройка кластера PCRF

Между серверами PCRF нужно открыть порты 5701 tcp, 5801 tcp 

На серверах в файлах конфигурации /etc/eltex-pcrf/hazelcast-cluster-network.xml нужно указать адреса сетевых интерфейсов (в строках 5 и 22 в примере - адрес самого сервера, строки 14-15 - список всех членов кластера)
пример, часть конфигурации:

<Директория SoftWLC>/data/eltex-pcrf/etc/eltex-pcrf/hazelcast-cluster-network
<network>
    <!-- Write here public address of the node -->
 
    <!-- здесь нужно указать собственный адрес сервера -->
    <public-address>ip_server1</public-address>
    <port auto-increment="false" port-count="100">5701</port>
    <outbound-ports>
        <ports>0</ports>
    </outbound-ports>
    <join>
        <multicast enabled="false"/>
        <tcp-ip enabled="true">
            <!-- Перечислить IP-адреса всех членов кластера (включая этот) -->
            <member>ip_server1</member>
            <member>ip_server2</member>
        </tcp-ip>
        <discovery-strategies>
        </discovery-strategies>
    </join>
    <interfaces enabled="true">
    <!-- здесь нужно указать собственный адрес сервера -->
        <interface>ip_server1</interface>
    </interfaces>

В конфигурации <Директория Softwlc>/environment-override/eltex-pcrf.env нужно разрешить запуск кластера:

PCRF_cluster.enable=true


Перезапустить Eltex-PCRF командой

sudo docker compose down eltex-pcrf
sudo docker compose up -d eltex-pcrf

Проверка состояния кластера

{
  "data": {
    "enabled": true,
    "state": "ACTIVE",
    "members": [
      {
        "address": "ip_server1",
        "local": true,
        "active": true
      },
      {
        "address": "ip_server2",
        "local": false,
        "active": true
      }
    ]
  },
  "key": "PcrfErrorCode.success",
  "message": "Success",
  "code": 0,
  "args": [
    
  ]
}

Особенности настройки ESR для взаимодействия с кластером PCRF

При использовании кластера PCRF на ESR настроить взаимодействие со всеми нодами кластера используя их реальный адрес.

Настройка модулей SoftWLC

Необходимо настроить модули SoftWLC на работу с контроллером по virtual ip на обоих серверах. Необходимо внести изменения в файлы конфигурации environment-override/<Сервис>.env. По умолчанию данные файлы пустые.


Внимание! При изменении настроек подключения к БД Mysql и MongoDB следует исключительно внимательно относится к настройкам коннектов к БД  - ошибки в настройке, такие как ошибки в символах между параметрами (например "?" вместо "&"), лишние символы и т. п. приведут к сложно диагностируемым ошибкам подключения к БД!

После внесения изменений в конфигурационные файлы необходимо перезапустить соответствующий сервис:

sudo docker compose restart <Название сервиса>

Файл .env.override
MONGO_URL=mongodb://<ip_mongo_primary>,<ip_mongo_secondary>:27017
Файл environment/eltex-pcrf.env
PCRF_cluster.enable=true

PCRF_radius__url=jdbc:mysql://<virtual_ip>/radius?useUnicode=true&characterEncoding=utf8&connectTimeout=5000&socketTimeout=5000&autoReconnect=true&useSSL=false

PCRF_mongo.pcrf__connection_string=${MONGO_URL}/pcrf?replicaSet=<Название реплики>&waitQueueMultiple=500&connectTimeoutMS=10000&socketTimeoutMS=0&readPreference=secondaryPreferred

PCRF_sql.ems__url=jdbc:mysql://<virtual_ip>/eltex_ems?useUnicode=true&characterEncoding=utf8&connectTimeout=5000&socketTimeout=5000&autoReconnect=true&useSSL=false

PCRF_sql.wireless__url=jdbc:mysql://<virtual_ip>/wireless?useUnicode=true&characterEncoding=utf8&connectTimeout=5000&socketTimeout=5000&autoReconnect=true&useSSL=false

PCRF_sql.auth.service__url=jdbc:mysql://<virtual_ip>/eltex_auth_service?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&connectTimeout=5000&socketTimeout=5000&useSSL=false

PCRF_sql.pcrf__url=jdbc:mysql://<virtual_ip>/eltex_pcrf?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&socketTimeout=5000

PCRF_sql.ott__url=jdbc:mysql://<virtual_ip>/eltex_ott?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&socketTimeout=5000

PCRF_clickhouse__url=jdbc:clickhouse://<virtual_ip>:8123/radius


Файл environment-override/eltex-portal-constructor.env
# Хост подключения к БД
database.host=<virtual_ip>


Файл environment-override/eltex-portal.env
# Хост подключения к БД
database.host=<virtual_ip>


Файл environment-override/eltex-radius-nbi.env
# DB  radius(alias=radius)
RADIUS_JDBC_DBURL=jdbc:mysql://<virtual_ip>/radius?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false

# DB  radius replica(alias=radiusReplicaPool)
RADIUS_JDBC_REPLICA_DBURL=jdbc:mysql://<virtual_ip>/radius?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false

# DB ems(alias=ems)
EMS_JDBC_DBURL=jdbc:mysql://<virtual_ip>/eltex_ems?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false&noAccessToProcedureBodies=true

# DB  wireless (alias=wireless)
WIRELESS_JDBC_DBURL=jdbc:mysql://<virtual_ip>/wireless?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false

# DB logs (alias=logs)
LOGS_JDBC_DBURL=jdbc:mysql://<virtual_ip>/eltex_alert?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false

# DB logs (alias=eltex_auth_service)
ELTEX_AUTH_SERVICE_JDBC_DBURL=jdbc:mysql://<virtual_ip>/eltex_auth_service?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false

# адрес ems-northbound
# IP-адрес сервера EMS
EMS_NBI_HOST=<virtual_ip>

# pcrf stuff
PCRF_ENABLED=true
# адрес Eltex-PCRF
PCRF_URL=http://<virtual_ip>:7070

# pcrf mysql
PCRF_JDBC_DBURL=jdbc:mysql://<virtual_ip>:3306/eltex_pcrf?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000

# wifi-customer-cab mysql
WIFI_CAB_JDBC_DBURL=jdbc:mysql://<virtual_ip>:3306/eltex_wifi_customer_cab?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000

# Eltex.SORM2.replicator MariaDB 'sorm2' connect
SORM2_JDBC_DBURL=jdbc:mysql://<virtual_ip>:3306/eltex_sorm2?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000

# ott mysql
OTT_JDBC_DBURL=jdbc:mysql://<virtual_ip>:3306/eltex_ott?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000

# ott mongodb connector
OTT_MONGODB_ENABLED=true
OTT_MONGODB_URI=${MONGO_URL}/ott?replicaSet=<Название реплики>

PORTAL_DB_URL=jdbc:mysql://<virtual_ip>:3306/ELTEX_PORTAL?max_allowed_packet=32362048&useUnicode=true&characterEncoding=utf8&useSSL=false
PORTAL_DB_USERNAME=${MYSQL_USER}
PORTAL_DB_PASSWORD=${MYSQL_PASSWORD}

# NGW
NGW_URL=http://<virtual_ip>:8040


Файл environment-override/eltex-ngw.env
# Xост подключения к БД
database.host=<virtual_ip>


Файл /etc/eltex-radius/local.conf
# MySQL database
RADIUS_DB_HOST=<virtual_ip>
#PCRF
RADIUS_PCRF_HOST=<virtual_ip>


Файл data/eltex-wifi-cab/etc/eltex-wifi-cab/system.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <entry key="mongoaddress">mongodb://localhost:27017/wifi-customer-cab</entry>
    <entry key="nbiaddress">http://<virtual-ip>:8080/axis2/services/RadiusNbiService?wsdl</entry>
    <entry key="nbi.serviceLogin.user">softwlc_service</entry>
    <entry key="nbi.serviceLogin.password">softwlc</entry>
    <entry key="nbi.serviceLogin.requestTimeout.sec">120</entry>
 
    <!--Bonnie or NBI-->
    <entry key="data.service.type">NBI</entry>
    <entry key="bonnie.service.host"><virtual-ip></entry>
    <entry key="bonnie.service.port">9070</entry>
 
    <!--Bruce-->
    <entry key="bruce.service.host"><virtual-ip></entry>
    <entry key="bruce.service.port">8008</entry>
 
    <!--Jobs-->
    <entry key="jobs.service.host"><virtual-ip></entry>
    <entry key="jobs.service.port">9696</entry>
 
    <!-- Support link  -->
    <entry key="support.page.enabled">false</entry>
    <entry key="support.page.url">http://eltex-co.ru</entry>
 
    <!-- DPI link  -->
    <entry key="dpi.page.enabled">false</entry>
    <entry key="dpi.page.url">https://filter.wifi.rt.ru/</entry>
 
    <!-- SSO Settings -->
    <entry key="sso.enabled">false</entry>
    <entry key="sso.redirectUri">http://<virtual-ip>:8080/wifi-cab/sso</entry>
    <entry key="sso.clientSecret"></entry>
    <entry key="sso.clientId"></entry>
    <entry key="sso.localauth.enabled">true</entry>
 
    <!-- SSO Auth -->
    <entry key="sso.auth.server.protocol">http</entry>
    <entry key="sso.auth.server.address"></entry>
    <entry key="sso.auth.server.port">80</entry>
 
    <entry key="sso.auth.auth.path">/auth/realms/b2b/protocol/openid-connect/auth</entry>
    <entry key="sso.auth.logout.path">/auth/realms/b2b/protocol/openid-connect/logout</entry>
 
    <!-- SSO REST -->
    <entry key="sso.rest.server.protocol">http</entry>
    <entry key="sso.rest.server.address"></entry>
    <entry key="sso.rest.server.port">80</entry>
    <entry key="sso.rest.server.timeout.sec">10</entry>
    <entry key="sso.rest.protocol.provider">rtk</entry> <!-- rtk/keycloak -->
    <entry key="sso.rest.protocol.version">2.0</entry> <!--setting only matters when provider=rtk-->
    <entry key="sso.rest.username"></entry> <!--setting only matters when provider=rtk-->
    <entry key="sso.rest.password"></entry> <!--setting only matters when provider=rtk-->
 
    <entry key="sso.rest.getToken.path">/apiman-gateway/b2b_test/getToken</entry>
    <entry key="sso.rest.getUserInfo.path">/apiman-gateway/b2b_test/getUserInfo</entry>
 
    <!--the settings only matter when provider=rtk-->
    <entry key="sso.rest.addUser.path">/apiman-gateway/b2b_test/addUser</entry>
    <entry key="sso.rest.updateUser.path">/apiman-gateway/b2b_test/updateUser</entry>
    <entry key="sso.rest.delUser.path">/apiman-gateway/b2b_test/delUser</entry>
    <entry key="sso.rest.addUserParam.path">/apiman-gateway/b2b_test/addUserParam</entry>
    <entry key="sso.rest.delUserParam.path">/apiman-gateway/b2b_test/delUserParam</entry>
    <entry key="sso.rest.getUserByName.path">/apiman-gateway/b2b_test/getUserByName</entry>
    <entry key="sso.rest.resetPassword.path">/apiman-gateway/b2b_test/resetPassword</entry>
    <entry key="sso.rest.getUserByParam.path">/apiman-gateway/b2b_test/getUserByParam</entry>
    <entry key="sso.rest.getUserByEmail.path">/apiman-gateway/b2b_test/getUserByEmail</entry>
 
</properties>

Проверьте и при необходимости измените mongodb://localhost на mongodb://ip_mongo_primary,ip_mongo_secondary в строке 4 и указать replicaSet, который вы настроили в /etc/mongod.conf. Таким образом строка будет выглядить примерно следующим образом

<entry key="mongoaddress">mongodb://<ip_mongo_primary>,<ip_mongo_secondary>:27017/wifi-customer-cab?replicaSet=<Название реплики></entry>


Файл environment-override/eltex-wifi-cab.env
SPRING_FLYWAY_URL=jdbc:mysql://<virtual-ip>/eltex_wifi_customer_cab

SPRING_DATASOURCE_URL=jdbc:mysql://<virtual-ip>/eltex_wifi_customer_cab


Файл environment-override/eltex-ems.env
# DB Event
CONFIG_FORCE_event_jdbc_dbUrl=jdbc:mysql://<virtual-ip>:3306/eltex_alert?useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false

# DB Tree
CONFIG_FORCE_tree_jdbc_dbUrl=jdbc:mysql://<virtual-ip>:3306/eltex_ems?useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&noAccessToProcedureBodies=true&useSSL=false

# DB Ont
CONFIG_FORCE_ont_jdbc_dbUrl=jdbc:mysql://<virtual-ip>:3306/eltex_ont?useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false
 
# DB Syslog
CONFIG_FORCE_syslog_jdbc_dbUrl=jdbc:mysql://<virtual-ip>:3306/Syslog?useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false
 
# DB acsmain (alias=cpe)
CONFIG_FORCE_cpe_jdbc_dbUrl=jdbc:mysql://<virtual-ip>:3306/acsmain?useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false
 
# DB  acscmds(alias=cmds)
CONFIG_FORCE_cmds_jdbc_dbUrl=jdbc:mysql://<virtual-ip>:3306/acscmds?useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false
 
# DB  acsinf(alias=inf)
CONFIG_FORCE_inf_jdbc_dbUrl=jdbc:mysql://<virtual-ip>:3306/acsinf?useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false
 
# DB  acscache(alias=cache)
CONFIG_FORCE_cache_jdbc_dbUrl=jdbc:mysql://<virtual-ip>:3306/acscache?useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false
 
# DB  radius(alias=radius)
CONFIG_FORCE_radius_jdbc_dbUrl=jdbc:mysql://<virtual-ip>:3306/radius?useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false

# DB  wireless (alias=wireless)
CONFIG_FORCE_wireless_jdbc_dbUrl=jdbc:mysql://<virtual-ip>:3306/wireless?useUnicode=true&characterEncoding=utf8&relaxAutoCommit=true&connectTimeout=5000&useSSL=false


Файл environment-override/eltex-bruce.env
# URI для подключения к БД MySQL
SPRING_DATASOURCE_URL=jdbc:mysql://<virtual-ip>/eltex_bruce

# URI для подключения к БД MySQL
SPRING_FLYWAY_URL=jdbc:mysql://<virtual-ip>/eltex_bruce

# URI для подключения к БД MySQL
SPRING_QUARTZ_PROPERTIES_ORG_QUARTZ_DATASOURCE_QUARTZDATASOURCE_URL=jdbc:mysql://<virtual-ip>:3306/eltex_bruce


Файл environment-override/eltex-disconnect-service.env
# Настройки pcrf
pcrf.host=<virtual-ip>


Файл environment-override/eltex-doors.env
# Настройка подключения к БД
database.host=<virtual-ip>


Файл environment-override/eltex-johnny.env
# Хост подключения к сервису eltex-pcrf
pcrf.host=<virtual-ip>


Файл environment-override/eltex-logging-service.env
# URI БД
database.uri=${MONGO_URL}/wifi-customer-cab

# Настройка подключения к БД eltex_wifi_customer_cab
database.jdbcUrl=jdbc:mysql://<virtual-ip>/eltex_wifi_customer_cab


Файл environment-override/eltex-mercury.env
# Хост подключения к БД
database.host=<virtual_ip>


Файл data/eltex-pcrf/etc/eltex-pcrf/hazelcast-local.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~ http://www.apache.org/licenses/LICENSE-2.0
  -->
 
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config http://www.hazelcast.com/schema/config/hazelcast-config-3.6.xsd"
           xmlns="http://www.hazelcast.com/schema/config"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <group>
        <name>dev</name>
    </group>
    <management-center enabled="false">http://<virtual_ip>:8080/mancenter</management-center>
    <network>
        <port auto-increment="false" port-count="100">5701</port>
        <outbound-ports>
            <ports>0</ports>
        </outbound-ports>
        <join>
            <multicast enabled="false"/>
            <tcp-ip enabled="false"/>
            <discovery-strategies>
            </discovery-strategies>
        </join>
        <interfaces enabled="false"/>
        <ssl enabled="false"/>
        <socket-interceptor enabled="false"/>
        <symmetric-encryption enabled="false">
            <algorithm>PBEWithMD5AndDES</algorithm>
            <!-- salt value to use when generating the secret key -->
            <salt>thesalt</salt>
            <!-- pass phrase to use when generating the secret key -->
            <password>thepass</password>
            <!-- iteration count to use when generating the secret key -->
            <iteration-count>19</iteration-count>
        </symmetric-encryption>
    </network>
    <partition-group enabled="false"/>
 
    <map name="__vertx.subs">
        <backup-count>1</backup-count>
        <time-to-live-seconds>0</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>NONE</eviction-policy>
        <max-size policy="PER_NODE">0</max-size>
        <eviction-percentage>25</eviction-percentage>
        <merge-policy>com.hazelcast.map.merge.LatestUpdateMapMergePolicy</merge-policy>
    </map>
 
    <semaphore name="__vertx.*">
        <initial-permits>1</initial-permits>
    </semaphore>
 
    <!--map name="serviceOnlineMap">
        <in-memory-format>OBJECT</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>0</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>NONE</eviction-policy>
        <max-size policy="PER_NODE">0</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>100</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map-->
 
    <map name="sessions">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.user.UserSessionStore</class-name>
            <write-delay-seconds>1</write-delay-seconds>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>0</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">10</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="sourceIpNodeIdMap">
        <map-store enabled="false"></map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>60</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">10</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="subnets">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.hazelcast.mysql.SubnetLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">10</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlSsid">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.wireless.SsidLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlSsidLink">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.wireless.SsidLinkLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlGeoObj">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.geo.GeoObjectLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlCell">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.cell.CellLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlNas">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.hazelcast.mysql.NasLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlTariff">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.hazelcast.mysql.TariffLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="shapers">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.shaper.ShaperLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">10</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="vrf">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.vrf.VrfLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">10</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <serialization>
        <portable-version>0</portable-version>
    </serialization>
 
    <services enable-defaults="true"/>
 
    <lite-member enabled="false"/>
 
    <properties>
        <property name="hazelcast.logging.type">log4j2</property>
        <property name="hazelcast.shutdownhook.enabled">false</property>
        <property name="hazelcast.jmx">true</property>
    </properties>
 
</hazelcast>

Изменить localhost на <virtualip> в 18 строке.

Файл data/eltex-pcrf/etc/eltex-pcrf/hazelcast-cluster.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright (c) 2008-2016, Hazelcast, Inc. All Rights Reserved.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~ http://www.apache.org/licenses/LICENSE-2.0
  -->
 
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.6.xsd"
           xmlns="http://www.hazelcast.com/schema/config"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <management-center enabled="false">http://<virtual_ip>:8080/mancenter</management-center>
 
    <!-- load network configuration from another file -->
    <import resource="file:///etc/eltex-pcrf/hazelcast-cluster-network.xml"/>
 
    <partition-group enabled="false"/>
 
    <map name="__vertx.subs">
        <backup-count>1</backup-count>
        <time-to-live-seconds>0</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>NONE</eviction-policy>
        <max-size policy="PER_NODE">0</max-size>
        <eviction-percentage>25</eviction-percentage>
        <merge-policy>com.hazelcast.map.merge.LatestUpdateMapMergePolicy</merge-policy>
    </map>
 
    <semaphore name="__vertx.*">
        <initial-permits>1</initial-permits>
    </semaphore>
 
    <!--map name="serviceOnlineMap">
        <in-memory-format>OBJECT</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>0</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>NONE</eviction-policy>
        <max-size policy="PER_NODE">0</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>100</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map-->
 
    <map name="sessions">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.user.UserSessionStore</class-name>
            <write-delay-seconds>1</write-delay-seconds>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>0</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">10</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="sourceIpNodeIdMap">
        <map-store enabled="false"></map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>60</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">10</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="subnets">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.hazelcast.mysql.SubnetLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">10</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlSsid">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.wireless.SsidLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlSsidLink">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.wireless.SsidLinkLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlGeoObj">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.geo.GeoObjectLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlCell">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.cell.CellLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlNas">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.hazelcast.mysql.NasLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="mysqlTariff">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.hazelcast.mysql.TariffLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">5</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="shapers">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.shaper.ShaperLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">10</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <map name="vrf">
        <map-store enabled="true">
            <class-name>org.eltex.softwlc.pcrf.hazelcast.vrf.VrfLoader</class-name>
            <properties>
                <property name="configPath">/etc/eltex-pcrf/eltex-pcrf.json</property>
            </properties>
        </map-store>
        <in-memory-format>BINARY</in-memory-format>
        <backup-count>0</backup-count>
        <async-backup-count>0</async-backup-count>
        <time-to-live-seconds>600</time-to-live-seconds>
        <max-idle-seconds>0</max-idle-seconds>
        <eviction-policy>LRU</eviction-policy>
        <max-size policy="FREE_HEAP_PERCENTAGE">10</max-size>
        <eviction-percentage>25</eviction-percentage>
        <min-eviction-check-millis>5000</min-eviction-check-millis>
        <merge-policy>com.hazelcast.map.merge.PutIfAbsentMapMergePolicy</merge-policy>
        <cache-deserialized-values>INDEX-ONLY</cache-deserialized-values>
    </map>
 
    <serialization>
        <portable-version>0</portable-version>
    </serialization>
 
    <services enable-defaults="true"/>
 
    <lite-member enabled="false"/>
 
    <properties>
        <property name="hazelcast.logging.type">log4j2</property>
        <property name="hazelcast.shutdownhook.enabled">false</property>
        <property name="hazelcast.jmx">true</property>
    </properties>
 
</hazelcast>

Изменить localhost на <virtualip> в 15 строке.

Скопируйте лицензии в директорию /usr/lib/eltex-ems/conf/licence/ на обоих серверах. 

Если используются иные лицензионные файлы, также необходимо скопировать их на второй сервер (список всех лицензионных файлов доступен в следующей статье)

Добавление пользователя в таблицу NAS

Для доступа в Личный кабинет необходимо добавить соответствующие записи в таблицу NAS.

Данная таблица находится в БД eltex_auth_service и содержит адреса клиентов, имеющих право отправлять запросы на проведение авторизации пользователей. Если клиент не включен в эту таблицу, то запросы авторизации будут игнорироваться.

Для этого в личном кабинете в разделе НастройкиСерверные адреса добавить : 

  • <ip_server_1> - IP-адрес сервера-1
  • <ip_server_2> - IP-адрес сервера-2
  • <virtual_ip> - Виртуальный IP-адрес









Ключ RADIUS -eltex


Смена настроек в GUI

Также нужно настроить модули SoftWLC при помощи графического интерфейса.

Личный кабинет Wi-Fi

В разделе Настройки → Интеграция в параметрах PCRF URL, URL NGW-клиента и URL конструктора порталов изменить localhost на виртуальный ip-адрес:

Конструктор порталов

Изменить localhost на виртуальный ip-адрес в разделах настроек:

Системные настройки → Конструктор порталов

Системные настройки → Доступ к NBI

Системные настройки → Доступ к NGW

Системные настройки → Доступ к PCRF

Системные настройки → Доступ к Mercury

EMS-GUI

В графическом интерфейсе сервера EMS изменить localhost (либо 127.0.0.1) на виртуальный ip-адрес в следующих разделах:

Администрирование → Настройка сервера → Системные модули → pcrf

Администрирование → Настройка сервера → Системные модули → radius

Также, необходимо отключить перезапуск RADIUS

Администрирование → Настройка сервера → Системные модули → softwlc.nbi

Администрирование → Настройка сервера → Системные модули → system

Администрирование → Настройка сервера → Системные модули → tftpserver

Администрирование → Настройка сервера → Системные модули →wifelessCommon

Данный ключ должен совпадать с файлом /etc/eltex-wifi-cab/local_secret на каждом хосте, где установлен eltex-wifi-cab . 

Если вы используете модуль netconf, то там так же необходимо актуализировать информацию (mongodb://<IP_node1>:27017,<IP_node2>:27017/netconf?replicaSet=<YourClusterName>)

Администрирование → Настройка сервера → Системные модули → netconf 


  • Нет меток