Гид по технологиям

Настройка Corosync, Pacemaker и DRBD для Active/Passive PostgreSQL-кластера

12 min read Отказоустойчивость Обновлено 26 Nov 2025
Настройка Corosync/Pacemaker/DRBD для PostgreSQL
Настройка Corosync/Pacemaker/DRBD для PostgreSQL

К чему это руководство

Это руководство объясняет, как настроить и мониторить Active/Passive кластер PostgreSQL с использованием Pacemaker, Corosync (openAIS) и DRBD. Приведены точные команды для двух узлов (node1 и node2), примеры ожидаемого вывода и подробные списки действий для администраторов. Предполагается базовый опыт работы с Linux, сетью и PostgreSQL.

Важно: все команды и конфигурации даны в том виде, в каком их нужно выполнять. Кодовые блоки и примеры логов сохранены оригинальными.

Основные варианты запроса (SEO intent)

  • Настройка Corosync Pacemaker DRBD PostgreSQL
  • Active/Passive кластер PostgreSQL
  • DRBD мультиплексирование и Pacemaker
  • Как настроить кластер PostgreSQL с Corosync

6. Настройка Corosync (openAIS)

Corosync — форк проекта Heartbeat, который хорошо работает вместе с Pacemaker. В этом разделе показано, как подготовить конфигурацию Corosync на двух узлах и как запустить сервис.

Подготовка на node1 — переменные окружения

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

export ais_port=4000
export ais_mcast=226.94.1.1
export ais_addr=ip address show eth0 | grep "inet " | tail -n 1 | awk '{print $4}' | sed s/255/0/

Пояснение: ais_addr должен содержать сетевой адрес подсети, на котором будет слушать кластер. В примерах статьи это 10.0.0.0.

Проверим переменные:

env | grep ais_

Важно: переменная ais_addr должна содержать сетевой адрес подсети кластера (в примере 10.0.0.0).

Создание конфигурации Corosync

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

cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf
sed -i.gres "s/.*mcastaddr:.*/mcastaddr:\ $ais_mcast/g" /etc/corosync/corosync.conf
sed -i.gres "s/.*mcastport:.*/mcastport:\ $ais_port/g" /etc/corosync/corosync.conf
sed -i.gres "s/.*bindnetaddr:.*/bindnetaddr:\ $ais_addr/g" /etc/corosync/corosync.conf

Добавим секцию aisexec и объявим загрузку Pacemaker в конфигурацию:

cat <<-END >>/etc/corosync/corosync.conf
aisexec {
user: root
group: root
}
END
cat <<-END >>/etc/corosync/corosync.conf
service {
# Load the Pacemaker Cluster Resource Manager
name: pacemaker
ver: 0
}
END

Файл /etc/corosync/corosync.conf в результате будет содержать примерно следующее:

compatibility: whitetank

totem {
   version: 2
   secauth: off
   threads: 0
   interface {
       ringnumber: 0
       bindnetaddr: 10.0.0.0
       mcastaddr: 226.94.1.1
       mcastport: 4000
   }
}

logging {
   fileline: off
   to_stderr: yes
   to_logfile: yes
   to_syslog: yes
   logfile: /tmp/corosync.log
   debug: off
   timestamp: on
   logger_subsys {
      subsys: AMF
      debug: off
   }
}

amf {
   mode: disabled
}
aisexec {
   user: root
   group: root
}
service {
   # Load the Pacemaker Cluster Resource Manager
   name: pacemaker
   ver: 0
}     

Примечание: если ваша сеть использует другое имя интерфейса (не eth0), замените ip-выражение соответствующим интерфейсом.

Распространение конфигурации на node2

Скопируйте конфигурационные файлы Corosync с node1 на node2:

