Pacemaker/Corosync/Heartbeat

Thank you for reading this post, don't forget to subscribe!

Pacemaker про­грамм­ное обес­пе­че­ния для настрой­ки отка­зо­устой­чи­вых систем. Напри­мер, с его помо­щью мож­но настро­ить кла­стер сер­ве­ров высо­кой доступности

Corosync про­грамм­ный про­дукт, поз­во­ля­ю­щий реа­ли­зо­вать кла­стер сер­ве­ров. Его основ­ное назна­че­ние — знать и пере­да­вать состо­я­ние всех участ­ни­ков кластера.

Heartbeat спе­ци­аль­ный сиг­нал, кото­рый гово­рит о рабо­то­спо­соб­но­сти про­грамм­но­го обес­пе­че­ния или аппарт­ной плат­фор­мы. Отсут­ствие дан­но­го сиг­на­ла может сви­де­тель­ство­вать о нали­чие про­блем. Тер­мин heartbeat пере­во­дить­ся как «серд­це­би­е­ние».

Corosync — про­грамм­ный про­дукт, кото­рый поз­во­ля­ет созда­вать еди­ный кла­стер из несколь­ких аппа­рат­ных или вир­ту­аль­ных сер­ве­ров. Corosync отсле­жи­ва­ет и пере­да­ет состо­я­ние всех участ­ни­ков (нод) в кластере.

Этот про­дукт позволяет:

  • мони­то­рить ста­тус приложений;
  • опо­ве­щать при­ло­же­ния о смене актив­ной ноды в кластере;
  • отправ­лять иден­тич­ные сооб­ще­ния про­цес­сам на всех нодах;
  • предо­став­лять доступ к общей базе дан­ных с кон­фи­гу­ра­ци­ей и статистикой;
  • отправ­лять уве­дом­ле­ния об изме­не­ни­ях, про­из­ве­ден­ных в базе.

Pacemaker — мене­джер ресур­сов кла­сте­ра. Он поз­во­ля­ет исполь­зо­вать служ­бы и объ­ек­ты в рам­ках одно­го кла­сте­ра из двух или более нод. Вот вкрат­це его достоинства:

  • поз­во­ля­ет нахо­дить и устра­нять сбои на уровне нод и служб;
  • не зави­сит от под­си­сте­мы хра­не­ния: можем забыть общий нако­пи­тель, как страш­ный сон;
  • не зави­сит от типов ресур­сов: все, что мож­но про­пи­сать в скрип­ты, мож­но кластеризовать;
  • под­дер­жи­ва­ет STONITH (Shoot-The-Other-Node-In-The-Head), то есть умер­шая нода изо­ли­ру­ет­ся и запро­сы к ней не посту­па­ют, пока нода не отпра­вит сооб­ще­ние о том, что она сно­ва в рабо­чем состоянии;
  • под­дер­жи­ва­ет кво­рум­ные и ресур­со­за­ви­си­мые кла­сте­ры любо­го размера;
  • под­дер­жи­ва­ет прак­ти­че­ски любую избы­точ­ную конфигурацию;
  • может авто­ма­ти­че­ски реп­ли­ци­ро­вать кон­фиг на все узлы кла­сте­ра — не при­дет­ся пра­вить все вручную;
  • мож­но задать поря­док запус­ка ресур­сов, а так­же их сов­ме­сти­мость на одном узле;
  • под­дер­жи­ва­ет рас­ши­рен­ные типы ресур­сов: кло­ны (когда ресурс запу­щен на мно­же­стве узлов) и допол­ни­тель­ные состо­я­ния (master/slave и подоб­ное) — акту­аль­но для СУБД (MySQL, MariaDB, PostgreSQL, Oracle);
  • име­ет еди­ную кла­стер­ную обо­лоч­ку CRM с под­держ­кой скриптов.

Идея заклю­ча­ет­ся в том, что с помо­щью Corosync мы постро­им кла­стер, а сле­дить за его состо­я­ни­ем будем с помо­щью Pacemaker.

 

