Построение отказоустойчивого кластера СУБД Postgres¶
Choose a language: RU | EN | ZH
- Содержание
- Построение отказоустойчивого кластера СУБД Postgres
- Архитектура
- Установка пакетов
- Предварительная подготовка
- Настраиваем репликацию
- Настройка кластера
Вы уже знаете, что редакция Tegu Enterprise может хранить базу данных параметров и почту в СУБД Postgres.
Мультисерверная редакция Tegu Enterprise позволяет собрать кластер вычислительных нод Tegu, состоящий из любого количества нод, что позволяет обеспечить отказоустойчивость, а также горизонтально масштабировать мощность сервера. Все они работают симметрично и хранят информацию в СУБД. Однако и сама СУБД может быть собрана по отказоустойчивой схеме. Как это сделать описано в данном разделе.
Обратите внимание, что сборка кластера Postgres не имеет прямого отношения в дистрибутиву Tegu. Тем не менее, данная статья может оказаться полезной в практической реализации решения и потому предлагается вашему вниманию.
Архитектура¶
- Три ноды:
- сервер СУБД - pgc1 (10.1.1.21),
- сервер СУБД - pgc2 (10.1.1.22),
- участник кворума pgc3 (10.1.1.23),
- виртуальный IP - pgc-vip (10.1.1.20).
Установка пакетов¶
На серверы СУБД необходимо установить сервер PostgreSQL версии не ниже 13.
На все серверы надо установить pcs, необходимый агент fence (fence_pve, fence_virsh, fence_vmware или др.).
Если в репозитории resource-agents-paf версии ниже 2.3.0, то надо скачать отсюда последнюю стабильную версию.
Предварительная подготовка¶
На всех серверах в файле /etc/hosts должны быть сопоставления имён всех нод с их адресами IP.
Также в этом файле должно быть сопоставление имени для виртуального IP:
10.1.1.20 pgc-vip 10.1.1.21 pgc1.lan pgc1 10.1.1.22 pgc2.lan pgc2 10.1.1.23 pgc3.lan pgc3
Отключаем автозапуск PostgreSQL на серверах СУБД:
systemctl stop postgresql-13.service
systemctl disable postgresql-13.service
Также не забываем убедиться, что в SysV тоже выключено (update-rc.d, chkconfig,...)
Настраиваем репликацию¶
На сервере pgc1¶
Если менеджер пакетов не создал системную БД, то надо её создать:
/usr/pgsql-13/bin/postgresql-13-setup initdb
В конец postgresql.conf добавляем параметры:
listen_addresses = '*' hba_file = '/var/lib/postgresql/13/pg_hba.conf' include = '../standby.conf'
Файл postgresql.conf может быть либо в /etc/postgresql, либо в в PGDATA (/var/lib/postgresql/13/data).
В файле /var/lib/postgresql/13/standby.conf указываем параметры подключения к мастеру для репликации (это нужно на случай, если она перестанет быть мастером):
primary_conninfo = 'user=repuser host=10.1.1.20 application_name=pgc1'
Переносим pg_hba.conf в папку /var/lib/postgresql/13. Этот файл изначально может быть либо в /etc/postgresql, либо в PGDATA.
В файл pg_hba.conf добавляем запреты и разрешения доступа на репликацию:
host replication repuser 10.1.1.20/32 reject local replication all reject host replication all pgc1 reject host replication all 127.0.0.0/8 reject host replication all ::1/128 reject host replication all 10.1.1.21/32 reject host replication repuser 10.1.1.22/32 trust
Временно назначаем виртуальный IP:
ifconfig eth0:1 10.1.1.20/24
Временно запускаем PostgreSQL:
systemctl start postgresql-13.service
Переходим под системного пользоваеля postgres и создаём роль для репликации:
su - postgres
psql
CREATE USER repuser REPLICATION;
Выходим из psql (Ctrl+D) и из пользователя postgres (Ctrl+D).
На сервере pgc2¶
Чистим PGDATA:
rm -rf /var/lib/postgresql/13/data/*
Переходим под пользователя postgres и скачиваем реплику с мастера:
su - postgres
pg_basebackup -h pgc-vip -U repuser -D /var/lib/postgresql/13/data -X stream -P
В файле /var/lib/postgresql/13/standby.conf указываем параметры подключения к мастеру для репликации:
primary_conninfo = 'user=repuser host=10.1.1.20 application_name=pgc2'
Создаём файл /var/lib/postgresql/13/pg_hba.conf с таким же содержимым, как и на pgc1, но меняем следующие строки:
host replication all pgc1 reject
Меняем на:
host replication all pgc2 reject
host replication all 10.1.1.21/32 reject
Меняем на:
host replication all 10.1.1.22/32 reject
host replication repuser 10.1.1.22/32 trust
Меняем на:
host replication repuser 10.1.1.21/32 trust
Указываем, что это подчинённый сервер:
touch /var/lib/postgresql/13/data/standby.signal
Выходим из пользователя postgres (Ctrl+D).
На сервере pgc1¶
Останавливаем PostgreSQL:
systemctl stop postgresql-13.service
Убираем виртуальный IP:
ifconfig eth0:1 0.0.0.0
Настройка кластера¶
Для начала на всех серверах надо задать один и тот же пароль для пользователя hacluster:
passwd hacluster
Включаем и запускаем демон pcsd на всех нодах:
systemctl enable --now pcsd
На каждой ноде запускаем авторизацию с остальными:
pcs host auth -u hacluster pgc1 pgc2 pgc3
Создаём кластер, выполнив следующее на первой ноде (pgc1):
pcs cluster setup pgsql_cluster pgc1 pgc2 pgc3
Чтобы не было никаких неожиданных спец.эффектов после перезапуска нод, отключаем автозапуск pacemaker-а. На каждой ноде:
pcs cluster disable --all
На сервере pgc1¶
Включаем кластер:
pcs cluster start --all
Задаём параметры по умолчанию:
pcs resource defaults migration-threshold=5
pcs resource defaults resource-stickiness=10
Создаём устройства ограждения (fencing). Здесь приводятся устройства для Proxmox, но в других конфигурациях могут быть другие. Для конкретного типа надо смотреть доку по параметрам:
pcs cluster cib fencing.xml
pcs -f fencing.xml stonith create fence_vm_pgc1 fence_pve pcmk_host_list="pgc1" pcmk_host_check="static-list" ipaddr="10.1.1.199" node_name="vrt1" login="fenceuser@pve" passwd="Qwe123Poi" port="101" power_wait="10" vmtype="lxc"
pcs -f fencing.xml stonith create fence_vm_pgc2 fence_pve pcmk_host_list="pgc2" pcmk_host_check="static-list" ipaddr="10.1.1.199" node_name="vrt1" login="fenceuser@pve" passwd="Qwe123Poi" port="102" power_wait="10" vmtype="lxc"
pcs -f fencing.xml stonith create fence_vm_pgc3 fence_pve pcmk_host_list="pgc3" pcmk_host_check="static-list" ipaddr="10.1.1.199" node_name="vrt1" login="fenceuser@pve" passwd="Qwe123Poi" port="103" power_wait="10" vmtype="lxc"
Здесь:
- 10.1.1.199 - адрес любой достуной ноды Proxmox,
- node_name="vrt1" - имя ноды (точно, как указано в самом Proxmox),
- fenceuser@pve - пользователь Proxmox, который имеет право перезапускать, запускать и останавливать данные ВМ,
- port="101" - vmid виртуалки, для которой создаётся устройство (берётся в Proxmox),
- vmtype="lxc" - тип виртуалки (в данном случае - контейнер LXC).
Указываем для каждой ноды, что её устройство ограждения на ней же самой сработать не может (сами в себя не стреляем):
pcs -f fencing.xml constraint location fence_vm_pgc1 avoids pgc1=INFINITY
pcs -f fencing.xml constraint location fence_vm_pgc2 avoids pgc2=INFINITY
pcs -f fencing.xml constraint location fence_vm_pgc3 avoids pgc3=INFINITY
И применяем конфигурацию:
pcs cluster cib-push scope=configuration fencing.xml
Создаём ресурс PostgreSQL:
pcs cluster cib cluster1.xml
pcs -f cluster1.xml resource create pgsqld ocf:heartbeat:pgsqlms \
bindir=/usr/lib/postgresql/13/bin \
pgdata=/var/lib/postgresql/13/data \
pghost=/var/run/postgresql \
op start timeout=60s \
op stop timeout=60s \
op promote timeout=30s \
op demote timeout=120s \
op monitor interval=15s timeout=10s role="Master" \
op monitor interval=16s timeout=10s role="Slave" \
op notify timeout=60s \
promotable notify=true
Здесь:
- bindir - папка с бинарниками PostgreSQL (нужен pg_ctl),
- pgdata - PGDATA,
- pghost - папка, где PostgreSQL создаёт unix-сокет (файл с именем .s.PGSQL.5432).
Запрещаем этому ресурсу запускаться на сервере участнике кворума (pgc3):
pcs -f cluster1.xml constraint location pgsqld-clone rule resource-discovery=never score=-INFINITY \#uname eq pgc3
Создаём ресурс виртуального IP:
pcs -f cluster1.xml resource create pgsql-pri-ip ocf:heartbeat:IPaddr2 ip=10.1.1.20 cidr_netmask=24 op monitor interval=10s
Привязываем этот ресурс к предыдущему и задаём порядок запуска ресурсов и их остановки:
pcs -f cluster1.xml constraint colocation add pgsql-pri-ip with master pgsqld-clone INFINITY
pcs -f cluster1.xml constraint order promote pgsqld-clone then start pgsql-pri-ip symmetrical=false kind=Mandatory
pcs -f cluster1.xml constraint order demote pgsqld-clone then stop pgsql-pri-ip symmetrical=false kind=Mandatory
Применяем конфигурацию:
pcs cluster cib-push scope=configuration cluster1.xml
Через несколько секунд будут запущены все ресурсы.
Мониторим командой crm_mon на любой ноде.