Active/Passive PostgreSQL Cluster

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 11:50, 26 июня 2018.
PostgreSQL
Postgresql.png
Разработчики: сообщество PostgreSQL
Выпущена: 8 июля 1996
Предыдущий выпуск: 10.4 / 10 мая 2018
Состояние разработки: активное
Платформа: кроссплатформенное программное обеспечение
Веб-сайт postgresql.org

Active/Passive PostgreSQL Cluster - отказоустойчивый кластер из нескольких узлов с работающим PostgreSQL сервером, в котором активный в каждый момент времени один, и в случае его отказа в строй вступает один из резервных. Подобное резервирование требует больших избыточных аппаратных средств, однако и надежность соответствующим образом повышается.


Active/Passive

Active / passive — такой тип отказоустойчивого кластера, который имеет полное резервирование (работоспособную копию) каждого узла.

Схема кластера
Резерв включается в работу только тогда, когда отказывает соответствующий основной узел. Эта конфигурация требует значительных избыточных аппаратных средств. В данном случае мы будем резервировать сервер PostgreSQL, а так же, которые данные будут храниться на внешнем накопителе. Его резервирование - отдельная тема. Можно резервировать как дисковым массивом (например RAID 1+0), который обычно имеет 2 контроллера для подключения к каждому серверу, так и отдельными накопителями, на которых настроена репликация. Пример логической репликации.



Утилиты, помогающие с реализацией

Pacemaker

Pacemaker это open-source high availability менеджер ресурсов, который используется в кластерных системах с 2004 года. До 2007 года, был частью проекта Linux-HA, но затем превратился в отдельный проект. Он реализует несколько API для управления ресурсами.

Особенности

  • Обнаружение и восстановление сбоев на уровне узлов и сервисов;
  • Независимость от подсистемы хранения: общий диск не требуется;
  • Независимость от типов ресурсов: все что может быть заскриптовано, может быть кластеризовано;
  • Поддержка STONITH (Shoot-The-Other-Node-In-The-Head) — лекарства от Split-Brain (появление одновременно двух master-узлов)
  • Поддержка кластеров любого размера;
  • Поддержка и кворумных и ресурсозависимых кластеров;
  • Поддержка практически любой избыточной конфигурации;
  • Автоматическая репликация конфига на все узлы кластера;
  • Возможность задания порядка запуска ресурсов, а также их совместимости на одном узле;
  • Поддержка расширенных типов ресурсов: клонов (запущен на множестве узлов) и с дополнительными состояниями (master/slave и т.п.);
  • Единый кластерный шелл (crm), унифицированный, скриптующийся.

Corosync

Corosync (Corosync Cluster Engine) — проект с открытым исходным кодом, реализующий систему группового общения для отказоустойчивых кластеров. Является развитием проекта OpenAIS и опубликован в соответствии с модифицированной лицензией BSD.

Особенности

Проект предоставляет четыре набора API для языка Си:

  • «Закрытая группа процессов» (англ. Closed Process Group — CPG) — модель взаимодействия, реализующая виртуальную синхронизацию, которая гарантирует, что процессы на узлах кластера получат одинаковые сообщения в одинаковом порядке.
  • «Простой менеджер доступности» (англ. Simple Availability Manager — SAM), отслеживающий состояния приложений и позволяющий их перезапускать после сбоя.
  • «База данных конфигурации» (англ. Configuration database — confdb) в оперативной памяти, позволяющая получать конфигурацию и статистику Corosync, менять конфигурацию и получать уведомления об её изменениях.
  • «Кворум» (англ. quorum) — система, оповещающая приложения о том, достигнут кворум (необходимое минимальное количество активных узлов кластера) или нет.

Программное обеспечение предназначено для работы в сетях UDP/IP и InfiniBand. [Источник 1]

Как это работает?

Общий принцип таков:

  • Устанавливаем вышеописанное програмное обеспечение.
  • Общение серверов происходит по протоколу ssh, поэтому надо заранее их подружить, обменяв публичные ключи и положив их в ~/.ssh/authorized_keys. Как сделать это, если есть 2 сервера безо всяких утилит и графической оболочки - будет показано далее.
  • После, назначить один узел основным, второй резервным, авторизовать оба узла в кластере.
  • Назначить общие ресурсы, а так же правила (операции), по которым ресурс будет мигрировать с одного узла на другой.
  • Среди этих ресурсов - общий IP-адрес кластера, а так же хранилище и процесс с PostgreSQL.
  • При исключительной ситуации утилиты переведут выдачу ресурсов с вышедшего из строя узла на функционирующий.

Установка на CentOS

Здесь рассмотрим установку на примере двух виртуальных машин с CentOS 7 в VirtualBox.

Установка необходимых пакетов

Первым делом - установим необходимые пакеты. С точностью до пакетного менеджера дистрибутива (apt, pacman или yum) пишем на каждом узле следующее:

$ yum install -y postgresql-server
$ yum install -y pacemaker pcs psmisc policycoreutils-python

После установки надо запустить инициализацию базы данных:

$ /usr/bin/postgresql-setup initdb

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