Установка

Созда­дим или откро­ем файл с опи­са­ни­ем репозиториев

# vi /etc/yum.repos.d/centos.repo

и доба­вим в него следующее:

[centos-7-base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
enabled=1

После нуж­но обно­вить спи­сок пакетов

yum update -y

Теперь мож­но уста­нав­ли­вать Pacemaker и свя­зан­ные с его рабо­той компоненты

yum install -y python3-devel ruby-devel gcc libffi-devel libffi-dev fontconfig coreutils rubygems gcc-c++ wget

yum install -y pacemaker pcs resource-agents corosync

Про­ве­ря­ем поль­зо­ва­те­ля hacluster (Pacemaker) и меня­ем пароль:

hacluster:x:189:189:cluster user:/home/hacluster:/sbin/nologin

Зада­дим пароль для учет­ной запи­си hacluster (она была созда­на авто­ма­ти­че­ски при уста­нов­ке Pacemaker)

passwd hacluster

Раз­ре­шим авто­ма­ти­че­ский запуск сервиса

# systemctl enable pcsd

И запу­стим его

systemctl start pcsd

Pacemaker уста­нов­лен и готов к настройке.

Про­ве­рить состо­я­ние pacemaker командой:

systemctl status pcsd

Посмот­реть состо­я­ние кластера:

pcs status

 

Настраиваем время.

Необ­хо­ди­мо, что­бы на всех нодах было оди­на­ко­вое время.

Уста­нав­ли­ва­ем ути­ли­ту для син­хро­ни­за­ции даты и времени:

yum install ntpdate

Настра­и­ва­ем син­хро­ни­за­цию по расписанию:

crontab -e

0 0 * * * /usr/sbin/ntpdate ru.pool.ntp.org

Выстав­ля­ем нуж­ный часо­вой пояс:

cp /usr/share/zoneinfo/Asia/Bishkek /etc/localtime

Син­хро­ни­зи­ру­ем время:

ntpdate ru.pool.ntp.org

 

Добав­ля­ем в hosts наши ноды
cat /etc/hosts
192.168.1.170 node1
192.168.1.172 node2

 

авто­ри­зо­вы­ва­ем­ся на сер­ве­рах сле­ду­ю­щей командой

pcs cluster auth node1 node2 -u hacluster
Password:
node1: Authorized
node2: Authorized

 где node1 и node2 — име­на сер­ве­ров, hacluster — слу­жеб­ная учет­ная запись (созда­на авто­ма­ти­че­ски при уста­нов­ке пакетов).

 

Созда­ем кластер:

pcs cluster setup --force --name NLB node1 node2

* где NLB — назва­ние для кла­сте­ра; node1 и node2 — сер­ве­ры, кото­рые долж­ны вхо­дить в кластер.

После успеш­но­го выпол­не­ния коман­ды мы уви­дим, при­мер­но, следующее:

pcs cluster setup --force --name NLB node1 node2
Destroying cluster on nodes: node1, node2…
node1: Stopping Cluster (pacemaker)…
node2: Stopping Cluster (pacemaker)…
node2: Successfully destroyed cluster
node1: Successfully destroyed cluster

Sending 'pacemaker_remote authkey' to 'node1', 'node2'
node1: successful distribution of the file 'pacemaker_remote authkey'
node2: successful distribution of the file 'pacemaker_remote authkey'
Sending cluster config files to the nodes…
node1: Succeeded
node2: Succeeded

Synchronizing pcsd certificates on nodes node1, node2…
node1: Success
node2: Success
Restarting pcsd on the nodes in order to reload the certificates…
node1: Success
node2: Success

* так­же, будет создан кон­фи­гу­ра­ци­он­ный файл /etc/corosync/corosync.conf.

 

Раз­ре­ша­ем авто­за­пуск и запус­ка­ем создан­ный кластер:

pcs cluster enable --all

pcs cluster start --all

pcs cluster enable --all
node1: Cluster Enabled
node2: Cluster Enabled
pcs cluster start --all
node1: Starting Cluster (corosync)…
node2: Starting Cluster (corosync)…
node1: Starting Cluster (pacemaker)…
node2: Starting Cluster (pacemaker)…

 опция --all гово­рит, что необ­хо­ди­мо выпол­нить коман­ду для всех нод, к кото­рым мы под­клю­чи­лись (вме­сто этой опции мож­но пере­чис­лить ноды вручную).

 

При исполь­зо­ва­нии двух нод вклю­ча­ем stonith. Он нужен для «доби­ва­ния» сер­ве­ров, кото­рые не смог­ли пол­но­стью завер­шить рабо­чие про­цес­сы. Игно­ри­ру­ем кворум.

pcs property set stonith-enabled=true

pcs property set no-quorum-policy=ignore

Про­смот­реть состо­я­ние мож­но командой:

pcs status

вывод будет следующим:

pcs status
Cluster name: NLB

WARNINGS:
No stonith devices and stonith-enabled is not false

Stack: corosync
Current DC: node2 (version 1.1.19-8.el7_6.4-c3c624ea3d) - partition with quorum
Last updated: Sun Apr 28 18:22:47 2019
Last change: Sun Apr 28 18:22:19 2019 by root via cibadmin on node1

2 nodes configured
0 resources configured

Online: [ node1 node2 ]

No resources

Daemon Status:
corosync: active/enabled
pacemaker: active/enabled
pcsd: active/enabled

 

Настройка виртуального IP

Рас­смот­рим самый рас­про­стра­нен­ный вари­ант исполь­зо­ва­ния Pacemaker. Он заклю­ча­ет­ся в исполь­зо­ва­нии вир­ту­аль­но­го IP-адре­са, кото­рый будет назна­чать­ся актив­но­му узлу кластера.

Для это­го созда­ем ресурс командой:

pcs resource create virtual_ip ocf:heartbeat:IPaddr2 ip=192.168.1.180 cidr_netmask=24 op monitor interval=30s

* где virtual_ip — назва­ние ресур­са (может быть любым);192.168.1.180 — вир­ту­аль­ный IP, кото­рый будет назна­чен кла­сте­ру; 24 — пре­фикс сети (соот­вет­ству­ет мас­ке 255.255.255.0); 30s — кри­ти­че­ское вре­мя про­стоя, кото­рое будет озна­чать недо­ступ­ность узла.

 

pcs status resources
virtual_ip (ocf::heartbeat:IPaddr2): Stopped

pcs status
Cluster name: NLB

WARNINGS:
No stonith devices and stonith-enabled is not false

Stack: corosync
Current DC: node2 (version 1.1.19-8.el7_6.4-c3c624ea3d) - partition with quorum
Last updated: Sun Apr 28 19:41:33 2019
Last change: Sun Apr 28 19:39:55 2019 by root via cibadmin on node1

2 nodes configured
1 resource configured

Online: [ node1 node2 ]

Full list of resources:

virtual_ip (ocf::heartbeat:IPaddr2): Stopped

Daemon Status:
corosync: active/enabled
pacemaker: active/enabled
pcsd: active/enabled

 

Что­бы уда­лить ресурс исполь­зу­ем команду:

pcs resource delete

Запу­стить ресурс и вер­нуть в обыч­ное состояние:

pcs resource enable resource_id

Уда­лить ресурс:

pcs resource delete virtual_ip

 

Ста­тус по ресурсам:

pcs resource show --full

Чтобы удалить ноду из кластера, воспользуйся командой 
pcs cluster node remove <node_name>.

Если не стар­ту­ет ресурс то запу­стим с дебагом:
pcs resource debug-start virtual_ip

 

про­ве­ря­ем что вир­ту­аль­ный ip появился:
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:9f:d1:3d brd ff:ff:ff:ff:ff:ff
inet 192.168.1.170/24 brd 192.168.1.255 scope global enp0s3
valid_lft forever preferred_lft forever
inet 192.168.1.180/24 brd 192.168.1.255 scope global secondary enp0s3
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe9f:d13d/64 scope link
valid_lft forever preferred_lft forever

Если ста­тус stop
pcs resource show
virtual_ip (ocf::heartbeat:IPaddr2): Stopped

выпол­ня­ем команду:
pcs property set stonith-enabled=false

про­ве­ря­ем:
pcs resource show
virtual_ip (ocf::heartbeat:IPaddr2): Started node1

 

что­бы сми­гри­ро­вать IP адрес выполняем:

pcs resource move virtual_ip node2
pcs status
Cluster name: NLB
Stack: corosync
Current DC: node2 (version 1.1.19-8.el7_6.4-c3c624ea3d) - partition with quorum
Last updated: Sun Apr 28 23:22:57 2019
Last change: Sun Apr 28 23:22:55 2019 by root via crm_resource on node1

2 nodes configured
1 resource configured

Online: [ node1 node2 ]

Full list of resources:

virtual_ip (ocf::heartbeat:IPaddr2): Started node2

Daemon Status:
corosync: active/enabled
pacemaker: active/enabled
pcsd: active/enabled

 

Отказоустойчивость сервисов

Кла­сте­ри­за­ция по вир­ту­аль­но­му IP-адре­су поз­во­лит обес­пе­чить высо­кую доступ­ность на уровне рабо­ты сер­ве­ра. Но если необ­хо­ди­мо более тон­кая настрой­ка, поз­во­ля­ю­щая менять актив­ную ноду при отка­зе служ­бы, выпол­ня­ем дей­ствия, опи­сан­ные ниже.

 

Список всех поддерживаемых сервисов можно посмотреть командой:

crm_resource --list-agents ocf

 

Раз­бе­рем кла­сте­ри­за­цию на базе postfix.

Под­клю­ча­ем­ся к кла­сте­ру и созда­ем сле­ду­ю­щий ресурс:

pcs cluster auth node1 node2 -u hacluster

pcs resource create postfix ocf:heartbeat:postfix op monitor interval=30s timeout=60s

 

Удаление ноды

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

pcs cluster node remove node_name

* где node_name — имя узла, кото­рый хотим удалить.

 

Добавим nginx как ресурс и запрашиваем статус кластера

pcs resource create nginx ocf:heartbeat:nginx op monitor interval=30s timeout=60s

pcs status

Full list of resources:

virtual_ip (ocf::heartbeat:IPaddr2): Started ha-node1
nginx (ocf::heartbeat:nginx): Started ha-node1

Daemon Status:
corosync: active/enabled
pacemaker: active/enabled
pcsd: active/enabled

 

Выклю­ча­ем первую ноду на несколь­ко минут. Запра­ши­ва­ем ста­тус вто­рой ноды, что­бы убе­дить­ся, что пер­вая недоступна.

Full list of resources:

virtual_ip (ocf::heartbeat:IPaddr2): Started node2
nginx (ocf::heartbeat:nginx): Started node2

Daemon Status:
corosync: active/enabled
pacemaker: active/enabled
pcsd: active/enabled

Как толь­ко пер­вая нода будет доступ­на, вруч­ную пере­клю­ча­ем на нее вир­ту­аль­ный IP и nginx командой

Оста­лось запро­сить ста­тус кла­сте­ра и убе­дить­ся, что адрес при­сво­ен пер­вой ноде.

virtual_ip (ocf::heartbeat:IPaddr2): Started node1

Спи­сок всех под­дер­жи­ва­е­мых сер­ви­сов мож­но посмот­реть c помо­щью команды

crm_resource --list-agents ocf

 

На обе­их нодах дол­жен быть уста­нов­лен и настро­ен nginx. Под­клю­ча­ем­ся к кла­сте­ру и созда­ем сле­ду­ю­щий ресурс:

Здесь мы созда­ем ресурс из служ­бы, кото­рая будет каж­дые 30 секунд про­ве­рять­ся, и в слу­чае минут­но­го тайм-аута ресурс будет вклю­чен на дру­гой ноде.