Перейти к основному содержимому

Приложение 1. Установка и настройка кластера БД

Для обеспечения отказоустойчивости БД мы рекомендуем использование в качестве кластерного решения использование следующих компонентов:

  • Hashicorp Consul DCS - в роли арбитра для кластерных ресурсов и сервисов.
  • Patroni - в роли управляющего кластером PostgreSQL ПО.
  • Dnsmasq - как кеширующий DNS-сервер, для разрешения имен зарегистрированных сервисов Consul.
  • Дополнительное конфигурирование DHCP-клиента, при использовании динамического получения адреса.

Все вышеназванное ПО имеет открытый код и длительное время показывает стабильную работу. Мы включаем в рекомендации только протестированные нами версии ПО.

к сведению

Установка кластерной БД под управлением Patroni требует согласования параметров всех компонентов. Поэтому при развертывании мы рекомендуем использовать сценарии Ansible.

к сведению

Процесс установки ПО для кластеризации БД в данном разделе описывается для пояснения взаимодействия между компонентами.

Исходные параметры:

  • На всех узлах c компонентами Luxms BI устанавливается HashiCorp Consul с режимом работы server или client.
  • Для кластера HashiCorp Consul используется нечетное количество узлов в режиме server - 3.
  • Для кластера БД PostgreSQL используется не менее 2-х узлов, для запуска экземпляра БД.

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

Установку Consul DCS рекомендуем выполнять из нашего репозитория.
Отличие нашей сборки - мы добавили в пакет наш шаблон конфигурационного файла в формате HCL.

осторожно

Вы можете использовать репозиторий производителя. Для использования репозитория Производителя ПО, в связи с санкционными ограничениями, требуется использование прокси-сервера с отличным от отечественного GEO-локацией по IP-адресу.

Лицензионные ограничения Hashicorp Consul

В связи с изменением лицензионной политики компании Hashicorp c Mozilla Public License v2.0 на Business Source License v1.1, мы не можем более предлагать к развертыванию Consul DCS с версией выше чем 1.16.1.

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

Consul, в большей степени, используется в роли DCS для организации отказоустойчивого кластера БД Postgres. Дополнительно мы вложили в него логику проверок (HealthChecks) работоспособности сервисов Luxms BI и обеспечения их доступности.

Для организации работоспособности нашего решения эта версия содержала весь необходимый функционал. При этом за все время эксплуатации не было зафиксировано инцидентов информационный безопасности. В данный момент версия 1.16.1 доступна в наших репозиториях для установки и использования.

Мы начали процесс пересмотра технологий и поиск нового подхода для обеспечения контроля за узлами и компонентами Luxms BI. Это потребует достаточно много времени.

Мы собрали и опубликовали в наших репозиториях пакеты Consul с версией 1.16.1 (и даже исправили уязвимости, которые Производитель закрыл в декабре 2023 года).

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

  • при развертывании Consul необходимо использовать уникальный ключ шифрования;
  • при развертывании Consul использовать встроенные средства фильтрации сетевого трафика(Firewall) для ограничения доступа;
  • ограничивать доступ к Web-консоли DCS Consul с использованием аутентификации пользователей.

Планирование DCS Consul

Типовая схема кластера

Схема взаимодействия компонентов кластера PostgreSQL

Планирование DCS Consul

Consul - это Distributed Control Service (DCS), гарантированно предоставляющий актуальную информацию по состоянию зарегистрированных сервисов. Продукт хорошо документирован производителем и обладает широким ассортиментом интеграционных решений. Для поддержки отказоустойчивости кластера PostgreSQL и разнесения нагрузки мы воспользуемся функционалом DNS-интерфейса.

к сведению

Необходимость установки Consul на все сервера программного комплекса обусловлена использованием его DNS-интерфейса для настройки доступа к БД в приложениях.

к сведению