$ sudo systemctl start postgresql
$ sudo systemctl enable postgresql
$ sudo systemctl status postgresql

Настройка Cluster Shared Volume

в ВиртуалБоксе добавляем виртуальный жесткий диск для первого узла, в нем он должен отобразится в /dev/sdb Теперь настраиваем LVM:

$ pvcreate /dev/sdb
$ vgcreate shared_vg /dev/sdb
$ lvcreate -l 100%FREE -n ha_lv shared_vg
$ mkfs.ext4 /dev/shared_vg/ha_lv

С целью упрощения демонстрации работы - упустим инициализацию полноценной БД с репликацией, так как это уже рассмотрено в рамках отдельной статьи, здесь же сделаем заглушку на месте базы данных (запускаться она будет, и кластер будет реагировать на ее отказ). На реальных серверах при настройке следует инициализировать базу данных именно здесь.

Монтируем где-нибудь, и добавляем файл postgresql.conf (далее в примере в кластере он будет подмонтирован в /data/postgresql.conf):

$ mount /dev/shared_vg/ha_lv /data
$ cp /var/lib/pgsql/data/postgresql.conf /data/postgresql.conf

Обязательно проставьте права для записи туда процессом postgre, например (вместо 777 выставьте права в зависимости от настройки БД):

$ chmod 777 /data
$ chmod 777 /data/postgresql.conf

Диск готов. Теперь нам необходимо сделать так, что было на диск не применялось правило автомонтирования для LVM, так как pacemaker сам будет это делать при старте кластера. Делается это внесением изменений в файле /etc/lvm/lvm.conf (раздел activation) на обоих хостах:

