Содержание
Актуальная схема
Описание
Архитектура рассчитана на использование одного сервера как основной и второго сервера как запасной с постоянной репликацией. В случае отказа работы основного возможность ручного переключения на запасного с помощью скрипта и изменении ip адреса указывающего на основную ноду.
В архитектуре используются следующие компоненты и входят в состав стандартной установки Корпоративного сервера 2024:
- PostgreSQL 12.22
- RabbitMQ-Server 3.13.7
- Redis Server 7.2.7
- GlusterFS 11.1
Проверка осуществлялась на версии 2.0.2024.14752 Корпоративного сервера и сервера документов 2025.2.1.801.
Условия эксплуатации
1) При использовании одной доменной А записи с несколькими IP-адресами (с возможностью включения и выключения IP) или изменение доменной записи для Корпоративного сервера вида *.domain.ru
, например:
*.test2.s7-office.site.
И отдельными записями для двух почтовых серверов (*опционально).
2) В случае если почтовый сервер не нужен, то возможна установка без почтового сервера. Предварительно ознакомьтесь с инструкцией чтобы исключить почтовый сервер из установки.
Команды связанные с почтовым сервером отмечены в статье.
3) При ошибках работы приложений на сервере master потребуется переключение сервера slave в режим master с помощью скрипта.
Технические требования
- 2 Виртуальные машины;
- Для хранения данных GlusterFS;
- ТХ Машин, для тестирования, возможно использовать:
от 4 CPU;
от 8Гб RAM;
от 50Гб свободного пространства на диске; - Более конкретные данные рассчитываются по обращению в ТП;
- Отключение или перевод SELinux в режим permissive для корректной работы сервисов.
1. Установка и настройка сервиса хранения GlusterFS
Описание
Файловое хранилище:
- Для почтового сервера будет использоваться каталог
/mail
- Корпоративный Сервер
/var/r7-office/filestorage
/var/r7-office/searchindex
- Сервер документов
/var/www/r7-office/Data /var/lib/r7-office/documentserver/App_Data/cache
Нет необходимости синхронизировать временных каталогов:
filestorage_temp filestorage_temp_proc
База данных (БД):
Используется PostgreSQL версии 12 в режиме master-slave.
1.1. Установка и настройка glusterfs
Добавьте запись в /etc/hosts
:
192.168.27.186 gluster1
192.168.26.253 gluster2
Рекомендуется использовать запись 127.0.0.1 localhost
как стандартную и без использования имени сервера, так как в дальнейшем будут добавлены другие записи для работы почтового сервера.
Укажите соответствующее имя (поправить на свой домен и IP-адрес сервера), вместо mx1
можно использовать любое необходимое имя (например, mail
):
Создание томов выполняется на сервере №1.
hostnamectl set-hostname mx1.your-domain.ru
Hostname сервера не совпадает с его доменом.
Например, server.example.com
— полное имя домена, а server — его hostname
.
Данная запись необходима для почтового сервера.
Без использования почтового сервера возможно задать любое имя сервера
Укажите соответствующее имя на сервере №2 для почтового сервера (поправить на свой домен):
Создание томов выполняется на сервере №2.
hostnamectl set-hostname mx2.your-domain.ru
Для применения параметров выполните перезапуск серверов.
Без использования почтового сервера возможно задать любое имя сервера.
1.2. На всех нодах установить, запустить и добавить в автозагрузку
dnf install -y glusterfs-server
systemctl start glusterd.service
systemctl enable glusterd.service
Не имеет значения, какой из узлов вы будете использовать, но в следующем примере команда запускается на gluster1
:
gluster peer probe gluster2
Фактически эта команда сообщает gluster1
доверять gluster2
и регистрирует его как часть пула хранения данных.
Если зондирование пройдет успешно, вы получите следующий вывод:
peer probe: success
Вы можете проверить связь узлов в любое время путем запуска команды:
gluster peer status
Если вы запустите эту команду из gluster2
, вы увидите следующий вывод:
Number of Peers: 1 Hostname: gluster1 Uuid: 7ecfa2d1-3394-4f15-a1f5-bba484f2bbef State: Peer in Cluster (Connected)
Рекомендуется на время установки/настройки отключить firewalld.
На этом этапе два ваших сервера взаимодействуют и готовы к созданию томов хранения друг с другом.
Создание томов выполняется на сервере №1.
Для создания тома вы будете использовать команду gluster volume create
с таким общим синтаксисом:
sudo gluster volume create mail_volume replica 2 gluster{1,2}:/mail_volume force sudo gluster volume create cddisk-filestorage replica 2 gluster{1,2}:/cddisk-filestorage force sudo gluster volume create cddisk-searchindex replica 2 gluster{1,2}:/cddisk-searchindex force sudo gluster volume create ds-data replica 2 gluster{1,2}:/ds-data force sudo gluster volume create ds-cache replica 2 gluster{1,2}:/ds-cache force
Если том был создан успешно, вы увидите следующий вывод:
volume create: mail_volume: success: please start the volume to access data
На этом этапе ваш том создан, но еще не активирован.
Вы можете запустить том и сделать его доступным для использования путем выполнения следующей команды с любого сервера Gluster (для почтового сервера):
sudo gluster volume start mail_volume sudo gluster volume start cddisk-filestorage sudo gluster volume start cddisk-searchindex sudo gluster volume start ds-data sudo gluster volume start ds-cache
Вы получите следующий вывод, если том запущен корректно:
volume start: mail_volume: success volume start: cddisk-filestorage: success volume start: cddisk-searchindex: success volume start: ds-data: success volume start: ds-cache: success
Затем проверьте, находится ли том в сети. Запустите следующую команду с любого из ваших узлов:
sudo gluster volume status
В результате вы увидите вывод, аналогичный данному:
Status of volume: mail Gluster process TCP Port RDMA Port Online Pid ------------------------------------------------------------------------------ Brick gluster1:/mail 49152 0 Y 4495 Brick gluster2:/mail 49152 0 Y 20192 Self-heal Daemon on localhost N/A N/A Y 4518 Self-heal Daemon on gluster2 N/A N/A Y 20215 Task Status of Volume mail_volume ------------------------------------------------------------------------------ There are no active volume tasks
Создайте каталог и смонтируйте:
Следующие инструкции выполняются на всех серверах (для почтового сервера).
mkdir /mail mkdir -p /var/r7-office/filestorage mkdir -p /var/r7-office/searchindex mkdir -p /var/www/r7-office/Data mkdir -p /var/lib/r7-office/documentserver/App_Data/cache mount.glusterfs localhost:/mail_volume /mail mount.glusterfs localhost:/cddisk-filestorage /var/r7-office/filestorage mount.glusterfs localhost:/cddisk-searchindex /var/r7-office/searchindex mount.glusterfs localhost:/ds-data /var/www/r7-office/Data mount.glusterfs localhost:/ds-cache /var/lib/r7-office/documentserver/App_Data/cache
Добавьте в автозагрузку (для почтового сервера):
{ echo 'localhost:/mail_volume /mail glusterfs defaults,_netdev,backupvolfile-server=localhost 0 0' echo 'localhost:/cddisk-filestorage /var/r7-office/filestorage glusterfs defaults,_netdev,backupvolfile-server=localhost 0 0' echo 'localhost:/cddisk-searchindex /var/r7-office/searchindex glusterfs defaults,_netdev,backupvolfile-server=localhost 0 0' echo 'localhost:/ds-data /var/www/r7-office/Data glusterfs defaults,_netdev,backupvolfile-server=localhost 0 0' echo 'localhost:/ds-cache /var/lib/r7-office/documentserver/App_Data/cache glusterfs defaults,_netdev,backupvolfile-server=localhost 0 0' } | sudo tee -a /etc/fstab
Добавьте задание для перезапуска GlusterFS, в случае перезагрузки или выключения питания:
Следующие инструкции выполняются на всех серверах.
После перезагрузки сервера, могут наблюдаться проблемы с синхронизацией GlusterFS. Поэтому данный метод решает эту проблему.
echo "@reboot sleep 30 && systemctl restart glusterd.service" | crontab -
Проверка монтирования:
df -h mount -a
Проверьте корректность синхронизации каталогов между серверами, создавая тестовые файлы или каталоги в монтированных каталогах.
При настройке разрешенных портов рекомендуется проверить все задействованные порты на двух серверах:
ss -tulnp | grep gluster
2. Подготовка к установке почтового сервера (*опционально)
2.1. Записи в DNS и необходимые конфигурации
Для почтового сервера необходимо сделать A и MX записи в виде:
# MX-записи
mx1 — 192.168.27.186 mx2 — 192.168.26.253
# А-записи
smtp — 192.168.27.186, 192.168.26.253 imap — 192.168.27.186, 192.168.26.253
Примеры А-записей:
А также TXT-запись v=spf1 +mx ~all
.
TXT-запись v=spf1 +a +mx -all
— говорит о том, что отправлять письма от имени домена your-domain.ru
могут сервера, указанные в A и MX-записях этого домена, а письма, отправленные от других серверов должны быть удалены (Fail).
Важно понимать: SPF-запись не наследуется на поддомены.
2.2. Скопируйте репозиторий для возможности быстрого доступа к копированию и просмотру конфигурационных файлов
Следующие инструкции выполняются на всех серверах.
Скачайте архив:
wget https://download.r7-office.ru/mailserver/mailserver-rpm-config.tar.gz
И распакуйте его, чтобы каталог config
и остальные файлы была после данной директории /mnt/mailserver/
, чтобы было быстрее выполнять команды.
Например так:
tar -xzf mailserver-rpm-config.tar.gz -C /mnt mv /mnt/mailserver-redos73-config /mnt/mailserver
Так как, далее примеры команд указаны с данным путём.
2.3 Установка для почтового сервера dovecot, postfix
dnf install postgresql-server postfix postfix-pgsql dovecot dovecot-pgsql dovecot-pigeonhole ca-certificates acl rsyslog
3. Установка и настройка БД
Установите следующие пакеты на оба сервера:
dnf install postgresql-server-12 postgresql-12
3.1. БД
Следующие инструкции выполняются на всех серверах.
Создайте первичный кластер базы данных:
sudo postgresql-setup --initdb sudo systemctl enable --now postgresql
Отредактируйте /var/lib/pgsql/data/postgresql.conf
:
listen_addresses = 'localhost,ip_srv1,ip_srv2' # Слушать на адресах port = 5432 # Задать порт БД wal_level = replica # Включить репликацию archive_mode = on # Включить архивирование WAL archive_command = 'cp %p /var/lib/pgsql/archive/%f' # Команда для архивирования WAL max_wal_senders = 5 # Максимальное количество одновременных подключений репликации wal_keep_segments = 50 # Количество WAL-сегментов для хранения hot_standby = on # Разрешить подключения в режиме hot standby
Где, ip_srv1
, ip_srv2
— адреса внутренней сети первого и второго почтового сервера.
Следующие инструкции выполняются на всех серверах.
В файле postgresql.conf
разрешите логическую репликацию, добавляем строку для прослушивания локального интерфейса:
/var/lib/pgsql/data/pg_hba.conf
Привести к виду:
# Разрешить локальные подключения для всех пользователей # "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust host all all ip_srv1/32 trust host all all ip_srv2/32 trust
Вместо ip_srv1/32
и ip_srv2/32
укажите IP-адрес двух серверов. Режим trust
необходим для установки Корпоративного сервера.
Для возможности репликации БД добавьте строки в конце:
# Разрешить репликацию с обоих серверов для пользователя replication_user host replication replication_user ip_srv1/32 md5 host replication replication_user ip_srv2/32 md5
Где, ip_another_srv/32
— адрес первого или второго почтового сервера, в зависимости от сервера где производится настройка.
Выполните перезапуск сервиса БД:
sudo systemctl restart postgresql
Следующие инструкции выполняются на сервере №1.
После базовой настройки базы данных, создаем необходимую структуру в БД, создаем пользователей и настраиваем репликацию:
sudo -u postgres psql
В консоли psql выполните следующие команды, подтверждая каждую нажатием Enter
:
Вместо паролей password
и replication_password
, cddisk
и ds
задайте свои пароли.
В поле insert into
вместо YOUR_DOMAIN
укажите реальный адрес вашего домена.
Не рекомендуется использовать другие имена для баз данных cddisk
и ds
.
CREATE USER cddisk WITH password 'cddisk'; CREATE USER ds WITH password 'ds'; CREATE DATABASE cddisk OWNER cddisk; CREATE DATABASE ds OWNER ds; GRANT ALL privileges ON DATABASE cddisk TO cddisk; GRANT ALL privileges ON DATABASE ds TO ds; CREATE USER replication_user WITH REPLICATION LOGIN PASSWORD 'replication_password'; GRANT CONNECT ON DATABASE cddisk TO replication_user; GRANT CONNECT ON DATABASE ds TO replication_user; \c cddisk GRANT USAGE ON SCHEMA public TO replication_user; GRANT SELECT ON ALL TABLES IN SCHEMA public TO replication_user; GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO replication_user; \c ds GRANT USAGE ON SCHEMA public TO replication_user; GRANT SELECT ON ALL TABLES IN SCHEMA public TO replication_user; GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO replication_user; # Для выхода из БД: \q
Для почтового сервера:
CREATE DATABASE postfix ENCODING 'UTF-8';
CREATE USER postfix WITH PASSWORD 'password';
GRANT ALL PRIVILEGES ON DATABASE postfix TO postfix;
GRANT CONNECT ON DATABASE postfix TO replication_user;
\c postfix;
CREATE TABLE virtual_domains (
id serial PRIMARY KEY,
name varchar(50) NOT NULL
);
CREATE TABLE virtual_users (
id serial PRIMARY KEY,
domain_id int NOT NULL,
password varchar(106) NOT NULL,
email varchar(120) NOT NULL,
quota bigint DEFAULT NULL,
UNIQUE (email),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
);
CREATE TABLE virtual_aliases (
id serial PRIMARY KEY,
domain_id int NOT NULL,
source varchar(100) NOT NULL,
destination varchar(100) NOT NULL,
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
);
GRANT ALL PRIVILEGES ON TABLE virtual_domains TO postfix;
GRANT ALL PRIVILEGES ON TABLE virtual_users TO postfix;
GRANT ALL PRIVILEGES ON TABLE virtual_aliases TO postfix;
GRANT ALL PRIVILEGES ON SEQUENCE virtual_domains_id_seq TO postfix;
GRANT ALL PRIVILEGES ON SEQUENCE virtual_users_id_seq TO postfix;
GRANT ALL PRIVILEGES ON SEQUENCE virtual_aliases_id_seq TO postfix;
GRANT USAGE ON SCHEMA public TO replication_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO replication_user;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO replication_user;
INSERT INTO virtual_domains (name) VALUES ('YOUR_DOMAIN');
# Для выхода из БД:
\q
Следующие инструкции выполняются на сервере №1.
Создайте директорию для архива:
sudo mkdir /var/lib/pgsql/archive sudo chown -R postgres: /var/lib/pgsql/archive sudo chmod -R 750 /var/lib/pgsql/archive
Следующие инструкции выполняются на сервере №1.
Перезагрузите службу PostgreSQL для применения изменений:
systemctl restart postgresql
3.2. Настройка репликации БД
Следующие инструкции выполняются на сервере №2.
Удалите существующую директорию данных:
rm -rf /var/lib/pgsql/data
Создайте базовую резервную копию с мастера:
su — postgres -c "pg_basebackup --host=ip_srv1 --username=replication_user --pgdata=/var/lib/pgsql/data --wal-method=stream --write-recovery-conf"
Где, ip_srv1
— адрес внутренней сети первого сервера, с master БД.
Перезапустите сервис и проверьте его статус:
systemctl restart postgresql.service systemctl status postgresql.service
4. Настройка почтового сервера (*опционально)
4.1. Конфигурация Postfix.
Следующие инструкции выполняются на всех серверах.
Для настройки Postfix, внесите изменения (сменив домен на свой), скопируйте файл /etc/postfix/main.cf
:
Все конфигурационные файлы задействованные при установки находятся в mailserver / config gitlab
.
yes | cp /mnt/mailserver/config/main_pgsql.cf /etc/postfix/main.cf
Необходимо поправить параметры в файле /etc/postfix/main.cf
, в строках:
myhostname = mx1.domain.ru mydomain = domain.ru
Где:
mx1.domain.ru
— А запись почтового сервера в DNS;domain.ru
— ваш домен.
Скопируйте файл конфигурации /etc/postfix/master.cf
:
yes | cp /mnt/mailserver/config/master.cf /etc/postfix
Скопируйте и отредактируйте конфигурационные файлы, при помощи которых Postfix сможет обращаться к базе данных PostgreSQL:
Если пользователь с правами в БД был добавлен иной, не postfix, учитывайте это и измените пароль после копирования этих файлов, необходимо отредактировать параметр password
, который в п.2.12 указали отличный от password
.
mkdir -p /etc/postfix/pgsql cp -a /mnt/mailserver/config/pgsql/. /etc/postfix/pgsql/ find /etc/postfix/pgsql -type d -exec chmod 750 {} \; find /etc/postfix/pgsql -type f -exec chmod 640 {} \; sudo vi /etc/postfix/pgsql/virtual_alias_maps.cf sudo vi /etc/postfix/pgsql/virtual_mailbox_domains.cf sudo vi /etc/postfix/pgsql/virtual_mailbox_maps.cf
Необходимо положить или сгенерировать сертификаты домена.
Вам необходимо положить сертификаты по пути /etc/ssl/
.
Где:
mail_cert.pem
— ключ с полной цепочкой сертификатов;mail_key.pem
— закрытый ключ.
Скопируйте файл tls_policy_maps
, с помощью которого можно вручную задавать версию tls протокола для общения серверов, либо полностью отключать его. Это иногда бывает нужно, если подключаешься к очень старому серверу, который не поддерживает современные протоколы. Приходится использовать нешифрованное подключение:
cp /mnt/mailserver/config/tls_policy_maps /etc/postfix/ postmap /etc/postfix/tls_policy_maps
Настройте работу SMTP-сервера для работы и поменяйте права на файлы. Создайте папку etc
для Postfix и скопируйте файлы:
mkdir /var/spool/postfix/etc cp /etc/host.conf /var/spool/postfix/etc/ cp /etc/resolv.conf /var/spool/postfix/etc/ cp /etc/services /var/spool/postfix/etc/
Измените права в файлах /etc/resolv.conf и /var/pool/postfix/etc/
на 1777
:
chmod 1777 /etc/resolv.conf chmod 1777 -R /var/spool/postfix/etc systemctl restart postfix.service
4.2. Интеграция служб Dovecot
Следующие инструкции выполняются на всех серверах.
Создайте специализированную группу и пользователя для работы с Dovecot с указанными в конфиге uid 1100
:
Если у вас уже занят этот uid, то везде замените его на другой или удалите пользователя с uid 1100
, если он вам не нужен.
groupadd -g 1100 vmail sudo useradd -d /mail -g 1100 -u 1100 vmail usermod -a -G dovecot vmail chown vmail:vmail /mail
Скопируйте и отредактируйте конфигурационный файл /etc/dovecot/dovecot.conf
, в который впишете настройки сервиса (меняем домен в строке auth_default_realm =
):
Обратите внимание, что сертификат из переменных ssl_key и ssl_cert будет использоваться тот же самый, который был сгенерирован для Postfix.
yes | cp /mnt/mailserver/config/dovecot_pgsql.conf /etc/dovecot/dovecot.conf sudo vi /etc/dovecot/dovecot.conf
Замените параметр в строке:
auth_default_realm = domain.ru
Скопируйте и отредактируйте конфигурацию для подключения к базе данных PostgreSQL:
cp /mnt/mailserver/config/dovecot-pgsql.conf /etc/dovecot/ && chmod 640 /etc/dovecot/dovecot-pgsql.conf sudo vi /etc/dovecot/dovecot-pgsql.conf
Замените параметр в строке:
password=<пароль из п.3.1>
Так же потребуется скопировать и отредактировать параметр:
cp /mnt/mailserver/config/dovecot-dict-sql.conf.ext /etc/dovecot/ && chmod 640 /etc/dovecot/dovecot-dict-sql.conf.ext sudo vi /etc/dovecot/dovecot-dict-sql.conf.ext
Замените параметр в строке:
password=<пароль из п.3.1>
Создайте директорию и файлы для логов:
mkdir /var/log/dovecot touch /var/log/dovecot/{main.log,info.log,debug.log,lda-errors.log,lda-deliver.log,lmtp.log} chown -R vmail:dovecot /var/log/dovecot
Создайте служебную папку для плагина acl:
mkdir /mail/shared-folders chown -R vmail:vmail /mail
На этом основная настройка почтового сервера на базе Postfix и Dovecot завершена.
Можно запускать службы и проверять работу системы:
sudo postfix check systemctl reload postfix systemctl start dovecot systemctl enable postfix systemctl enable dovecot
4.3. Создание почтовых ящиков
Следующие инструкции выполняются на сервере с master БД.
Создайте файл паролей для PostgreSQL и поменяйте права на него:
awk -F '[= ]+' 'BEGIN {OFS=":"} /^connect/ {print "127.0.0.1", "5432", $5, $7, $9}' /etc/dovecot/dovecot-pgsql.conf >> ~/.pgpass chmod 600 .pgpass
Скачайте каталог скриптов:
wget https://download.r7-office.ru/mailserver/operations_mailserver_db-pgsql.tar.gz
Распакуйте архив, например так:
tar -xzf operations_mailserver_db-pgsql.tar.gz
Команда указанная ниже, как пример, создания пользователя:
bash operations_mailserver_db-pgsql-mailserver/mailserver/create_user.sh user@your-domain.ru password
Запустите скрипт на создание почтового ящика:
bash /script/mailserver/create_user.sh user@your-domain.ru password
Где, вместо user@your-domain.ru
указываете необходимое наименование для почтового ящика, а также вместо password
указываете пароль для него.
Разрешается использовать только те спецсимволы при установке пароля, что указаны ниже:
~ @ # % ^ * _ + = - ? : { } [ ] \ /
5. Установка Корпоративного сервера
Выполнение установки производится по инструкции: Установка Корпоративного сервера 2024 на РЕД ОС.
Следующие инструкции выполняются на сервере №1.
5.1. Предварительная подготовка
Скачайте дистрибутив и рекомендуем, для корректной установки, архив разместите в директории, отличной от /root
, например в /mnt
или /tmp
.
Перейдите в каталог:
cd /mnt
Распакуйте архив:
unzip RedOS_*.zip
Для корректной работы Корпоративного сервера обязательно требуется настройка HTTPS. Перед установкой скопируйте crt
и key
файлы в папку sslcert
.
Предоставьте права на скрипт установки:
chmod +x online_installer.sh
Создайте DNS запись для Корпоративного сервера, например:
5.2 Запуск установки первого сервера
Выполните команду:
sudo bash ./online_installer.sh
Выберите «Нет»:
Выберите «Нет»:
Выберите «Да»:
Задайте secret. Необходимо ввести секрет (Набор цифр, букв и спецсимволов. Длина от 8 символов) для защищённого доступа Р7-Диска и Сервера Документов:
Укажите пароль к БД ds, ранее созданного в пункте 3.1 (из примера: ds
):
Выберите «Да»:
Выберите «postgresql»:
Выберите «Нет»:
Укажите БД master и IP-адрес текущего первого сервера:
Укажите по умолчанию порт 5432
:
Укажите БД cddisk из пункта 3.1 (из примера: cddisk
):
Укажите пароль к БД cddisk из пункта 3.1 (из примера: cddisk
):
Измените на актуальный, если есть Р7-Офис Корпоративный сервер 2019 и нажмите «ОК»:
Выберите «Да»:
Необходимо указать домен, в котором у вас созданы записи из пункта подготовки:
Далее укажите необходимые префиксы для всех модулей.
Выберите «Нет»:
Перезапустите сервер.
5.3. Установка второго сервера
Следующие инструкции выполняются на сервере №2.
Скачайте дистрибутив и рекомендуем, для корректной установки, архив разместите в директории, отличной от /root
, например в /mnt
или /tmp
:
Перейдите в каталог :
cd /mnt
Распакуйте архив:
unzip RedOS_*.zip
Для корректной работы Корпоративного сервера обязательно требуется настройка HTTPS. Перед установкой скопируйте crt
и key
файлы в папку sslcert
.
Предоставьте права на скрипт установки:
chmod +x online_installer.sh
5.4. Запуск установки
Выполните команду:
sudo bash ./online_installer.sh
Выберите «Нет»:
Выберите «Нет»:
Выберите «Да»:
Укажите такой же secret
как для первого сервера:
Укажите пароль к БД ds из пункта 2.2.1 (из примера: ds
):
Выберите «Да»:
Выберите «postgresql»:
Выберите «Нет»:
Укажите IP-адрес первого сервера master:
Укажите порт 5432
:
Укажите БД cddisk из пункта 3.1 (из примера: cddisk
):
Укажите пароль к БД cddisk из пункта 3.1 (из примера: cddisk
):
Измените на актуальный, если есть Р7-Офис Корпоративный сервер 2019 и нажмите «ОК»:
Выберите «Да»:
Необходимо указать домен, в котором у вас созданы записи из пункта подготовки:
Далее укажите необходимые префиксы для всех модулей.
Выберите «Нет»:
Перезапустите сервер.
6. Выполните дополнительную настройку Nginx и Сервер документов
Выведите значение параметра secure_link_secret
на первом сервере:
grep -rn "set \$secure_link_secret" /etc/r7-office/documentserver/nginx/ds.conf
Пример вывода:
13: set $secure_link_secret kCj7RMAAYCNtOh6KiGin;
Для второго сервера:
sudo sed -i "s/set \$secure_link_secret [^;]*/set \$secure_link_secret НОВОЕ_ЗНАЧЕНИЕ/" $(grep -rl "set \$secure_link_secret" /etc/r7-office/documentserver/) sudo sed -i "s/set \$secretString [^;]*/set \$secretString НОВОЕ_ЗНАЧЕНИЕ/" $(grep -rl "set \$secretString" /etc/r7-office/documentserver/)
Где замените НОВОЕ_ЗНАЧЕНИЕ
на необходимый параметр c вывода предыдущей команды.
Пример: kCj7RMAAYCNtOh6KiGin
.
Выполните команды по перезапуску Nginx и Сервера документов:
systemctl restart nginx ds-converter.service ds-docservice.service ds-metrics.service
7. Настройка подключения почтового сервера (*опционально)
Перейдите в https://admin.test2.s7-office.site/ Организации — Выберите организацию, в которую добавлены пользователи — Почтовые серверы:
Укажите ранее добавленные данные по почтовому серверу:
В таком случае управлять почтовыми ящиками можно через консоль сервера.
Интеграция с почтовым сервером не поддерживается из-за наличия конфликтов двух одинаковых записей доменов.
8. Управление переключением БД при неработоспособности первого сервера
8.1. Создайте скрипт управления
Укажите необходимые константы в начале скрипта. Потребуется указать необходимые параметры, что является master (первый сервер) и slave (второй сервер).
Параметры указанные ранее в пункте 3.1:
Константы для подключения к БД:
MASTER_IP="192.168.27.186"
— укажите адрес master БД;SLAVE_IP="192.168.26.253"
— укажите адрес replica БД;REPLICATION_USER="replication_user"
— укажите пользователя для репликации;REPLICATION_PASS="replication_password"
— пароль от пользователя для репликации;LOG_FILE="/var/log/switch_postgres.log"
— расположение файла логирования скрипта.
Константы для cddisk (appsettings.json):
CDDISK_DB_NAME="cddisk"
— не рекомендуется изменять;CDDISK_DB_USER="cddisk"
— укажите пользователя КС;CDDISK_DB_PASS="cddisk"
— укажите пароль для пользователя КС;CDDISK_DB_PORT="5432"
— укажите порт БД.
Константы для documentserver (local.json):
DS_DB_NAME="ds"
— не рекомендуется изменять;DS_DB_USER="ds"
— укажите пользователя ДС;DS_DB_PASS="ds"
— укажите пароль для пользователя ДС;DS_DB_PORT="5432"
— укажите порт БД.
#!/bin/bash # === Константы для подключения к БД === MASTER_IP="192.168.27.186" SLAVE_IP="192.168.26.253" REPLICATION_USER="replication_user" REPLICATION_PASS="replication_password" LOG_FILE="/var/log/switch_postgres.log" # === Константы для cddisk (appsettings.json) === CDDISK_DB_NAME="cddisk" CDDISK_DB_USER="cddisk" CDDISK_DB_PASS="cddisk" CDDISK_DB_PORT="5432" # === Константы для documentserver (local.json) === DS_DB_NAME="ds" DS_DB_USER="ds" DS_DB_PASS="ds" DS_DB_PORT="5432" function log() { echo "$(date '+%Y-%m-%d %H:%M:%S') — $1" | tee -a "$LOG_FILE" } function check_superuser() { if [[ $EUID -ne 0 ]]; then log "Ошибка: Скрипт должен запускаться от root." exit 1 fi } function get_local_ip() { hostname -I | awk '{print $1}' } function is_master() { [[ "$(get_postgres_role)" == "master" ]] } function is_slave() { [[ "$(get_postgres_role)" == "slave" ]] } function backup_file_if_needed() { local file="$1" local bak_file="${file}.bak" if [[ ! -f "$bak_file" ]]; then cp "$file" "$bak_file" log "Создана резервная копия: $bak_file" fi } function restore_from_backup() { local file="$1" local bak_file="${file}.bak" if [[ -f "$bak_file" ]]; then log "Восстановление файла $file из резервной копии..." cp "$bak_file" "$file" else log "⚠️ Резервная копия для $file не найдена. Пропущено." fi } function restore_all_configs() { log "Начало восстановления конфигураций из резервных копий..." local files=( "/opt/r7-office/Api/appsettings.json" "/opt/r7-office/Sso.Api/appsettings.json" "/opt/r7-office/Processing/appsettings.json" "/etc/r7-office/documentserver/local.json" ) for file in "${files[@]}"; do restore_from_backup "$file" done log "✅ Восстановление завершено." } function extract_cddisk_db_credentials() { local file="/opt/r7-office/Api/appsettings.json" if [[ ! -f "$file" ]]; then log "Файл $file не найден." return 1 fi # Извлекаем строку подключения local line line=$(grep -A2 '"R7StorageServerUserActions"' "$file" | tr -d ' ') if [[ -z "$line" ]]; then log "Строка R7StorageServerUserActions не найдена в $file" return 1 fi local conn_str conn_str=$(echo "$line" | sed -E 's/.*"R7StorageServerUserActions"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/') if [[ -z "$conn_str" ]]; then log "Не удалось извлечь строку подключения из $file" return 1 fi DB_NAME=$(echo "$conn_str" | grep -oP 'Database=\K[^;]+') DB_USER=$(echo "$conn_str" | grep -oP 'Username=\K[^;]+') DB_PASS=$(echo "$conn_str" | grep -oP 'Password=\K[^;]+') DB_HOST=$(echo "$conn_str" | grep -oP 'Host=\K[^;]+') DB_PORT=$(echo "$conn_str" | grep -oP 'Port=\K[^;]*') DB_PORT="${DB_PORT:-5432}" if [[ -z "$DB_NAME" || -z "$DB_HOST" ]]; then log "В строке подключения отсутствуют необходимые параметры (Database и Host)." return 1 fi export DB_NAME DB_USER DB_PASS DB_HOST DB_PORT } function extract_documentserver_db_credentials() { local config="/etc/r7-office/documentserver/local.json" if [[ ! -f "$config" ]]; then log "⚠️ Файл $config не найден." return 1 fi DS_DB_HOST=$(grep '"dbHost"' "$config" | awk -F '"' '{print $4}') DS_DB_NAME=$(grep '"dbName"' "$config" | awk -F '"' '{print $4}') DS_DB_USER=$(grep '"dbUser"' "$config" | awk -F '"' '{print $4}') DS_DB_PASS=$(grep '"dbPass"' "$config" | awk -F '"' '{print $4}') DS_DB_PORT=$(grep '"dbPort"' "$config" | awk -F '"' '{print $4}') DS_DB_PORT="${DS_DB_PORT:-5432}" if [[ -z "$DS_DB_HOST" || -z "$DS_DB_USER" || -z "$DS_DB_PASS" ]]; then log "⚠️ В файле local.json отсутствуют данные для подключения к БД." return 1 fi export DS_DB_HOST DS_DB_NAME DS_DB_USER DS_DB_PASS DS_DB_PORT } function check_db_connection_after_change() { local new_master="$1" log "Проверка подключения к БД с новыми параметрами..." # === cddisk: используем константы с обновлённым Host === local db_name="$CDDISK_DB_NAME" local db_user="$CDDISK_DB_USER" local db_pass="$CDDISK_DB_PASS" local db_host="$new_master" local db_port="${CDDISK_DB_PORT:-5432}" log "Попытка подключения (cddisk): Host=$db_host, User=$db_user, Database=$db_name, Port=$db_port" echo "$db_pass" | PGPASSWORD="$db_pass" psql -h "$db_host" -U "$db_user" -p "$db_port" -d "$db_name" -c "\q" > /dev/null 2>&1 if [ $? -eq 0 ]; then log "✅ Успешное подключение к cddisk" else log "❌ Не удалось подключиться к cddisk" return 1 fi # === documentserver: используем DS_* константы с обновлённым Host === local ds_name="$DS_DB_NAME" local ds_user="$DS_DB_USER" local ds_pass="$DS_DB_PASS" local ds_host="$new_master" local ds_port="${DS_DB_PORT:-5432}" log "Попытка подключения (documentserver): Host=$ds_host, User=$ds_user, Database=$ds_name, Port=$ds_port" echo "$ds_pass" | PGPASSWORD="$ds_pass" psql -h "$ds_host" -U "$ds_user" -p "$ds_port" -d "$ds_name" -c "\q" > /dev/null 2>&1 if [ $? -eq 0 ]; then log "✅ Успешное подключение к documentserver" else log "❌ Не удалось подключиться к documentserver" return 1 fi return 0 } function check_db_connection() { log "Проверка подключения к БД с текущими параметрами..." # === cddisk === if extract_cddisk_db_credentials; then local db_host="$DB_HOST" local db_name="$DB_NAME" local db_user="$DB_USER" local db_pass="$DB_PASS" local db_port="${DB_PORT:-5432}" log "Попытка подключения (cddisk): Host=$db_host, User=$db_user, Database=$db_name, Port=$db_port" echo "$db_pass" | PGPASSWORD="$db_pass" psql -h "$db_host" -U "$db_user" -p "$db_port" -d "$db_name" -c "SELECT version();" > /dev/null 2>&1 if [ $? -eq 0 ]; then log "Успешное подключение к БД от пользователя $db_user" else log "Не удалось подключиться к БД от пользователя $db_user. Проверьте настройки доступа или пароль." fi else log "⚠️ Пропущена проверка cddisk: не удалось получить данные из appsettings.json" fi # === documentserver === if extract_documentserver_db_credentials; then local ds_host="$DS_DB_HOST" local ds_name="$DS_DB_NAME" local ds_user="$DS_DB_USER" local ds_pass="$DS_DB_PASS" local ds_port="$DS_DB_PORT" log "Попытка подключения (documentserver): Host=$ds_host, User=$ds_user, Database=$ds_name, Port=$ds_port" echo "$ds_pass" | PGPASSWORD="$ds_pass" psql -h "$ds_host" -U "$ds_user" -p "$ds_port" -d "$ds_name" -c "SELECT version();" > /dev/null 2>&1 if [ $? -eq 0 ]; then log "Успешное подключение к БД от пользователя $ds_user" else log "Не удалось подключиться к БД от пользователя $ds_user. Проверьте настройки доступа или пароль." fi else log "⚠️ Пропущена проверка documentserver: не удалось получить данные из local.json" fi return 0 } function update_cddisk_configs() { local new_master="$1" log "Обновление appsettings.json для cddisk на новый мастер: $new_master..." # Формируем новые строки подключения с новым IP local conn_user_actions="Database=$CDDISK_DB_NAME;Username=$CDDISK_DB_USER;Password=$CDDISK_DB_PASS;Host=$new_master;Port=$CDDISK_DB_PORT;" local conn_server="Database=$CDDISK_DB_NAME;Username=$CDDISK_DB_USER;Password=$CDDISK_DB_PASS;Host=$new_master;Port=$CDDISK_DB_PORT;" local files=( "/opt/r7-office/Api/appsettings.json" "/opt/r7-office/Sso.Api/appsettings.json" "/opt/r7-office/Processing/appsettings.json" ) for file in "${files[@]}"; do if [[ ! -f "$file" ]]; then log "⚠️ Файл $file не найден, пропущено." continue fi backup_file_if_needed "$file" # === R7StorageServerUserActions === local old_line=$(grep -A2 '"R7StorageServerUserActions"' "$file" | tr -d ' ') if [[ -n "$old_line" ]]; then log "Старая строка (R7StorageServerUserActions): $old_line" sed -i "s|\"R7StorageServerUserActions\": *\"[^\"]*\"|\"R7StorageServerUserActions\": \"$conn_user_actions\"|" "$file" if [[ $? -eq 0 ]]; then log "✅ R7StorageServerUserActions в $file обновлён" else log "❌ Ошибка при обновлении R7StorageServerUserActions в $file" fi else log "⚠️ R7StorageServerUserActions не найден в $file" fi # === R7StorageServer === local old_line=$(grep -A2 '"R7StorageServer"' "$file" | tr -d ' ') if [[ -n "$old_line" ]]; then log "Старая строка (R7StorageServer): $old_line" sed -i "s|\"R7StorageServer\": *\"[^\"]*\"|\"R7StorageServer\": \"$conn_server\"|" "$file" if [[ $? -eq 0 ]]; then log "✅ R7StorageServer в $file обновлён" else log "❌ Ошибка при обновлении R7StorageServer в $file" fi else log "⚠️ R7StorageServer не найден в $file" fi done } function update_documentserver_config() { local new_master="$1" local config="/etc/r7-office/documentserver/local.json" if [[ ! -f "$config" ]]; then log "⚠️ Файл $config не найден, пропущено." return 1 fi backup_file_if_needed "$config" current_host=$(grep '"dbHost"' "$config" | awk -F '"' '{print $4}') if [[ "$current_host" == "$new_master" ]]; then log "IP-адрес в $config уже актуален ($new_master). Изменение не требуется." return 0 fi log "Старый dbHost: $current_host" sed -i "s/\"dbHost[^\"]*\": *\"[^\"]*\"/\"dbHost\": \"$new_master\"/" "$config" if [[ $? -eq 0 ]]; then log "dbHost в $config успешно обновлён на $new_master" else log "❌ Ошибка обновления $config" fi } function restart_supervisor_services() { log "Перезапуск supervisor-сервисов..." supervisorctl restart all } function restart_documentserver_services() { log "Перезапуск ds-сервисов..." local prepare_script="/usr/bin/documentserver-prepare4shutdown.sh" if [[ -f "$prepare_script" ]]; then log "Выполняется подготовительный скрипт: $prepare_script..." "$prepare_script" if [[ $? -eq 0 ]]; then log "Подготовительный скрипт выполнен успешно." else log "⚠️ Подготовительный скрипт завершился с ошибкой. Продолжить перезапуск? (y/n)" read -p "Продолжить? " confirm [[ "$confirm" != "y" && "$confirm" != "Y" ]] && log "Перезапуск отменён пользователем." && return 1 fi else log "⚠️ Подготовительный скрипт $prepare_script не найден. Пропущено." fi local services=( "ds-converter.service" "ds-docservice.service" "ds-metrics.service" ) for service in "${services[@]}"; do if systemctl is-active --quiet "$service"; then log "Перезапуск $service..." systemctl daemon-reload > /dev/null 2>&1 systemctl restart "$service" log "$service перезапущен." else if systemctl list-units --type=service | grep -q "$service"; then log "⚠️ Сервис $service найден, но не активен. Пропущено." else log "⚠️ Сервис $service не найден. Проверьте установку документ-сервера." fi fi done log "✅ Все актуальные ds-сервисы перезапущены." } function promote_slave_to_master() { log "Продвижение slave в master..." local pg_data="/var/lib/pgsql/data" if [[ ! -f "$pg_data/standby.signal" && ! -f "$pg_data/recovery.signal" ]]; then log "⚠️ Сервер не находится в режиме standby. Пропущено продвижение в master." return 0 fi sudo -u postgres pg_ctl promote -D "$pg_data" if [ $? -eq 0 ]; then log "✅ Slave успешно переведён в режим master." else log "⚠️ Не удалось продвинуть в master (возможно, уже является master)." fi } function switch_to_slave_as_master() { log "Начало процесса переключения slave -> master..." log "Используем MASTER_IP = $MASTER_IP из констант." # Проверяем доступность БД с новым IP check_db_connection_after_change "$MASTER_IP" # Продвигаем в master (работает только если standby.signal существует) promote_slave_to_master # Обновляем конфиги приложений update_cddisk_configs "$MASTER_IP" update_documentserver_config "$MASTER_IP" # Перезапуск сервисов restart_supervisor_services restart_documentserver_services log "✅ Сервер переведён в режим master." } function switch_to_master_as_slave() { log "Начало процесса переключения master -> slave..." log "Используем MASTER_IP = $MASTER_IP для создания реплики." read -p "Вы уверены, что хотите сделать этот сервер slave? Это очистит данные. (y/n): " confirm [[ "$confirm" != "y" ]] && log "Операция отменена пользователем." && exit 1 # Убираем запрос пароля — используем REPLICATION_PASS из констант if [[ -z "$REPLICATION_PASS" ]]; then log "❌ Пароль не может быть пустым." exit 1 fi log "Остановка PostgreSQL..." systemctl stop postgresql log "Очистка каталога данных PostgreSQL..." rm -rf /var/lib/pgsql/data/* mkdir -p /var/lib/pgsql/data log "Создание новой реплики с мастера: $MASTER_IP..." # Передаем пароль через PGPASSWORD вместо stdin sudo -u postgres env PGPASSWORD="$REPLICATION_PASS" pg_basebackup \ -h "$MASTER_IP" \ -D /var/lib/pgsql/data \ -U "$REPLICATION_USER" \ -P -R if [ $? -ne 0 ]; then log "❌ Ошибка при создании реплики. Проверьте доступность мастера и учётные данные." exit 1 fi log "Запуск PostgreSQL..." systemctl start postgresql # === Меняем IP на MASTER_IP === check_db_connection_after_change "$MASTER_IP" update_cddisk_configs "$MASTER_IP" update_documentserver_config "$MASTER_IP" restart_supervisor_services restart_documentserver_services log "✅ Сервер успешно переведён в режим slave." } function show_current_configurations() { echo -e " === Текущие конфигурации с подключением к БД ===" echo "Файлы appsettings.json (только актуальные):" local files=( "/opt/r7-office/Api/appsettings.json" "/opt/r7-office/Sso.Api/appsettings.json" "/opt/r7-office/Processing/appsettings.json" ) for file in "${files[@]}"; do if [[ ! -f "$file" ]]; then echo " $file — не найден" continue fi echo " === $file ===" local user_actions=$(grep -A2 '"R7StorageServerUserActions"' "$file" | tr -d ' ' | sed 's/[",]//g; s/:[ ]*/:/g') if [[ -n "$user_actions" ]]; then echo " R7StorageServerUserActions: ${user_actions#*R7StorageServerUserActions: }" else echo " R7StorageServerUserActions: не найден" fi local storage_server=$(grep -A2 '"R7StorageServer"' "$file" | tr -d ' ' | sed 's/[",]//g; s/:[ ]*/:/g') if [[ -n "$storage_server" ]]; then echo " R7StorageServer: ${storage_server#*R7StorageServer: }" else echo " R7StorageServer: не найден" fi echo "" done local doc_config="/etc/r7-office/documentserver/local.json" echo "Файл local.json (documentserver):" if [[ -f "$doc_config" ]]; then grep -E '"(dbHost|dbName|dbUser|dbPass|dbPort)"' "$doc_config" | sed 's/^/ /' else echo " Файл не найден" fi } function get_postgres_data_dir() { local dir="/var/lib/pgsql/data" if [[ -d "$dir" ]]; then echo "$dir" return 0 else log "❌ Каталог данных PostgreSQL не найден." return 1 fi } function get_postgres_role() { local pg_data="/var/lib/pgsql/data" # Попробуем через SQL, если PostgreSQL запущен if systemctl is-active --quiet postgresql > /dev/null 2>&1; then local role_sql=$(sudo -u postgres psql -tAc "SELECT pg_is_in_recovery();") if [[ $? -eq 0 ]]; then if [[ "$(echo "$role_sql" | tr '[:upper:]' '[:lower:]')" == "f" ]]; then echo "master" return 0 else echo "slave" return 0 fi else log "⚠️ Не удалось выполнить запрос к PostgreSQL." fi fi # Если БД не запущена — проверяем сигналы if [[ -f "$pg_data/standby.signal" ]]; then echo "slave" return 0 elif [[ -f "$pg_data/postmaster.pid" ]]; then echo "master" return 0 else log "❌ Не удалось определить роль PostgreSQL." echo "unknown" return 1 fi } function is_master() { [[ "$(get_postgres_role)" == "master" ]] } function is_slave() { [[ "$(get_postgres_role)" == "slave" ]] } function show_status_replication() { local local_ip=$(get_local_ip) echo -e " === Текущий статус сервера ===" echo "IP сервера: $local_ip" echo "MASTER_IP (константа): $MASTER_IP" echo "SLAVE_IP (константа): $SLAVE_IP" local role=$(get_postgres_role) echo "Роль: ${role^}" if [[ "$role" == "master" ]]; then echo "Проверка состояния репликации:" env PGHOME=/tmp sudo -u postgres PGOPTIONS="-c search_path=pg_catalog" psql -c "SELECT * FROM pg_stat_replication;" elif [[ "$role" == "slave" ]]; then echo "Проверка состояния восстановления:" env PGHOME=/tmp sudo -u postgres PGOPTIONS="-c search_path=pg_catalog" psql -c "SELECT * FROM pg_stat_wal_receiver;" else echo "Роль: Не определена" fi echo -e "============================== " } function main_menu() { clear echo "=== Добро пожаловать в систему управления PostgreSQL ===" echo "Лог-файл: $LOG_FILE" echo "" while true; do echo "=== Меню управления PostgreSQL ===" echo "1. Установка параметров master" echo "2. Установка параметров slave" echo "3. Показать текущие конфиги" echo "4. Проверка подключения с новыми параметрами" echo "5. Восстановить конфигурации из .bak" echo "6. Перезапустить сервисы приложений" echo "7. Показать текущий статус сервера" echo "8. Выход" read -p "Выберите действие (1-8): " choice case $choice in 1) switch_to_slave_as_master show_status_replication read -p "Нажмите Enter для продолжения..." ;; 2) switch_to_master_as_slave show_status_replication read -p "Нажмите Enter для продолжения..." ;; 3) show_current_configurations read -p "Нажмите Enter для продолжения..." ;; 4) check_db_connection_after_change "$MASTER_IP" read -p "Нажмите Enter для продолжения..." ;; 5) restore_all_configs read -p "Нажмите Enter для продолжения..." ;; 6) log "Перезапуск всех сервисов..." supervisorctl restart all restart_documentserver_services read -p "Нажмите Enter для продолжения..." ;; 7) show_status_replication read -p "Нажмите Enter для продолжения..." ;; 8) log "Выход..." exit 0 ;; *) echo "Неверный выбор." sleep 2 ;; esac clear done } # === MAIN === check_superuser main_menu
Описание пунктов:
- Установка параметров master — устанавливает параметры master для сервера используемого основным (меняет конфигурации приложений на использование БД master) и создает в том же каталоге резервную копию изменяемых файлов;
- Установка параметров slave — устанавливает параметры slave для сервера используемым запасным (меняет конфигурации приложений на использование БД master и включение репликации на этом сервере) и создает в том же каталоге резервную копию изменяемых файлов;
- Показать текущие конфиги — показывает текущие параметры приложений;
- Проверка подключения с новыми параметрами — проверяет доступ для приложений с заданными константами по подключению к master;
- Восстановить конфигурации из
.bak
— при ранее измененных конфигураций приложений может восстановить резервные копии файлов из формата.bak
; - Перезапустить сервисы приложений — перезапускает сервисы приложений;
- Показать текущий статус сервера — указывает состояние БД на текущем сервере.
8.2. Проверка работы серверов
Для проверки потребуется переключать в DNS А-запись ведущая на первый сервер.
Перейдите по адресу https://admin.test2.s7-office.site.
Убедитесь что используется корректная адресация на первый адрес Корпоративного сервера (используйте команду ping) и используйте предустановленный логин\пароль superadmin.
Создайте пользователя и проверьте редактирование файлов — корректное сохранение файлов и повторное открытие файлов.
Далее переключите А-запись на второй сервер и так же проверьте его работу.
В DNS используйте установленную текущую ноду как master. Запустите скрипт управления БД и проверьте текущие статусы серверов.
Настоятельно рекомендуется отработать поэтапное переключение из slave в master на втором сервере в случае появления ошибок на первом сервере.
9. Резервное копирование и восстановление
Для проведения резервирования и восстановления необходимо использовать скрипты из статьи: Резервное копирование/восстановление Корпоративный сервер 2024.
Перед использованием скрипта создания бекапа добавьте каталог mail, приведите к виду строку:
При использовании почтового сервера.
# Создание архива с бэкапом
tar cf "$backup_dir/cddisk-${backup_date}.tar.bz2" --selinux --use-compress-prog="lbzip2 -k -n$num_cores" /opt/r7-office $supervisor_dir /etc/r7-office /var/r7-office /var/www/r7-office "$backup_dir/cddisk_db.tar.gz /mail"
При восстановлении на мастер ноде рекомендуется остановить службу:
systemctl stop glusterfs
После завершения восстановления включить:
systemctl start glusterfs
При восстановлении резервной ноды нет необходимости выполнения восстановления, так как скрипт позволяет назначить вторую ноду репликой первой для БД и автоматическую синхронизацию каталогов производится средствами GlusterFS.