Альтернативное решение - настройка /etc/resolv.conf может привести к значительному снижению времени отклика приложений, в случае выхода/вывода из рабочего режима одного из настроенных серверов имен.

Для начала установки необходимо:

  1. Определить перечень узлов, на которых Consul агент должен запускаться в серверном режиме.

На каждый узел программного комплекса Luxms BI должен быть установлен агент Consul, работающий в серверном или клиентском режиме. Так как для обеспечения работы Consul требуется нечетное количество агентов в серверном режиме (рекомендуемое количество 3 и не более 7) большая часть узлов использует агента в клиентском режиме. Режим работы определяется флагом server(bool) файла конфигурации.

  1. Для настройки файла конфигурации необходимо сгенерировать единый секретный token.

Общий секретный token используется на всех узлах программного комплекса. Можно использовать собственный генератор или любую из предложенных ниже команд:

openssl rand -base64 32

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

/usr/sbin/consul keygen

Установка и настройка Consul DCS

Как было сказано выше, пакет consul находится в репозиториях Luxms. Поэтому установку можно выполнить без дополнительных настроек.

  1. Установка:

Для RPM-based OC:

sudo dnf -y install consul

Для DEB-based ОС:

sudo apt-get update && sudo apt-get -y install consul
  1. Настройка конфигурационного файла:

Для первоначального запуска предлагаем использовать следующие конфигурационные файлы. Замените значение параметра encrypt на преварительно сгенерированный секретный токен:

Конфигурационный файл для работы в режиме **server**, /etc/consul.d/consul.hcl
datacenter = "luxmsbi"
data_dir = "/opt/consul"
bind_addr = "0.0.0.0"
client_addr = "0.0.0.0"
advertise_addr = "10.0.0.11"
domain = "consul"
enable_local_script_checks = true
dns_config = {
enable_truncate = true
only_passing = true
}
recursors = [ "127.0.0.1" ]
enable_syslog = true
encrypt = "5wDTh+YLWG5DTDDfEeWkQ1j9J72+aJ3NOavqTRaLlUA="
leave_on_terminate = true
log_level = "INFO"
rejoin_after_leave = true
retry_join = [
"consul-server-01.localnet",
"consul-server-02.localnet",
"consul-server-03.localnet"
]
server = true
bootstrap_expect = 3
ui_config = {
enabled = true
}
Конфигурационный файл для работы в режиме **client**, /etc/consul.d/consul.hcl
datacenter = "luxmsbi"
data_dir = "/opt/consul"
bind_addr = "0.0.0.0"
client_addr = "0.0.0.0"
advertise_addr = "10.0.0.5"
domain = "consul"
enable_local_script_checks = true
dns_config = {
enable_truncate = true
only_passing = true
}
recursors = [ "127.0.0.1" ]
enable_syslog = true
encrypt = "5wDTh+YLWG5DTDDfEeWkQ1j9J72+aJ3NOavqTRaLlUA="
leave_on_terminate = true
log_level = "INFO"
rejoin_after_leave = true
retry_join = [
"consul-server-01.localnet",
"consul-server-02.localnet",
"consul-server-03.localnet"
]
  • datacenter — привязка сервера к конкретному датацентру. Нужен для логического разделения. Серверы с одинаковым датацентром должны находиться в одной локальной сети.
  • data_dir — каталог для хранения данных.
  • bind_addr — адрес, на котором будет слушать наш сервер Consul. Это может быть IP любого из наших сетевых интерфейсов или, как в данном примере, все.
  • client_addr — адрес, к которому будут привязаны клиентские интерфейсы.
  • advertise_addr — адрес, которой мы анонсируем другим узлам кластера. Это должен быть адрес, назначенный на одном из интерфейсов сервера.
  • domain — домен, в котором будет зарегистрирован сервис.
  • enable_local_script_checks — разрешает на агенте проверку работоспособности.
  • dns_config — параметры для настройки DNS.
  • recursors — адреса вышестоящих DNS-серверов, которые используются для рекурсивного разрешения запросов, если они не находятся внутри домена службы Consul.
  • enable_syslog — разрешение на ведение лога.
  • encrypt — ключ для шифрования сетевого трафика. В качестве значения используем сгенерированный ранее.
  • leave_on_terminate — при получении сигнала на остановку процесса консула, корректно отключать ноду от кластера.
  • log_level — минимальный уровень события для отображения в логе. Возможны варианты “trace”, “debug”, “info”, “warn”, and “err”.
  • rejoin_after_leave — по умолчанию, нода, покидающая кластер, не присоединяется к нему автоматически. Данная опция позволяет управлять данным поведением.
  • retry_join — перечисляем узлы, к которым можно присоединять кластер. Процесс будет повторяться, пока не завершится успешно.
  • server — режим работы сервера.
  • start_join — список узлов кластера, к которым пробуем присоединиться при загрузке сервера.
  • ui_config — конфигурация для графического веб-интерфейса.

