Отказоустойчивый кластер на базе OpenVZ, DRBD и Heartbeat 2
Совместное применение технологий Linux Heartbeat, DRBD и OpenVZ позволяет создавать удобные в эксплуатации решения, обеспечивающие повышенную надёжность функционирования важных для пользователей сервисов. Несмотря на доступность большого количества материалов по технологиям построения отказоустойчивых решений на базе ОС Linux, автору данной статьи не удалось отыскать полного и исчерпывающего описания процесса создания системы, основанной на сочетании использования перечисленных выше технологий. Данная статья описывает результаты практической апробации отказоустойчивого решения, осуществляющего автоматическую миграцию виртуальных окружений OpenVZ на резервный узел кластера при нарушении функционирования основного узла.
Рассматриваем пример развёртывания приложения, использующего базу данных (PostgreSQL) и развёртываемого на базе сервера приложений (Tomcat). В качестве базовой операционной системы используем Debian GNU/Linux 5.0 (Lenny).
Предполагаем, что приложение не поддерживает кластерный режим работы (не может функционировать одновременно на нескольких узлах). Для обеспечения отказоустойчивого функционирования используем два идентичных сервера, на одном из которых в нормальном режиме функционируют необходимые базы данных, на другом - сервер приложений. Взаимодействие между базами данных и приложениями осуществляется через сеть TCP/IP.
Для установки сервера СУБД и сервера приложений создаем отдельные виртуальные OpenVZ-окружения. Конфигурация виртуальных окружений и физических серверов подбирается таким образом, чтобы на одном физическом сервере при необходимости могли одновременно функционировать как сервер СУБД, так и сервер приложений (возможно, со сниженной производительностью).
Для обеспечения функционирования OpenVZ при использовании 32-битной версии Debian GNU/Linux физические сервера должны поддерживать технологию PAE (Physical Address Extension). Если вместо физических серверов используются виртуальные машины VirtualBox, требуется включить соответствующий режим в настройках виртуальной машины.
Для синхронизации данных, хранящихся на физических серверах, используем DRBD в режиме master-slave. На физических серверах создаем два DRBD-раздела (один для сервера приложений, другой для сервера СУБД), причём в нормальном режиме функционирования на каждом из серверов в режиме master находится только один из DRBD-разделов.
Для контроля доступности серверов кластера и переключения на резервный узел при отказе основного узла используем Heartbeat. Создаваемый в результате кластер обеспечивает автоматическую миграцию ресурсов с вышедшего из строя узла кластера на оставшийся работоспособным узел. Поскольку ни используемая СУБД, ни приложения не поддерживают кластерный режим работы, неизбежно возникает приостановка предоставления сервисов на период миграции ресурсов с остановленного узла кластера на работающий. Продолжительность периода приостановки сервисов зависит от времени запуска мигрируемых сервисов после сбоя, из практических соображений в нашем примере получается, что этот период будет менее 1 минуты.
1.Работа с инсталлятором системы Debian/GNU Linux 5.0, в частности, с модулем разметки дисков. Умение установить и настроить базовую систему.
2.Установка и удаление пакетов Debian с использованием программы aptitude. Настройка исходных репозиториев для установки и обновления программ (/etc/apt/sources).
3.Понимание принципов работы LVM, навыки настройки и применения LVM (http://tldp.org/HOWTO/LVM-HOWTO/).
4.Понимание принципов работы OpenVZ (http://www.openvz.org/). Навыки настройки окружений OpenVZ и работы с ними.
5.Общее понимание принципов организации отказоустойчивых кластеров (контроль доступности, синхронизация данных, миграция ресурсов, потеря синхронизации - “brain split”).
6.Понимание принципов работы DRBD 8 (http://www.drbd.org/).
7.Понимание принципов работы Heartbeat 2 (http://linux-ha.org/wiki/Heartbeat).
Для установки базовой системы может использоваться дистрибутивный комплект Debian GNU/Linux 5.0. При установке для удобства дальнейшей работы выполним русификацию системы, а вот от установки группы пакетов “Стандартная система” откажемся - большая часть пакетов из этой группы нам не понадобится.
Установку системы на обоих узлах выполняем идентичным образом, различаются только имя узла и сетевые настройки. В данном примере использовались параметры, приведённые в таблице.
Параметр Узел 1 Узел 2 Имя узла deimos phobos IP-адрес 192.168.5.101 192.168.5.102
Для разметки дисков используем комбинацию обычных разделов и LVM. Для корневой файловой системы (совмещённой с файловой системой /boot) создаем обычный раздел №1 размером 4 Гбайт (этого более, чем достаточно для размещения необходимых компонентов), всё остальное пространство выделяем в раздел 2 и создаем на нем физический том LVM. Здесь предполагается, что к серверам подключено по одному диску (тому дискового массива), в случае наличия нескольких устройств следует особым образом спланировать порядок их использования.
На основе созданного физического тома LVM создаем группу логических томов, в которой создаем том подкачки (размер зависит от размера оперативной памяти) и том для файловой системы /var (объёмом 2 Гбайт).
Для корневой файловой системы и файловой системы /var используем файловую систему ext3, так как на нее меньше всего нареканий по части восстановления в аварийных ситуациях.
После завершения установки необходимо убедиться в наличии связи между узлами кластера с помощью команды ping. Для обеспечения доступа к узлам кластера по именам рекомендуется прописать соответствие адресов именам в файле /etc/hosts.
Вместо установленной по умолчанию версии ядра необходимо установить ядро с поддержкой OpenVZ:
aptitude install linux-image-2.6-openvz-686 aptitude remove linux-image-2.6-686
Также необходимо установить модули DRBD8 и соответствующие управляющие программы:
aptitude install drbd8-modules-2.6-openvz-686 drbd8-utils
Установка Heartbeat 2:
aptitude install heartbeat-2
Для удобства работы устанавливаем mc, less, atop и ssh:
aptitude install mc atop ssh
На каждом узле будущего кластера необходимо создать по два тома: один для базы данных, другой - для сервера приложений.
Размер томов следует выбирать исходя из планируемых потребностей базы данных и сервера приложений. В дальнейшем при необходимости можно будет расширить соответствующие тома. Поскольку заранее точно предсказать требуемое пространство (и его соотношение между потребителями) достаточно сложно, предпочтительно оставить в группе томов LVM достаточный объём свободного пространства, а виртуальным окружениям выделить тот объём, который будет необходим в ближайшее время.
Пример команд создания томов LVM:
lvcreate -L 8G -n db VGroup00 lvcreate -L 4G -n apps VGroup00
Далее необходимо создать конфигурационный файл /etc/drbd.conf, определяющий состав дисковых ресурсов DRBD. Пример конфигурационного файла drbd.conf:
global { usage-count no; }
common { handlers { pri-on-incon-degr "echo o > /proc/sysrq-trigger ; halt -f"; pri-lost-after-sb "echo o > /proc/sysrq-trigger ; halt -f"; local-io-error "echo o > /proc/sysrq-trigger ; halt -f"; outdate-peer "/usr/lib/heartbeat/drbd-peer-outdater -t 5"; # pri-lost "echo pri-lost. Have a look at the log files. | mail -s 'DRBD Alert' root"; # split-brain "echo split-brain. drbdadm -- --discard-my-data connect $DRBD_RESOURCE ? | mail -s 'DRBD Alert' root"; }
startup { # wfc-timeout 0; degr-wfc-timeout 120; # 2 minutes. # wait-after-sb; }
disk { on-io-error detach; no-disk-flushes; no-md-flushes; }
syncer { rate 30M; al-extents 257; }
net { sndbuf-size 512k;
timeout 60; # 6 seconds (unit = 0.1 seconds) connect-int 10; # 10 seconds (unit = 1 second) ping-int 10; # 10 seconds (unit = 1 second) ping-timeout 5; # 500 ms (unit = 0.1 seconds)
max-buffers 2048;
cram-hmac-alg "sha1"; shared-secret "DJujhjltepbyfFDRbtddtLzlmrf";
after-sb-0pri discard-younger-primary; after-sb-1pri consensus; after-sb-2pri disconnect; rr-conflict disconnect; } }
resource db {
protocol C;
on deimos { device /dev/drbd0; disk /dev/VGroup00/db; address 192.168.5.101:7788; flexible-meta-disk internal; }
on phobos { device /dev/drbd0; disk /dev/VGroup00/db; address 192.168.5.102:7788; flexible-meta-disk internal; } }
resource apps {
protocol C;
on deimos { device /dev/drbd1; disk /dev/VGroup00/apps; address 192.168.5.101:7789; flexible-meta-disk internal; }
on phobos { device /dev/drbd1; disk /dev/VGroup00/apps; address 192.168.5.102:7789; flexible-meta-disk internal; } }
В приведённом примере: Параметры в секции common наследуются всеми ресурсными секциями. При необходимости для конкретных ресурсов эти параметры можно переопределить.
Настройками определено два DRBD-устройства: /dev/drbd0 и /dev/drbd1, для каждого из которых используются два хранилища: на узле phobos и на узле deimos.
Параметр syncer.rate требуется установить исходя из пропускной способности сетевого интерфейса между узлами. Параметр задается в единицах байт/сек, суффикс M означает умножение на 1 млн.
Параметр common.net.shared-secret требуется установить в значение пароля, используемого для аутентификации взаимодействия между узлами.
Сетевые адреса узлов и номера портов необходимо установить в соответствии с сетевой конфигурацией, соответствующие параметры:
resource(db).on(deimos).address resource(db).on(phobos).address resource(apps).on(deimos).address resource(apps).on(phobos).address
Подготовленный конфигурационный файл /etc/drbd.conf должен быть одинаков на обоих узлах. Передать файл с узла phobos на узел deimos можно командой:
scp /etc/drbd.conf deimos:/etc/drbd.conf
Необходимо убедиться, что DRBD запущен. Для этого используется команда /etc/init.d/drbd status. Если DRBD остановлен, требуется выполнить команду /etc/init.d/drbd start.
После создания и синхронизации конфигурационного файла необходимо выполнить инициализацию томов DRBD выполнением (на каждом узле) следующих команд:
drbdadm create-md db drbdadm create-md apps
После завершения томов необходимо форсировать синхронизацию томов между узлами. Для этого следует выбрать (произвольным образом) один из узлов в качестве основного, и выполнить на нем команды:
drbdsetup /dev/drbd0 primary -o drbdsetup /dev/drbd1 primary -o
Ход синхронизации можно контролировать по содержимому файла /proc/drbd. После завершения синхронизации рекомендуется перезагрузить оба узла и проконтролировать, что запуск DRBD был выполнен автоматически и что состояние томов является синхронным, путём выполнения (после перезагрузки) команды /etc/init.d/drbd status.
Перед созданием виртуальных окружений необходимо принять решение, на каком из физических серверов какое из двух виртуальных окружений должно функционировать в нормальном режиме. Предположим, что сервер баз данных (db) будет функционировать на физическом сервере deimos, а сервер приложений (apps) - на физическом сервере phobos.
Действия по настройке каждого из виртуальных окружений будем выполнять на том физическом сервере, на котором данное окружение будет в дальнейшем преимущественно функционировать. Затем скопируем необходимые настройки на второй сервер.
Первым шагом в создании виртуальных окружений является создание файловых систем, в которых будут размещаться данные этих виртуальных окружений:
1.Создаются каталоги для монтирования файловых систем виртуальных окружений
2.Соответствующей DRBD-устройство переводится в режим “primary”
3.Создается файловая система ext3 на DRBD-устройстве
4.Отключаются автоматические проверки целостности файловой системы при монтировании
5.Выполняется монтирование созданной файловой системы
На сервере deimos выполняем команды:
mkdir /Data mkdir /Data/db mkdir /Data/apps drbdadm primary db mkfs -t ext3 /dev/drbd0 tune2fs -c 0 -i 0 /dev/drbd0 mount /dev/drbd0 /Data/db
На сервере phobos выполняем команды:
mkdir /Data mkdir /Data/db mkdir /Data/apps drbdadm primary apps mkfs -t ext3 /dev/drbd1 tune2fs -c 0 -i 0 /dev/drbd1 mount /dev/drbd1 /Data/apps
Создание виртуальных окружений необходимо выполнять на основе шаблона. Такой шаблон можно подготовить самостоятельно в соответствии с инструкцией (http://wiki.openvz.org/Debian_template_creation), либо использовать готовый.
Для создания виртуальных окружений используются команды:
На сервере deimos
vzctl create 101 --ostemplate debian-5.0-i386-my --ipadd \ 192.168.5.103 --hostname db --private /Data/db/vm
На сервере phobos
vzctl create 102 --ostemplate debian-5.0-i386-my --ipadd \ 192.168.5.104 --hostname apps --private /Data/apps/vm
Необходимо учесть следующие особенности:
1.Виртуальным окружениям необходимо присвоить разные идентификаторы (в нашем примере - 101 и 102), иначе их нельзя будет запустить на одном сервере.
2.IP-адреса и имена хостов виртуальных окружений должны соответствовать используемой сетевой конфигурации.
3.В параметре ostemplate нужно указать имя используемого шаблона виртуальных окружений.
4.Подкаталог 'vm' томов виртуальных окружений не должен существовать на момент выполнения команды vzctl create, иначе команда завершится с ошибкой.
После создания виртуальных окружений необходимо установить для них ресурсные ограничения и проверить формальную корректность выполненных настроек. Величина ресурсных ограничений зависит от доступных аппаратных ресурсов серверов и от потребностей запускаемых приложений. В нашем примере используются следующие команды настройки:
На сервере deimos
vzctl set 101 --numproc 300:300 --kmemsize 32m:40m \ --vmguarpages 512m:unlimited --privvmpages 512m:512m \ --oomguarpages 256m:unlimited --shmpages 256m:256m \ --tcpsndbuf 1m:2m --tcprcvbuf 1m:2m --save
На сервере phobos
vzctl set 102 --numproc 300:300 --kmemsize 32m:40m \ --vmguarpages 512m:unlimited --privvmpages 512m:512m \ --oomguarpages 256m:unlimited --shmpages 256m:256m \ --tcpsndbuf 1m:2m --tcprcvbuf 1m:2m --save
В приведённом примере разрешено запускать до 300 потоков выполнения (параметры numproc и kmemsize), использующих до 512 Мбайт виртуальной памяти (параметры vmguardpages, privvmpages), с гарантией отсутствия вытеснения при нехватке памяти до 256 Мбайт (параметр oomguarpages), и с допустимым использованием разделяемой памяти System V до 256 Мбайт (параметр shmpages). Также установлен увеличенный размер буферов протокола TCP.
Для проверки корректности полученной конфигурации используется программа vzcfgvalidate:
На сервере deimos
vzcfgvalidate /etc/vz/conf/101.conf
На сервере phobos
vzcfgvalidate /etc/vz/conf/102.conf
Необходимо отключить автоматический запуск виртуальных окружений при старте сервера, так как запуск и остановка должны выполняться под управлением системы Heartbeat.
На сервере deimos
vzctl set 101 --onboot no --save
На сервере phobos
vzctl set 102 --onboot no --save
Для запуска и остановки виртуальных окружений вручную используются команды:
На сервере deimos
vzctl start 101 # Запуск vzctl stop 101 # Остановка
На сервере phobos
vzctl start 102 # Запуск vzctl stop 102 # Остановка
ВНИМАНИЕ! Запуск и остановка виртуальных окружений вручную, как и другие операции ручного манипулирования состоянием управляемых Heartbeat ресурсов (включая тома DRBD и созданные на них файловые системы) допускается только тогда, когда службы Heartbeat остановлены на обоих узлах кластера. Или - в нашем текущем примере - ещё не настроены вовсе.
После первоначального запуска созданных виртуальных окружений можно выполнить установку в эти виртуальные окружения прикладного программного обеспечения, а можно и отложить действия по установке до завершения настройки кластера. В нашем примере можно установить сервер СУБД в виртуальное окружение db и сервер приложений в виртуальное окружение apps:
На сервере deimos выполняем команды:
vzctl enter 101 aptitude install postgresql exit
На сервере phobos выполняем команды:
vzctl enter 102 cd /root mkdir DISTRIB cd DISTRIB scp files.sample.com:/distrib/jdk-6u22-linux-i586.bin . scp files.sample.com:/distrib/apache-tomcat-6.0.29.tar.gz . cd /opt sh /root/DISTRIB/jdk-6u22-linux-i586.bin tar xfz /root/DISTRIB/apache-tomcat-6.0.29.tar.gz exit
Описание полного состава действий по настройке СУБД, сервера приложений и самих приложений выходит за рамки данной статьи. Конфигурационные файлы виртуальных окружений необходимо сохранить на обоих узлах кластера. Для этого на узле phobos выполним следующие команды:
scp deimos:/etc/vz/conf/101.conf /etc/vz/conf/ scp /etc/vz/conf/102.conf deimos:/etc/vz/conf/
В рамках подготовки к настройке Heartbeat необходимо активировать модуль ядра softdog, обеспечивающий автоматическую перезагрузку физического сервера при длительном отсутствии активности со стороны системы Heartbeat. Для этого на обоих узлах кластера (phobos и deimos) выполняются следующие команды:
modprobe softdog nowayout=0 echo "softdog nowayout=0" >>/etc/modules.conf
Настройка Heartbeat заключается в создании трёх конфигурационных файлов:
/etc/ha.d/ha.cf - файл основной конфигурации Heartbeat /etc/ha.d/authkeys - файл аутентификации узлов /etc/ha.d/haresources - файл описания ресурсов кластера
Файлы authkeys и haresources должны быть одинаковы на обоих узлах кластера. Файлы ha.cf также должны совпадать с точностью до параметров метода контроля состояния соседнего узла кластера (в нашем примере используется метод ucast, для которого обязательно указать IP другого узла кластера - при использовании других методов файлы ha.cf на обоих узлах кластера обычно совпадают).
Пример содержимого файла authkeys:
auth 1 1 sha1 4ffb8d2d786ba67772045b2eeac899ed
Команда для генерации ключа, помещаемого в файл файла authkeys:
(dd if=/dev/urandom bs=1024 count=1 2>/dev/null) | md5sum
Пример файла haresources, настроенного для нашего случая:
deimos drbddisk::db Filesystem::/dev/drbd0::/Data/db openvz::101 phobos drbddisk::apps Filesystem::/dev/drbd1::/Data/apps openvz::102
Здесь предполагается наличие в каталоге /etc/ha.d/resource.d следующих скриптов:
drdbdisk - управление DRBD
Filesystem - обеспечение монтирования файловой системы
openvz - управление виртуальными окружениями OpenVZ
Скрипты drdbdisk и Filesystem поставляются в составе пакета heartbeat-2 ОС Debian GNU/Linux 5.0.
Скрипт openvz приводим здесь:
#!/bin/bash # # This script is inteded to be used as resource script by heartbeat # ###
VZCTL="/usr/sbin/vzctl"
if [ "$#" -eq 2 ]; then RES="$1" CMD="$2" else RES="101" CMD="$1" fi
case "$CMD" in start) $VZCTL start $RES ;; stop) $VZCTL stop $RES ex=$? case $ex in 0) exit 0 ;; *) exit 1 ;; esac ;; status) ST=$( $VZCTL status $RES 2>&1 ) STATE=$( echo "$ST" | (read s1 s2 s3 s4 st && echo $st) ) case $STATE in running) echo "running" exit 0 # LSB status "service is OK" ;; down) echo "stopped" ;; *) echo "stopped ($ST)" ;; esac exit 3 # LSB status "service is not running" ;; *) echo "Usage: openvz resource {start|stop|status}" exit 1 ;; esac exit 0
Примеры файлов ha.cf на серверах phobos и deimos:
На сервере deimos:
keepalive 1 deadtime 15 warntime 5 initdead 120
ucast eth0 192.168.5.102
auto_failback on watchdog /dev/watchdog
node deimos node phobos
На сервере phobos:
keepalive 1 deadtime 15 warntime 5 initdead 120
ucast eth0 192.168.5.101
auto_failback on watchdog /dev/watchdog
node deimos node phobos
Крайне желательно в промышленной конфигурации настроить отдельный канал контроля состояния серверов (например, на основе соединения через COM-порты). Для реализации такой схемы потребуется изменение настроек в файле ha.cf.
Также крайне желательно обеспечить функционирование STONITH-устройства. Как минимум должно быть настроено аварийное завершение работы узлов кластера путём входа через SSH (STONITH-модуль external/ssh), идеальным же вариантом является подача команды в систему управления электропитанием либо в отдельный блок управления состоянием сервера (iLo, …).
Для тестирования необходимо сымитировать стандартные ситуации:
1.Выключение узла deimos 2.Включение узла deimos через некоторое время 3.Выключение узла phobos 4.Включение узла phobos через некоторое время 5.Одновременная загрузка узлов кластера 6.Загрузка узлов кластера с задержкой относительно друг друга
В случае реализации описанных выше дополнительных настроек Heartbeat также полезно выполнить дополнительные тесты:
1. Нарушение сетевого взаимодействия между узлами кластера (возможно - при сохранении доступа к ним из внешних сетей)
Для расширения доступного виртуальным окружениям дискового пространства в группе томов LVM, в которой были созданы тома DRBD, должно быть достаточное свободное пространство.
В случае отсутствия достаточного свободного пространства можно расширить группу томов путём включения в неё дополнительных физических томов. Для этого необходимо, чтобы к используемым серверам были подключены необходимые дисковые устройства. В большом числе случаев для подключения дополнительных дисков будет необходимо выполнить остановку соответствующего сервера, в нашем случае эту операцию можно выполнить без длительного перерыва в предоставлении сервисов пользователям, за счёт использования возможностей кластера. Пример сценария добавления дисков:
1.Остановить (выключить) сервер deimos. Все сервисы мигрируют на сервер phobos.
2.Добавить дополнительные диски в сервер deimos, выполнить необходимые настройки BIOS и контроллеров для обеспечения доступа к дискам.
3.Включить сервер deimos. Дождаться синхронизации томов DRBD (контроль по содержимому файла /proc/drbd) и завершения обратной миграции части сервисов обратно на сервер deimos.
4.Остановить (выключить) сервер phobos. Все сервисы мигрируют на сервер deimos.
5.Добавить дополнительные диски в сервер phobos.
6.Включить сервер phobos.
При выполнении работ по подключению дисков по описанному выше сценарию в нашем случае будет два перерыва в предоставлении сервисов пользователям, каждый из перерывов в пределах 1 минуты.
Подключенные дополнительные диски необходимо разметить и разместить на них физические тома LVM. Для разметки дисков используем программу GNU Parted, если она не установлена - устанавливаем её командой aptitude install parted. Пример команд для выполнения разметки диска:
deimos:~# parted /dev/sdc GNU Parted 1.8.8 Using /dev/sdc Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) print Error: /dev/sdc: unrecognised disk label (parted) mklabel New disk label type? msdos (parted) mkpart primary 1s -1s (parted) set 1 lvm on (parted) print Model: ATA VBOX HARDDISK (scsi) Disk /dev/sdc: 2147MB Sector size (logical/physical): 512B/512B Partition Table: msdos
Number Start End Size Type File system Flags 1 512B 2147MB 2147MB primary lvm
(parted) quit Information: You may need to update /etc/fstab.
deimos:~#
Для создания физического тома LVM и включения его в необходимую группу томов используем команды:
pvcreate /dev/sdc vgextend Data /dev/sdc
Для расширения файловой системы конкретного виртуального окружения следует последовательно выполнить три операции:
1.Увеличить размер тома LVM 2.Расширить том DRBD 3.Расширить файловую систему
Все три операции могут быть выполнены без приостановки сервисов кластера, однако должны выполняться строго при наличии в составе кластера двух работоспособных узлов.
Увеличение размера тома LVM выполняется на обоих узлах кластера командой lvextend. Пример увеличения размера тома LVM виртуального окружения db на 1 Гбайт:
На сервере phobos
lvextend -L+1G /dev/VGroup00/db
На сервере deimos
lvextend -L+1G /dev/VGroup00/db
Операция расширения тома DRBD выполняется синхронно на обоих узлах кластера, и должна инициироваться выполнением команды drbdadm resize. Данная команда должна быть выполнена на узле кластера, являющемся основным (primary) длясоответствующего тома. Пример выполнения команды (в нашем случае - на сервере deimos):
drbdadm resize db
Выполнение данной команды приведёт к началу синхронизации между узлами добавленного пространства логического тома, прогресс синхронизации можно отследить по содержимому файла /proc/drbd. Расширение файловой системы производится путём выполнения команды resize2fs. Данная команда также должна быть выполнена на узле кластера, являющемся основным (primary) для соответствующего тома, и может выполняться без размонтирования файловой системы. Пример выполнения команды (в нашем случае - на сервере deimos):
resize2fs /dev/drbd0