scp /etc/corosync/* node2:/etc/corosync/

На обоих узлах создайте директорию для логов кластера:

mkdir /var/log/cluster/

Запуск Corosync

На node1 запустите Corosync:

/etc/init.d/corosync start

Проверим логи на предмет успешного старта:

grep -e "Corosync Cluster Engine" -e "configuration file" /var/log/messages

Пример ожидаемого вывода:

[root@node1 bin]# grep -e “Corosync Cluster Engine” -e “configuration file” /var/log/messages
Apr 7 12:37:21 node1 corosync[23533]: [MAIN ] Corosync Cluster Engine (‘1.2.0’): started and ready to provide service.
Apr 7 12:37:21 node1 corosync[23533]: [MAIN ] Successfully read main configuration file ‘/etc/corosync/corosync.conf’.

Проверка, что Corosync слушает на правильном интерфейсе:

grep TOTEM /var/log/messages

Пример:

[root@node1 bin]# grep TOTEM /var/log/messages
Apr 7 12:37:21 node1 corosync[23533]: [TOTEM ] Initializing transport (UDP/IP).
Apr 7 12:37:21 node1 corosync[23533]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).
Apr 7 12:37:21 node1 corosync[23533]: [TOTEM ] The network interface [10.0.0.191] is now up.
Apr 7 12:37:21 node1 corosync[23533]: [TOTEM ] A processor joined or left the membership and a new membership was formed.

Проверим запуск Pacemaker внутри Corosync:

grep pcmk_startup /var/log/messages

Пример:

[root@node1 bin]# grep pcmk_startup /var/log/messages
Apr 7 12:37:21 node1 corosync[23533]: [pcmk ] info: pcmk_startup: CRM: Initialized
Apr 7 12:37:21 node1 corosync[23533]: [pcmk ] Logging: Initialized pcmk_startup
Apr 7 12:37:21 node1 corosync[23533]: [pcmk ] info: pcmk_startup: Maximum core file size is: 4294967295
Apr 7 12:37:21 node1 corosync[23533]: [pcmk ] info: pcmk_startup: Service: 9
Apr 7 12:37:21 node1 corosync[23533]: [pcmk ] info: pcmk_startup: Local hostname: node1

Проверим процессы Corosync и связанные демоны:

ps axf

Ожидаемый фрагмент вывода:

[root@node1 bin]# ps axf
(should contain something like this)
23533 ? Ssl 0:00 corosync
23539 ? SLs 0:00 _ /usr/lib/heartbeat/stonithd
23540 ? S 0:00 _ /usr/lib/heartbeat/cib
23541 ? S 0:00 _ /usr/lib/heartbeat/lrmd
23542 ? S 0:00 _ /usr/lib/heartbeat/attrd
23543 ? S 0:00 _ /usr/lib/heartbeat/pengine
23544 ? S 0:00 _ /usr/lib/heartbeat/crmd

После успешного старта на node1 запустите Corosync на node2:

/etc/init.d/corosync start

Проверка статуса кластера (можно запускать с любого узла):

crm_mon -1

Пример вывода:

Last updated: Fri Oct 29 17:44:36 2010
Stack: openais
Current DC: node1.clusterbr.int - partition with quorum
Version: 1.0.9-89bd754939df5150de7cd76835f98fe90851b677
2 Nodes configured, 2 expected votes
0 Resources configured.

Online: [ node1.clusterbr.int node2.clusterbr.int ]

Убедитесь, что оба узла в онлайне.

Сделаем автозапуск Corosync при старте системы на уровнях запуска 3 и 5 (оба узла):

chkconfig --level 35 corosync on

7. Настройка Pacemaker

Pacemaker реплицирует конфигурацию кластера между узлами: любые изменения, выполненные на одном узле, применяются ко всему кластеру. Поэтому выполняйте crm-команды только на одном узле в момент времени — не запускайте одну и ту же команду одновременно на двух узлах.

Важные команды управления кластером

  • Проверка конфигурации кластера:
crm_verify -L
  • Показать статус и вернуться в shell:
crm_mon -1
  • Показать конфигурацию кластера:
crm configure show
  • Открыть интерактивную консоль crm (введите quit для выхода):
crm

Настройка Stonith

STONITH (Shoot The Other Node In The Head) — механизм fencing, который жестко отключает проблемный узел (обычно через устройства удалённого питания или управляющие контроллеры). Без корректного fencing вы рискуете появлением split-brain и повреждением данных.

В этой инструкции STONITH будет отключён (для лабораторной среды). Для продакшена рекомендуется настроить корректное оборудование fencing (IPMI, iLO, DRAC и т. п.). См. документацию проекта для вариантов настройки fencing: http://www.clusterlabs.org/doc/crm_fencing.html

Проверим, что crm_verify выдаёт ошибки, связанные с Stonith:

crm_verify -L

Чтобы отключить Stonith (на одном из узлов):

crm configure property stonith-enabled=false

Проверим повторно:

crm_verify -L

Общая конфигурация кластера

Выполните далее команды один раз с любого узла.

Укажем политику при отсутствии кворума — игнорировать (подходит для двухузловой лабораторной конфигурации):

crm configure property no-quorum-policy=ignore

Зададим resource-stickiness, чтобы ресурсы «прилипали» к узлу и не перемещались автоматически при кратковременных проблемах:

crm configure rsc_defaults resource-stickiness=100

Проверим конфигурацию:

crm configure show

Пример части вывода:

[root@node1 ~]# crm configure show
node node1.clusterbr.int
node node2.clusterbr.int
property $id=”cib-bootstrap-options” \
dc-version=”1.0.9-89bd754939df5150de7cd76835f98fe90851b677” \
cluster-infrastructure=”openais” \
expected-quorum-votes=”2” \
stonith-enabled=”false” \
no-quorum-policy=”ignore”
rsc_defaults $id=”rsc-options” \
resource-stickiness=”100”

Конфигурация виртуального IP (DBIP)

Для доступа к PostgreSQL извне нужен плавающий IP. Добавим примитив ресурса IP:

crm configure primitive DBIP ocf:heartbeat:IPaddr2 \
params ip=10.0.0.190 cidr_netmask=24 \
op monitor interval=30s

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

Last updated: Fri Oct 29 17:47:53 2010
Stack: openais
Current DC: node1.clusterbr.int - partition with quorum
Version: 1.0.9-89bd754939df5150de7cd76835f98fe90851b677
2 Nodes configured, 2 expected votes
1 Resources configured.

Online: [ node2.clusterbr.int node1.clusterbr.int ]

DBIP (ocf::heartbeat:IPaddr2): Started node2.clusterbr.int

Статус показывает, на каком узле сейчас запущен ресурс (в примере — node2).

Конфигурация DRBD в кластере

Добавим DRBD-ресурс в конфигурацию Pacemaker:

crm configure primitive drbd_postgres ocf:linbit:drbd \
params drbd_resource="postgres" \
op monitor interval="15s"

Создадим мастер/слейв (Master/Slave) для DRBD, указывая, что одновременно мастер может быть только один:

crm configure ms ms_drbd_postgres drbd_postgres \
meta master-max="1" master-node-max="1" \
clone-max="2" clone-node-max="1" \
notify="true"

Добавим ресурс для монтирования устройства DRBD в файловую систему:

crm configure primitive postgres_fs ocf:heartbeat:Filesystem \
params device="/dev/drbd0" directory="/var/lib/pgsql" fstype="ext3"

Конфигурация PostgreSQL как ресурса кластера

Добавим ресурс PostgreSQL (OCF-скрипт pgsql):

crm configure primitive postgresql ocf:heartbeat:pgsql \
op monitor depth="0" timeout="30" interval="30"

Теперь создадим группу, в которую войдут виртуальный IP, файловая система и сам PostgreSQL. Имя группы — postgres:

crm configure group postgres postgres_fs DBIP postgresql

Создадим колокацию, чтобы группа запускалась вместе с DRBD на узле, который является Primary для DRBD:

crm configure colocation postgres_on_drbd inf: postgres ms_drbd_postgres:Master

Укажем порядок запуска — сначала DRBD должно перейти в промоцию (Master), потом запустится postgres:

crm configure order postgres_after_drbd inf: ms_drbd_postgres:promote postgres:start

Проверим финальную конфигурацию:

crm configure show

Пример вывода (основные строки):

primitive DBIP ocf:heartbeat:IPaddr2
params ip=”10.0.0.190” cidr_netmask=”24”
op monitor interval=”30s”
primitive drbd_postgres ocf:linbit:drbd
params drbd_resource=”postgres”
op monitor interval=”15s”
primitive postgres_fs ocf:heartbeat:Filesystem
params device=”/dev/drbd0” directory=”/var/lib/pgsql” fstype=”ext3”
primitive postgresql ocf:heartbeat:pgsql
op monitor interval=”30” timeout=”30” depth=”0”
meta target-role=”Started”
group postgres postgres_fs DBIP postgresql
meta target-role=”Started”
ms ms_drbd_postgres drbd_postgres
meta master-max=”1” master-node-max=”1” clone-max=”2” clone-node-max=”1” notify=”true”
colocation postgres_on_drbd inf: postgres ms_drbd_postgres:Master
order postgres_after_drbd inf: ms_drbd_postgres:promote postgres:start

Назначение предпочтительного узла

Чтобы задать предпочтение для запуска служб на node1, используйте:

crm configure location master-prefer-node1 DBIP 50: node1.clusterbr.int

Пояснение: вес 50 устанавливает предпочтение, но из-за resource-stickiness=100 Pacemaker не будет перемещать ресурс обратно автоматически, если он работает на другом узле. Это помогает избежать «флаппинга» сервисов и проблем с синхронизацией после кратковременных перебоев.

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

crm_mon -1

Пример (все ресурсы запущены на node2):

Last updated: Fri Oct 29 19:54:09 2010
Stack: openais
Current DC: node2.clusterbr.int - partition with quorum
Version: 1.0.9-89bd754939df5150de7cd76835f98fe90851b677
2 Nodes configured, 2 expected votes
2 Resources configured.

Online: [ node2.clusterbr.int node1.clusterbr.int ]

Master/Slave Set: ms_drbd_postgres
Masters: [ node2.clusterbr.int ]
Slaves: [ node1.clusterbr.int ]
Resource Group: postgres
postgres_fs (ocf::heartbeat:Filesystem): Started node2.clusterbr.int
DBIP (ocf::heartbeat:IPaddr2): Started node2.clusterbr.int
postgresql (ocf::heartbeat:pgsql): Started node2.clusterbr.int

Если при проверке статуса появляются ошибки, иногда помогает корректная перезагрузка обоих узлов, чтобы Corosync полностью согласовал конфигурацию. После перезагрузки можно подключиться к DBIP (10.0.0.190) на порт TCP 5432 и проверить работу PostgreSQL.

Тестирование: выключите один узел (poweroff) или остановите corosync на нём и убедитесь, что ресурсы перезапустились на другом узле.

Управление кластером — полезные команды

  • Миграция ресурса на конкретный узел:
crm resource migrate postgres node1.clusterbr.int
  • Отмена миграции:
crm resource unmigrate postgres
  • Очистка ошибок ресурса:
crm resource cleanup postgres
  • Остановка ресурса postgres:
crm resource stop postgresql
  • Запуск ресурса postgres:
crm resource start postgresql

Дополнения и практическая информация (value add)

Ниже — дополнительные полезные разделы: чек-листы, план действий при сбое, тест-кейсы, матрица рисков, рекомендации по безопасности и совместимости.

Факт-бокс — ключевые параметры

  • Multicast порт Corosync: 4000
  • Multicast адрес: 226.94.1.1
  • Виртуальный IP (пример): 10.0.0.190/24
  • Интервалы мониторинга: DBIP 30s, DRBD 15s, PostgreSQL 30s
  • Resource-stickiness: 100
  • no-quorum-policy: ignore (для 2-нодовой лаборатории)
  • STONITH: отключён (не рекомендуется для продакшена)

Мини‑методология: порядок действий при развертывании

  1. Подготовьте сеть (уточните интерфейсы, multicast разрешён).
  2. Настройте DRBD-ресурс и убедитесь в синхронизации дисков вне Pacemaker (локально).
  3. Настройте Corosync на node1, затем скопируйте конфиг на node2.
  4. Запустите Corosync на node1, затем на node2, проверьте membership.
  5. Настройте Pacemaker: stonith, общие свойства, виртуальный IP, DRBD, FS, postgres.
  6. Протестируйте failover и откат, проверьте целостность данных.

Playbook / SOP для развёртывания (короткий чек‑лист)

Роль: системный администратор

  • Актуализировать пакеты Corosync, Pacemaker, DRBD, OCF-скрипты.
  • Проверить сетевые настройки (multicast, firewall, MTU).
  • Выполнить подготовку переменных ais_port, ais_mcast, ais_addr.
  • Скопировать и отредактировать /etc/corosync/corosync.conf.
  • Синхронизировать файл /etc/corosync/* на все узлы.
  • Создать /var/log/cluster/ на всех узлах.
  • Запустить Corosync на node1, проверить логи и ps.
  • Запустить Corosync на node2 и проверить crm_mon.
  • Настроить Pacemaker (stonith, no-quorum-policy, rsc_defaults).
  • Добавить DBIP, drbd_postgres, postgres_fs, postgresql и сгруппировать их.
  • Тестировать: остановка узла, сетевая деградация, восстановление.
  • Документировать результаты тестов и план отката.

Runbook при отказе (быстрые шаги)

Сценарий: основной узел внезапно упал, но кластер не перевёл ресурсы

  1. Проверить статус Corosync и Pacemaker на оставшемся узле:
    • crm_mon -1
    • crm_verify -L
  2. Если Corosync видит только один узел и нет кворума, проверить no-quorum-policy.
  3. Если ресурс не стартовал автоматически — попытаться промотировать DRBD и запустить группу:
    • crm resource migrate postgres node2.clusterbr.int
    • crm resource start postgresql
  4. Если есть split-brain для DRBD — выполнить ручную проверку состояния DRBD и синхронизацию (drbdadm / drbd-overview).
  5. При повреждении сервиса PostgreSQL — проверить логи PostgreSQL, fsck (если нужно), и выполнить восстановление из реплики или backup.

Критерии приёмки

  • Оба узла видны в crm_mon и имеют корректную роль.
  • Виртуальный IP (DBIP) доступен на ожидаемом узле.
  • DRBD синхронизирован (Primary/Secondary по ожиданиям).
  • PostgreSQL запускается через OCF-скрипт и доступен по DBIP:5432.
  • При отключении одного узла ресурсы корректно переносятся на второй узел.

Тест-кейсы / Acceptance tests

  1. Отключение network-интерфейса на node1: ресурсы должны перейти на node2 за время, близкое к сумме таймаутов мониторинга.
  2. Выключение node2: ресурсы должны перенестись на node1.
  3. Возврат node2 в сеть: ресурсы не должны мигрировать автоматически обратно из-за resource-stickiness.
  4. Split-brain DRBD: симулировать рассинхронизацию и проверить корректность обнаружения и ручной процедуры восстановления.
  5. Проверка восстановления после перезагрузки: оба узла поднимаются, кластер стабилен.

Матрица рисков и меры снижения

  • Риск: отсутствие fencing → возможен split-brain и повреждение данных.
    Митигирование: настроить STONITH через IPMI/управляемый PDU в продакшене.
  • Риск: сетевой флаппинг между узлами → постоянные переводы ресурсов.
    Митигирование: увеличить resource-stickiness, настроить сетевая устойчивость и мониторинг.
  • Риск: ненадёжные проверки здоровья PostgreSQL (слишком буквальные OCF-скрипты).
    Митигирование: тестировать сценарии, доработать OCF-скрипт, добавить более глубокие проверки (pg_isready, тестовые запросы).

Безопасность и GDPR-заметки

  • Доступ к управляющему интерфейсу кластера (crm, hb) должен быть ограничен по сети и пользователям.
  • Логи кластера содержат информацию о состоянии и IP-адресах — храните и архивируйте с учетом корпоративной политики хранения логов.
  • Если в кластере хранятся персональные данные, настройте шифрование дисков и корректные бэкапы соответствующие требованиям GDPR/локального законодательства.

Совместимость и примечания по версиям

В примерах логов показаны версии: Corosync 1.2.0 и Pacemaker/CRM 1.0.9. Новые версии Corosync/Pacemaker имеют отличия в конфигурации и командах (systemd unit-файлы вместо /etc/init.d/, изменения в синтаксисе конфигов). Перед применением проверьте совместимость OCF-скриптов (linbit/drbd, heartbeat/Filesystem, pgsql) с вашей версией Pacemaker.

Если вы мигрируете с более старых релизов (Heartbeat → Corosync), выполните тестовую миграцию и проверьте все OCF-ресурсы.

Рекомендации по резервному копированию и тестам отката

  • Делайте регулярные полные бэкапы PostgreSQL (pg_basebackup, WAL-архивация).
  • Тестируйте восстановление на отдельной тестовой среде.
  • Документируйте процедуру ручного recovery при повреждении данных и поддерживайте список контактных лиц.

Чек-лист после развёртывания (быстрая проверка)

  • Corosync запущен на обоих узлах
  • Узлы видят друг друга в crm_mon
  • DBIP отвечает на порту 5432
  • DRBD в состоянии синхронизации
  • PostgreSQL доступен и отвечает на простые запросы
  • STONITH настроен для продакшена или прокомментирован причину отключения

Глоссарий — 1‑строчные определения

  • Corosync: коммуникационный слой и менеджер членства кластера.
  • Pacemaker: менеджер ресурсов кластера (CRM).
  • DRBD: блочное зеркало по сети (disk replication block device).
  • STONITH: механизм fencing для изолирования проблемного узла.
  • OCF: Open Cluster Framework — стандарт для сценариев запуска ресурсов.

Советы по отладке (полезные команды)

  • Просмотр текущего состояния ресурсов: crm_mon -1
  • Проверка конфигурации на ошибки: crm_verify -L
  • Просмотр лога corosync: tail -n 200 /var/log/messages | grep corosync
  • Просмотр логов pacemaker/pengine: /var/log/messages (grep pcmk)
  • Проверка статуса DRBD: cat /proc/drbd или drbdadm status

Когда этот подход не подходит (контрпримеры)

  • Нужна множественная геораспределённая репликация с автоматическим failover и минимальными задержками для чтения/записи — лучше рассмотреть архитектуры с несколькими мастерами или репликацию на уровне PostgreSQL (logical replication, Patroni, BDR).
  • Если нельзя отключать STONITH или нет возможности физически управлять питанием — данный пример с отключением STONITH не подходит для продакшена.

Короткое резюме

  • Настройка Corosync + Pacemaker + DRBD позволяет сделать Active/Passive PostgreSQL-кластер с плавающим IP.
  • Важные параметры: multicast, bindnetaddr, intervals мониторинга, resource-stickiness и stonith.
  • Обязательно протестируйте отказоустойчивость и процедуры восстановления до ввода в продакшн.

Важно: перед развёртыванием в реальном окружении настройте STONITH, протестируйте сетевую устойчивость и выполните резервные копии данных.


Дополнительные материалы и ссылки:

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Изменение цвета окон в Windows 8
Windows

Изменение цвета окон в Windows 8

Как исправить ошибку dxgmms2.sys в Windows 11
Windows 11

Как исправить ошибку dxgmms2.sys в Windows 11

Проекты в ChatGPT — организация чатов
Руководство

Проекты в ChatGPT — организация чатов

Защита от сталкеров в Facebook
Приватность

Защита от сталкеров в Facebook

Как задать пользовательские значки на Android
Android.

Как задать пользовательские значки на Android

Поделиться доступом к камерам Netgear Arlo
Умный дом

Поделиться доступом к камерам Netgear Arlo