Проверяем корректность конфигурационного файла. Мы должны увидеть подтверждение корректности конфигурации в выводе:

/usr/bin/consul validate /etc/consul.d/consul.hcl

...
Configuration is valid!
  1. Настройка разрешений локального firewall:

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

Для RPM-based ОС при установке consul создаются файлы описания сервисов для Firewalld следующего содержания:

Шаблон конфигурации сервиса Firewalld, consul-server.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>consul-server</short>
<description>Server access. Consul makes it simple for services to register themselves and to discover other services via a DNS or HTTP interface. https://www.consul.io/docs/install/ports.html </description>
<port protocol="tcp" port="8300"/>
<port protocol="tcp" port="8301"/>
<port protocol="tcp" port="8302"/>
<port protocol="tcp" port="8502"/>
<port protocol="tcp" port="8600"/>

<port protocol="udp" port="8301"/>
<port protocol="udp" port="8302"/>
<port protocol="udp" port="8600"/>
</service>
Шаблон конфигурации сервиса Firewalld, consul-web.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>consul-web</short>
<description>Web access to Consul. Consul makes it simple for services to register themselves and to discover other services via a DNS or HTTP interface. https://www.consul.io/docs/install/ports.html </description>
<port protocol="tcp" port="8500"/>
<port protocol="tcp" port="8501"/>
</service>
Шаблон конфигурации сервиса Firewalld, consul-client.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>consul-client</short>
<description>Client access. Consul makes it simple for services to register themselves and to discover other services via a DNS or HTTP interface. https://www.consul.io/docs/install/ports.html </description>
<port protocol="tcp" port="8300"/>
<port protocol="tcp" port="8301"/>

<port protocol="udp" port="8301"/>
</service>
к сведению

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

Для обеспечения взаимодействия между узлами с ролью server. Добавление Firewalld-сервисов производится на на этих узлах, для примера на сервере 10.0.0.11 :

sudo firewall-cmd --permanent --new-service-from-file=consul-server.xml

sudo firewall-cmd --permanent \
--add-rich-rule='rule family="ipv4" source address="10.0.0.12" service name="consul-server" accept'
sudo firewall-cmd --permanent \
--add-rich-rule='rule family="ipv4" source address="10.0.0.13" service name="consul-server" accept'

sudo firewall-cmd --reload

Для ограничения доступа к Web-консоли Consul только с хостов принадлежащих администраторам, например 192.168.1.200, на узлах с ролью server выполняются следующие команды:

sudo firewall-cmd --permanent --new-service-from-file=consul-web.xml

sudo firewall-cmd --permanent \
--add-rich-rule='rule family="ipv4" source address="192.168.1.200" service name="consul-web" accept'

sudo firewall-cmd --reload

Для обеспечения взаимодействия между узлами(обнаружение узлов и проверка их работоспособности) с запущенным Consul, необходимо настроить сетевые ограничения. Наиболее оптимально использование сегментацию сетей, адреса сети и/или ipset.