activation {.....
 
#volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
volume_list = [ "centos",  "@node1" ]
# на втором узле - соответственно [ "centos",  "@node2" ]

Обновляем initrams и перезагружаем узлы:

dracut -H -f /boot/initramfs-$(uname -r).img $(uname -r)
shutdown -h now

Перечисленные выше манипуляции необходимо проделать на обоих узлах.

Настройка кластера

Обмен ключами

Если у вас как в этом примере, свежеустановленная минимальная сборка какого-нибудь дистрибутива, то обменять ключами можно стандартной утилитой, которая часто бывает очень полезна. Имя ей - netcat. Установим:

$ yum install -y nmap-ncat

Чтобы заработал netcat нужно выключить firewall:

$ systemctl stop firewalld
$ systemctl disable firewalld

Далее - надо дать узлам имена. Для этого смотрим их адреса через

$ ip addr

на каждом узле.

И теперь дописываем это в /etc/hosts:

10.1.66.23 node1.local.lan node1
10.1.66.24 node2.local.lan node2

Чтобы проверить, что все прошло хорошо, можно пропинговать второй узел с первого и наоборот:

$ ping node2

Если все сделано правильно, будут приходить ответы.

Теперь непосредственно обмен ключами: Для начала надо их сгенерить:

$ ssh-keygen

Далее передаем публичный ключ (имеет расширение *.pub). Как передать файл от одной машины (А) до другой (В) с помощью netcat? на A:

$ cat file | nc -l -p <port>

на В

$ nc <addr> <port> > file

Полученные ключи допишите на обоих хостах в ~/.ssh/authorized_keys.

Запускаем кластер

Стартуем и включаем службу pcs:

systemctl start pcsd.service
systemctl enable pcsd.service

Для управление кластером нам потребуется специальный пользователь, создаем его на обоих хостах:

$passwd hacluster
Changing password for user hacluster.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

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

[root@node1 ~]$ pcs cluster auth node1 node2
Username: hacluster
Password:
node1: Authorized
node2: Authorized

Далее, стартуем наш кластер и проверяем состояние запуска:

$ pcs cluster setup --force --name pacemaker1 node1 node2
$ pcs cluster start --all
$ pcs status --all

Вывод о состоянии через некоторое время будет примерно таким:

[root@node1 ~]$ pcs status --all
Cluster name: pacemaker1 
WARNING: no stonith devices and stonith-enabled is not false
Last updated: Tue Jun 16 10:11:29 2018
Last change: Tue Jun 16 10:12:47 2018
Stack: corosync
Current DC: node2 (version 1.1.13-10.el7_2.2-44eb2dd) - partition with quorum
2 Nodes configured
0 Resources configured
Online: [ node1 node2 ]
Full list of resources:
PCSD Status:
  node1: Online
  node2: Online
Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled

Настраиваем ресурсы

При запущенном кластере редактируем настройки в соответствии с моделью нашего кластера:

$ pcs property set stonith-enabled=false
$ pcs property set no-quorum-policy=ignore

Теперь, на первом узле настраиваем ресурсы кластера. В их числе - ip, логический том и файловая система, а так же непосредственно сама PostgreSQL. Обратите внимание на синтаксис операций в объявлении последней - так мы задаем что делать на другом узле при каждой из чрезвычайных ситуаций.

[root@node1 ~]$ pcs resource create virtual_ip IPaddr2 ip=192.168.1.75 cidr_netmask=24 --group PGCLUSTER
[root@node1 ~]$ pcs resource create DATA ocf:heartbeat:LVM volgrpname=shared_vg exclusive=true --group PGCLUSTER
[root@node1 ~]$ pcs resource create DATA_FS Filesystem device="/dev/shared_vg/ha_lv" directory="/data" fstype="ext4" force_unmount="true" fast_stop="1" --group PGCLUSTER
[root@node1 ~]$ pcs resource create pgsql pgsql pgctl="/usr/pgsql-9.4/bin/pg_ctl" psql="/usr/pgsql-9.4/bin/psql" pgdata="/data" pgport="5432" pgdba="postgres" node_list="node1 node2" op start   timeout="60s" interval="0s"  on-fail="restart"  op monitor timeout="60s" interval="4s" on-fail="restart" op promote timeout="60s" interval="0s"  on-fail="restart" op demote  timeout="60s" interval="0s"  on-fail="stop"  op stop    timeout="60s" interval="0s"  on-fail="block"  op notify  timeout="60s" interval="0s" --group PGCLUSTER

Теперь проверяем вывод о состоянии:

[root@node1 ~]$ pcs status --all
Cluster name: pacemaker1 
Last updated: Mon Jun 16 14:23:34 2018 Last change: Thu Jun 17 12:51:03 2018 by root via cibadmin on node1
Stack: corosync
Current DC: node1 (version 1.1.13-10.el7_2.2-44eb2dd) - partition with quorum
2 nodes and 4 resources configured
Online: [ node1 node2 ]
Full list of resources:
Resource Group: PGCLUSTER
       DATA (ocf::heartbeat:LVM): Started node1
       DATA_FS (ocf::heartbeat:Filesystem): Started node1
       virtual_ip (ocf::heartbeat:IPaddr2): Started node1
       pgsql (ocf::heartbeat:pgsql): Starting node1
PCSD Status:
  node1: Online
  node2: Online
Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled

Кластер готов к бою! можем прямо выключить первый узел, либо сделать остановку pg_sql:

[root@node1 ~]$ pcs resource debug-stop pgsql

И проверяем статус кластера:

[root@node1 ~]$ pcs status --all
Cluster name: pacemaker1 
Last updated: Mon Jun 16 14:23:34 2018 Last change: Thu Jun 17 12:51:03 2018 by root via cibadmin on node1
Stack: corosync
Current DC: node2 (version 1.1.13-10.el7_2.2-44eb2dd) - partition with quorum
2 nodes and 4 resources configured
Online: [ node1 node2 ]
Full list of resources:
Resource Group: PGCLUSTER
       DATA (ocf::heartbeat:LVM): Started node2
       DATA_FS (ocf::heartbeat:Filesystem): Started node2
       virtual_ip (ocf::heartbeat:IPaddr2): Started node2
       pgsql (ocf::heartbeat:pgsql): Starting node2
Failed Actions:
* pgsql_monitor_4000 on node1 'not running' (7): call=48, status=complete, exitreason='none',
    last-rc-change='Mon Jun 16 14:23:34 2018 ', queued=0ms, exec=0ms
PCSD Status:
  node1: Online
  node2: Online
Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled

Сервис все равно доступен, но уже на втором узле!. [Источник 2]

Видео с установкой и демонстрацией работы

В данном видео подробно показано как настраивать каждый узел, как обменять ключи на них, настройка кластера, а так же демонстрация работы. Для этого на первом узле процессу PostgreSQL не дали право на запись в Shared Volume, затем можно увидеть ошибку на первом узле и последующую миграцию ресурса на второй узел кластера.

Выводы

В современном мире практически любой информационный ресурс, который испытывает рост посещаемости и повышенную нагрузку, сталкивается с проблемой отказа важного оборудования. И пока нет ничего проще и надежнее, чем резервировать важные узлы, например СУБД. Это требует сильных избыточных аппаратных ресурсов, но показатели надежности возрастают многократно. Это обусловлено тем, что вероятность отказа обоих узлов одновременно на порядок ниже, чем вероятность отказа одного из них.

В данном примере было разобрано построение отказоустойчивого (Active/Passive) кластера, главный ресурс которого это сервер PostgreSQL и непосредственно хранилище данных, а синхронизация и правила миграции определялись с помощью Pacemaker и Corosync. На месте ресурсов могут быть не только хранилища и PostgreSQL. Возможны и многие другие реализации различных кластеров. Например, можно аналогично сделать отказоустойчивый кластер с Apache или Nginx, что делает решение гибким. Сама процедура не очень сложная, и с актуальной (на момент написания) версией PostgreSQL работает исправно.

Результат проделанной работы можно использовать для построения кластеров иного типа (в которых будет более двух узлов), предварительно определив правила миграции ресурсов.

Источники

  1. Quick start // ClusterLabs: Open Source High Availability Cluster Stack. URL: http://clusterlabs.org/quickstart.html (дата обращения: 10.06.2018)
  2. Active/Passive PostgreSQL cluster // Хабр: крупнейшее сообщество IT-специалистов в рунете. URL: https://habr.com/post/280872/ (дата обращения: 10.06.2018)