Кластер PostgreSQL
В этой инструкции рассматривается развёртывание отказоустойчивого кластера PostgreSQL средствами, включёнными в состав дистрибутива Геном.
Пропустите этот шаг, если отказоустойчивость СУБД не требуется или будет использоваться внешний сервер PostgreSQL.
Доступ к мастеру PostgreSQL выполняется через VIP. Для автоматического переназначения VIP на узлах кластера развёртываются службы vip-manager и etcd.
Для отслеживания состояния узлов кластера и автоматического выбора нового мастера используется Patroni.
|
В Patroni мастер PostgreSQL называется лидером. |
В этой инструкции в качестве примера рассматривается развёртывание кластера на узлах со следующими параметрами:
| IP-адрес | Доменное имя | Описание |
|---|---|---|
|
|
Узлы кластера |
|
|
|
|
|
|
|
|
VIP, всегда указывающий на мастер кластера PostgreSQL |
Сеть
Для корректной работы кластера должны быть открыты соответствующие сетевые порты. Список портов и протоколов приводятся в описании компонентов подсистемы мониторинга:
Подготовка узлов кластера
Чтобы подготовить узлы будущего кластера к развёртыванию:
-
Убедитесь, что настройки
sudoразрешают группеwheelвыполнение любых команд.Как правило, достаточно создать в директории
/etc/sudoers.d/файлwheel-groupсо следующим содержимым:%wheel ALL=(ALL:ALL) ALLДля создания файла рекомендуется использовать утилиту
visudo. Она автоматически проверит синтаксис созданного файла и предотвратит сохранение изменений, которые могут нарушить работуsudo.visudo -f /etc/sudoers.d/wheel-group -
Убедитесь, что пользователь
rootсостоит в группеwheel.Чтобы добавить пользователя
rootв группуwheel, используйте командуusermod:usermod -a wheel -G root
Установка
После подготовительных работ переходите к установке:
-
Выберите один из узлов будущего кластера и используйте в качестве установочного. Все описанные далее действия выполняйте на нём.
-
Создайте и активируйте виртуальное окружение Python.
-
Загрузите на установочный узел архив
ansible-ha-pg-cluster-2025-12-12.tar.gz. -
Распакуйте архив
ansible-ha-pg-cluster-2025-12-12.tar.gz:tar xvfz ansible-ha-pg-cluster-2025-12-12.tar.gz -
Перейдите в директорию с файлами, извлечёнными из архива
ansible-ha-pg-cluster-2025-12-12.tar.gz:cd ansible-pg-cluster/ -
Заполните файл инвентаря
inventory.yml.Пример заполнения файла inventory.ymlall: vars: ansible_user: root ansible_ssh_extra_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" ansible_ssh_pass: "<password>" secrets: /root/patroni_secrets cluster_name: patroni pgport: 5432 pgdata: /pgdata ip_master: 192.168.0.24/24 service_users: - name: admin password: "<admin_password>" flags: SUPERUSER hosts: pg-1.example.com: ansible_host: 192.168.0.21 hostname: pg-1.example.com pg-2.example.com: ansible_host: 192.168.0.22 hostname: pg-2.example.com pg-3.example.com: ansible_host: 192.168.0.23 hostname: pg-3.example.comЗдесь:
-
cluster_name— название кластера Patroni; -
ip_master— Virtual IP, который будет использоваться для доступа к мастеру PostgreSQL; -
pgdata— путь к директории для хранения данных PostgreSQL; -
pgport— номер порта, который будет слушать кластер PostgreSQL; -
secrets— путь к директории, в которую плейбук должен сохранить секреты, используемые для доступа к кластеру Patroni; -
service_users— список пользователей, используемых для управления кластером PostgreSQL.
-
-
Запустите выполнение плейбука:
ansible-playbook -i inventory.yml cluster.yml -
Деактивируйте виртуальное окружение:
deactivate -
Сохраните в надёжном месте содержимое директории, путь к которой указали в файле
inventory.ymlв значении параметраall.vars.secrets.При повторном запуске плейбук проверяет наличие секретов в указанной директории. Если секреты не будут найдены, плейбук сгенерирует их заново. При этом старые секреты станут недействительными и использующие их клиенты потеряют доступ к кластеру.
Инициализация
-
Используя VIP, подключитесь к мастеру кластера PostgreSQL через SSH.
-
Запустите интерпретатор PostgreSQL:
sudo -u postgres psql -
Создайте роли:
CREATE ROLE <role> WITH LOGIN PASSWORD '<password>';Здесь:
-
<role>— название роли.Таблица 1. Рекомендуемые названия ролей Роль Компонент authПлатформа
authzgenomebrГеном.БР
genomeСервер подсистемы управления
visionСервер подсистемы мониторинга и Grafana
-
<password>— пароль роли.
-
-
Создайте базы данных:
CREATE DATABASE <name> OWNER <owner> ENCODING 'UTF8' LC_COLLATE 'ru_RU.UTF-8' LC_CTYPE 'ru_RU.UTF-8' TEMPLATE template0;Здесь:
-
<name>— название БД; -
<owner>— название роли владельца БД.
Таблица 2. Рекомендуемые названия и владельцы БД БД Владелец Компонент auth_dbauthПлатформа
authz_dbauthzgenome_br_dbgenome_brГеном.БР
genome_dbgenomeСервер подсистемы управления
grafana_dbvisionGrafana
vision_dbСервер подсистемы мониторинга
-
-
Завершите работу с интерпретатором:
\q -
Отключитесь от мастера PostgreSQL.
Проверка корректности
Проверьте корректность развёртывания кластера:
-
На любом узле кластера выполните команду:
patronictl -c /etc/patroni/config.yml topologyОжидаемый результат выполнения команды:
-
Один узел с ролью Leader.
-
Один узел с ролью Sync Standby.
-
Один узел с ролью Replica.
-
-
На лидере выполните команду:
ip -br aОжидаемый результат выполнения команды: к одному из сетевых интерфейсов привязан VIP, указанный в файле
inventory.ymlв значении параметраall.vars.ip_master. -
Убедитесь в возможности подключения к кластеру с не входящих в него узлов:
psql -h <vip> -U <admin> -p 5432 -d postgresЗдесь:
-
<vip>— VIP лидера; -
<admin>— название учётной записи администратора СУБД.
Подключение должно быть успешным.
-
-
Выполните дополнительные проверки:
-
Убедитесь, что на лидере запрос возвращает значение
f:ЗапросSELECT pg_is_in_recovery();Ожидаемый результатpg_is_in_recovery ------------------- f (1 строка) -
Получите список БД:
\l+ -
Убедитесь, что на лидере выводится информация о репликах:
ЗапросSELECT * FROM pg_stat_replication \gxПример ответа-[ RECORD 1 ]----+------------------------------ pid | 36671 usesysid | 16384 usename | repl application_name | pg-2.example.com client_addr | 192.168.0.22 client_hostname | client_port | 44264 backend_start | 2026-09-02 12:24:38.271025+03 backend_xmin | state | streaming sent_lsn | 0/48E3F68 write_lsn | 0/48E3F68 flush_lsn | 0/48E3F68 replay_lsn | 0/48E3F68 write_lag | flush_lag | replay_lag | sync_priority | 1 sync_state | sync reply_time | 2026-09-02 13:14:12.321205+03 -[ RECORD 2 ]----+------------------------------ pid | 36672 usesysid | 16384 usename | repl application_name | pg-3.example.com client_addr | 192.168.0.23 client_hostname | client_port | 41578 backend_start | 2026-09-02 12:24:38.291781+03 backend_xmin | state | streaming sent_lsn | 0/48E3F68 write_lsn | 0/48E3F68 flush_lsn | 0/48E3F68 replay_lsn | 0/48E3F68 write_lag | flush_lag | replay_lag | sync_priority | 0 sync_state | async reply_time | 2026-09-02 13:14:12.321089+03 -
Проверьте значение настройки
archive_mode, по умолчанию оно должно быть равноoff.ЗапросSHOW archive_mode;Пример ответаarchive_mode -------------- off (1 строка)
-