На каждом узле с ролью server нужно запустить следующий перечень команд, например для сегментированной сети 10.0.0.0/28:

sudo firewall-cmd --permanent --new-service-from-file=consul-client.xml

sudo firewall-cmd --permanent \
--add-rich-rule='rule family="ipv4" source address="10.0.0.0/28" service name="consul-client" accept'

sudo firewall-cmd --reload

На каждом узлах с ролью client нужно запустить следующий перечень команд, например для ipset(небольшого списка IP-адресов и/или подсетей):

sudo firewall-cmd --permanent --new-service-from-file=consul-client.xml

sudo firewall-cmd --permanent --new-ipset=consulAgent --type=hash:net
sudo firewall-cmd --permanent --ipset=consulAgent --add-entry=10.0.0.5
sudo firewall-cmd --permanent --ipset=consulAgent --add-entry=10.0.0.6
sudo firewall-cmd --permanent --ipset=consulAgent --add-entry=10.0.0.7
sudo firewall-cmd --permanent --ipset=consulAgent --add-entry=10.0.0.8
sudo firewall-cmd --permanent --ipset=consulAgent --add-entry=10.0.0.9
sudo firewall-cmd --permanent --ipset=consulAgent --add-entry=10.0.0.10
sudo firewall-cmd --permanent --ipset=consulAgent --add-entry=10.0.0.11
sudo firewall-cmd --permanent --ipset=consulAgent --add-entry=10.0.0.12

sudo firewall-cmd --permanent \
--add-rich-rule='rule family="ipv4" source ipset="consulAgent" service name="consul-client" accept'

sudo firewall-cmd --reload

Для DEB-based ОС при установке consul создаются файлы приложений UFW следующего содержания:

Шаблон конфигурации сервиса UFW, /etc/ufw/applications.d/consul-server
[consul-server]
title=HashiCorp Consul DCS
description=Consul makes it simple for services to register themselves and to discover other services via a DNS or HTTP interface. https://www.consul.io/docs/install/ports.html.
ports=8300:8302,8502,8600/tcp|8301:8302,8600/udp
Шаблон конфигурации сервиса UFW, /etc/ufw/applications.d/сonsul-client
[consul-client]
title=HashiCorp Consul Client
description=Consul makes it simple for services to register themselves and to discover other services via a DNS or HTTP interface. https://www.consul.io/docs/install/ports.html.
ports=8300:8301/tcp|8301/udp
Шаблон конфигурации сервиса UFW, /etc/ufw/applications.d/consul-web
[consul-web]
title=HashiCorp Consul Web UI
description=Consul makes it simple for services to register themselves and to discover other services via a DNS or HTTP interface. https://www.consul.io/docs/install/ports.html.
ports=8500:8501/tcp

Для добавление application в конфигурацию UFW выполните следующие команды:

sudo ufw app update --add-new
sudo ufw allow from 10.0.0.4 to any app consul-server
sudo ufw allow from 10.0.0.5 to any app consul-server
sudo ufw allow from 10.0.0.6 to any app consul-client
sudo ufw allow from 10.0.0.0 to any app consul-web
  1. Запуск DCS Consul и проверка работоспособности:

Запускаем сервис Consul-a на всех узлах:

sudo systemctl enable consul.service --now

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

# /usr/bin/consul members

Или через Web-интерфейс, который доступен по ссылке, на резрешенном сетевыми правилами сервере с ролью server - http://<node>:8500/.

Настройка разрешения ресурсов зоны .consul

Для обеспечения актуальности сведений о зарегистрированных сервисах Consul DNS-интерфейс разрешает имена без кэширования с TTL=0. Consul позволяет перенаправлять запросы на другие DNS-сервера, но более оптимальное решение - использование интеграции Consul и Dnsmasq для разрешения всех запросов.

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

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

