Автоматическое отслеживание состояния узлов: HAD

На каждом узле кластера устанавливаем HAD штатным для ALT Linux способом:

[root@m1 ~]# apt-get install had

Создаем конфигурационный файл HAD (/etc/had/had.conf), который на узле m1 будет выглядеть так:

ENABLE=yes
DEBUG=no
IP1="192.168.200.1"
NET1="192.168.200.255"
NODES=2
MONITORING=1
TIMEOUT=5

а на m2 "-- так:

ENABLE=yes
DEBUG=no
IP1="192.168.200.2"
NET1="192.168.200.255"
NODES=2
MONITORING=1
TIMEOUT=5

Параметры в конфигурационом файле "-- это переменные shell, используемые стартовым скриптом /etc/init.d/had, который передает их в виде параметров командной строки исполняемому файлу /usr/sbin/had.

HAD отслеживает следующие основные состояния узла кластера:

  1. RUNNING "-- активный узел (всегда один)
  2. STANDBY "-- корректно функционирующий пассивный узел
  3. ERRORED "-- некорректно функционирующий узел
  4. TIMEDOUT "-- узел, связь с которым потеряна

Соответственно, в процессе работы HAD вызывает 3 скрипта:

  1. /etc/had/hasrv/starthasrv "-- при переключении в состояние 1
  2. /etc/had/hasrv/stophasrv "-- при переключении в состояние 3 или при завершении работы HAD
  3. /etc/had/hasrv/monitorhasrv "-- для проверки корректности функционирования кластера

В штатном режиме кластер стартует только в том случае, если достигнут кворум, т.е. стартовали более половины узлов (для двух узлов это 2/2+1=2, для четырех "-- 4/2+1=3 и т.д. "-- впрочем, сейчас нам интересны только двухузловые конфигурации). Чтобы запустить кластер, состоящий из одного узла (это может потребоваться разве что при выходе второго узла из строя и необходимости перезагрузки первого), придется выполнить:

[root@m1 ~]# service had start-force-main

или:

[root@m1 ~]# /usr/sbin/had -m ...

После старта кластера имена узлов сортируются в алфавитном порядке, на каждом вызывается скрипт 3 и выполняются следующие действия:

Эти же действия выполняются далее в процессе работы кластера: например, отказал один из узлов (тогда первый по алфавиту из оставшихся узлов в состоянии 2 перейдет в состояние 1) или была потеряна связь с узлом (и он, оставшись в одиночестве, перешел в состояние 1 "-- при возвращении в кластер он или другой узел будет переведен в состояние 3). Более подробно о состояниях и переходах между ними можно узнать из документации в пакете had.

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

[root@m1 ~]# cat /etc/had/hasrv/starthasrv 
#!/bin/sh -e

drbdadm primary all
mount /dev/drbd0 /d0

[root@m1 ~]# cat /etc/had/hasrv/stophasrv 
#!/bin/sh

umount /dev/drbd0
drbdadm secondary all

[root@m1 ~]# cat /etc/had/hasrv/monitorhasrv 
#!/bin/sh

[ `drbdadm state all | awk -F'/' '{print $1}'` == "Primary" ] && \
grep drbd0 /proc/mounts > /dev/null && \
exit 0
exit 1

Теперь можно запустить HAD на каждом узле:

[root@m1 ~]# service had start

После старта сервиса на ведущем узле кластера в логах можно увидеть такие сообщения:

m1 JETHA[31423]: daemon starting
m1 JETHA[31423]: Waiting for quorum of nodes to come online
m1 had: had startup succeeded
m1 JETHA[31423]: Services not running, cleaning up
m1 JETHA[31423]: Stopping Services (stophasrv)
m1 JETHA[31423]: Startup done, starting main loop [5]
m1 JETHA[31423]: Starting Services (starthasrv)
m1 kernel: drbd0: Secondary/Secondary --> Primary/Secondary
m1 kernel: kjournald starting.  Commit interval 5 seconds
m1 kernel: EXT3 FS on drbd0, internal journal
m1 kernel: EXT3-fs: mounted filesystem with ordered data mode.
m1 JETHA[31423]: ok, we are RUNNING!

В логах ведомого узла можно будет увидеть следующее:

m2 JETHA[27544]: daemon starting
m2 JETHA[27544]: Waiting for quorum of nodes to come online
m2 had: had startup succeeded
m2 JETHA[27544]: Services not running, cleaning up
m2 JETHA[27544]: Stopping Services (stophasrv)
m2 JETHA[27544]: Startup done, starting main loop [5]
m2 kernel: drbd0: Secondary/Secondary --> Secondary/Primary

После старта HAD на обоих узлах кластера устройство /dev/drbd0 будет примонтировано на ведущем узле. Если остановить сервис had на ведущем узле m1 (или выключить узел m1), ведомый m2 возьмет на себя функции ведущего (перейдет в состояние 1), и устройство /dev/drbd0 будет примонтировано на нем, при этом в логах мы увидим:

m2 kernel: drbd0: Secondary/Primary --> Secondary/Secondary
m2 JETHA[27544]: Warning: Node m1.mydomain.com timeout
m2 JETHA[27544]: Starting Services (starthasrv)
m2 kernel: drbd0: Secondary/Secondary --> Primary/Secondary
m2 kernel: kjournald starting.  Commit interval 5 seconds
m2 kernel: EXT3 FS on drbd0, internal journal
m2 kernel: EXT3-fs: mounted filesystem with ordered data mode.
m2 JETHA[27544]: ok, we are RUNNING!

При повторном запуске сервиса had на m1 или при включении узла m1 он не станет ведущим, а перейдет в состояние 2, ведущим останется узел m2.

Текущее состояние узлов можно узнать так:

[root@m1 ~]# service had status
HAD running. Node status:
m1.mydomain.com [Standby]
m2.mydomain.com [Running]



Eugene 2012-05-28