Для RPM-based ОС:

sudo dnf -y install dnsmasq

Для DEB-based ОС:

sudo apt -y install dnsmasq

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

Минимальный конфигурационный файл, /etc/dnsmasq.conf
# Configuration file for dnsmasq.
#
# Format is one option per line, legal options are the same
# as the long options legal on the command line. See
# "/usr/sbin/dnsmasq --help" or "man 8 dnsmasq" for details.

# Never forward plain names (without a dot or domain part)
domain-needed

# Add other name servers here, with domain specs if they are for
# non-public domains.
server=/consul/127.0.0.1#8600

# If you don't want dnsmasq to read /etc/hosts, uncomment the
# following line.
no-hosts

# Include all files in /etc/dnsmasq.d except RPM backup files
conf-dir=/etc/dnsmasq.d,.rpmnew,.rpmsave,.rpmorig

Разрешаем и запускаем сервис dnsmasq:

sudo systemctl enable dnsmasq --now

Дополнительная настройка ОС по разрешению имен

Если сервера используют статические IP-адреса, необходимо добавить в конфигурационный файл основного сетевого интерфейса параметр DNS1=127.0.0.1, назначая DNSMasq первичным.

Наиболее сложная тема - выбор между стандартной обработкой запросов на разрешение DNS-имен или использование systemd-resolved. Если Вы не готовы глубоко “копать” эту тему, позаботьтесь об наличии в секции [main] параметра:

[main]
...
dns=default

Если сервера используют динамическое получение IP-адреса, необходимо настроить DHCP-клиент. Создайте или добавьте следующую строку в конфигурационный файл /etc/dhcp/dhclient.conf:

prepend domain-name-servers 127.0.0.1;

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

sudo systemctl restart NetworkManager

Проверка разрешения DNS имен

Разрешение имен сервисов производится запросом:

  • для разрешения узлов
<node>.node.<partition>.ap.<datacenter>.dc.<domain>
  • для разрешения сервисов
[<tag>.]<service>.service[.<datacenter>].<domain>

Для разрешения имен сервисов в Consul DNS нет необходимости указывать имя, указанное в параметре конфигурации Consul-агента - datacenter. Если этот параметр отсутствует, то предполагается текущее значение у самого Consul-агента. т.е. следующие запросы вернут корректный IP-адрес:

  • nslookup consul.service.luxmsbi.consul
  • nslookup consul.service.consul

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

nslookup consul.service.consul
...
Name: consul.service.consul
Address: 10.0.2.5
Name: consul.service.consul
Address: 10.0.2.7
Name: consul.service.consul
Address: 10.0.2.6

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

C 2023 года, с учетом стремления Российских дистрибутивов Linux включить в себя пакеты patroni, мы поставляем свои пакеты для развертывания Менеджера отказоустойчивого кластера Postgres. В связи с чем, поставляемый нами пакет развертывает свои файлы в /opt.
Основные цели:

  • использование изолированного(VENV) экземпляра Python
  • предоставление шаблона конфигурации, для Luxms BI

До установки Patroni необходимо установить пакеты БД и необходимых расширений в соответствии с Разделом Установка и настройка сервера БД без развертывания БД Luxms BI.

Установка на RPM-based ОС

В зависимости от дистрибутива Linux, команды немного различаются.

а) Для Linux RPM (РЕД ОС, CentOS, Rocky и другие):

dnf install luxms-patroni

б) Для Linux DEB (Astra Linux):

apt install luxms-patroni

Установка конфигурации Patroni

Базовая конфигурация сервиса Patroni предоставлена ниже. Необходимо заменить некоторые значения параметров на соответствующие Вашим хостам в файле конфигурации /etc/patroni/patroni.yml (YAML):

  • name - имя узла, рекомендуется установить DNS-имя узла.
  • restapi.connect_adress - IP-адрес узла.
  • postgresql.connect_address - IP-адрес узла.
  • pg_hba.host(replication replicator), postgresql.pg_hba.host(replication replicator):
    сегмент сети узлов БД. Или несколько записей для IP-адресов узлов с маской /32.
осторожно

ОБЯЗАТЕЛЬНО замените значения (идентичные на всех узлах БД) для паролей и, если необходимо, имен учетных записей.

Данные учетных записей:

  • restapi.auth.
  • postgresql.pg_rewind.
  • postgresql.replication.
  • postgresql.superuser.

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

Исходный вид файла конфигурации /opt/patroni/etc/patroni.yml:
name: hostname
scope: db_cluster

watchdog:
mode: off

consul:
host: "localhost:8500"
register_service: true
#token: <consul-acl-token>

restapi:
listen: 0.0.0.0:8008
#!#connect_address: "192.168.0.10:8008"
auth: "patroni_rest_user:patroni_rest_password"

bootstrap:
dcs:
ttl: 30
loop_wait: 10
maximum_lag_on_failover: 1048576 # 1 megabyte in bytes
postgresql:
use_pg_rewind: true
use_slots: true
parameters:
archive_mode: "off"
wal_level: hot_standby
archive_command: "mkdir -p ../wal_archive && test ! -f ../wal_archive/%f && cp %p ../wal_archive/%f"
max_wal_senders: 10
wal_keep_segments: 8
archive_timeout: 1800s
max_replication_slots: 5
max_connections: 100
hot_standby: "on"
wal_log_hints: "on"

initdb:
- encoding: UTF8
- locale: ru_RU.UTF8
- data-checksums

pg_hba: # Add following lines to pg_hba.conf after running 'initdb'
- local all postgres peer
- host all all 0.0.0.0/0 md5
- host replication replicator 127.0.0.1/32 md5
#!#- host replication replicator 192.168.0.20/32 md5


postgresql:
use_unix_socket: true
listen: 0.0.0.0:5432
#!#connect_address: "192.168.0.10:5432"
data_dir: /var/lib/pgpro/std-13/data
bin_dir: /opt/pgpro/std-13/bin
pg_rewind:
username: postgres
pg_hba:
- local all postgres peer
- host all all 0.0.0.0/0 md5
- host replication replicator 127.0.0.1/32 md5
#!#- host replication replicator 192.168.0.20/32 md5

parameters:
unix_socket_directories: /tmp

replication:
username: replicator
password: "replicator_password"
superuser:
username: postgres
password: "postgres_password"

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

sudo systemctl enable patroni --now

Проверка работоспособности кластера БД

После запуска Patroni DNS-интерфейс Consul разрешает запросы для сервиса PostgreSQL, например:

[root@centos-4 ~]# dig master.postgresdb.service.consul +short
10.0.2.5
[root@centos-4 ~]# dig replica.postgresdb.service.consul +short
10.0.2.4
[root@centos-4 ~]# dig replica.postgresdb.service.consul SRV +short
1 1 5432 centos-2.local.node.dc0.consul.

Проверка статуса узлов кластера:

patronictl list

default

После установки пакета luxms-patroni в shell пользователя root добавляется alias, который позволяет набирать команду patronictl без необходимости прописывать полный путь до конфигурационного файла. Чтобы данный alias применился, нужно зайти под пользователем root или, если мы уже под ним работает, зайти еще раз.

:::

Если же мы работает не под пользователем root, команде patronictl нужно передавать аргумент с указанием пути до конфигурационного файла, например:

patronictl -c /etc/patroni/patroni.yml list

{.is-info}

Статус конкретного (например, postgresdb) кластера узла мы можем посмотреть командой:

patronictl list postgresdb

Пример ответа:

ClusterMemberHostRoleStateTLLag in MB
postgresdbcentos-1.local10.0.2.5Leaderrunning25
postgresdbcentos-2.local10.0.2.4running250.0