Возникла небольшая задача по созданию бюджетного отказоустойчивого кластера виртуалок.
Есть 2 двухголовых сервера, на них нужно развернуть ряд сервачков. Нагрузка по итогу не очень большая, можно было бы развернуть по отдельности поделив нагрузку, но есть второе требование: обеспечение резерва и высокой доступности, при полном отсутствии доп.финансирования
Посидев, подумав, было решено все это виртуализировать и кластеризировать.
Изучив предложения быстро понял, что единственным вариантом сделать все это является гипервизор kvm в дистрибутиве Proxmox VE, благо уже вышла версия 2.3 и основные косяки поправлены.
Поводом же написать сообщения явилось то, что полной пошаговой инструкции для развертывания такого кластера с использованием fencing нет в интернете, абзац в одном месте, кусок кода в другом месте, объяснение почему вообще на немецком.
Итак 2 сервера с 2-мя сетевыми картами. Первые из них втыкаем в свитч, вторые соединяем шнурком. Если используются raid, их нужно сконфигурировать по вкусу. Основная задача создать минимум 2 массива — один для самого proxmox, второй под общее хранилище. Параметры общего хранилища должны быть одинаковы.
Подготовка закончена.
Устанавливаем дистрибутив. Установка стандартна — лицензия, далее, ОК, выбрать часовой пояс, указать пароль root, электронную почту, выбрать диск для установки, забить настройки сетевого интерфейса.
Сеть настраивается только на статику (и это правильно для такой задачи) и только для первого интерфейса. Плюс к этому сетевое имя обязательно с указанием домена (fqdn).
Возьмем для примера:
Аналогично второй узел — node02.loc
ip — 192.168.0.200
mask — 255.255.255.0
gateway — 192.168.0.1
dns — 192.168.0.1
Все, на этом установка системы заканчивается, начинается работа.
Перво-наперво синхронизировать время. Если есть в сети сервер точного времени (контроллер домена например) указываем его и синхронизируемся. Если его нет, то вся надежда на pool.ntp.org
На обоих узлах:
echo «server ntp.company.lan» >> /etc/ntp.conf
/etc/init.d/ntp restart
ntpdc -p
# Правим /etc/hosts
для node01 добавляем строчку:
10.10.10.2 node02 node02.loc
для node02
10.10.10.1 node01 node01.loc
# Обновляемся
aptitude update && aptitude full-upgrade
Далее настраиваем сеть на вторых интерфейсах серверов. Это можно сделать как из терминала, так и из веб-интерфейса proxmox ( https://192.168.0.100:8006 для node01 и https://192.168.0.200:8006 для node02 соответственно). Заходим с логином root и паролем, указанным при установке, слева выбираем имя ноды, в главном окне вкладку Network, выделяем интерфейс eth1, Edit. Указываем адрес 10.10.10.1, маску 255.255.255.252, ставим галку на Autostart. Для второго узла повторяем процесс с ip 10.10.10.2
Перезагружаемся. Логинимся. Проверяем, что узлы видят друг друга
# на первом узле
ping node02
# на втором
ping node01
Если возникли проблемы, проверяем настройки сети, меняем патчкорд и т.д.
Создаем кластер
На узле node01:
pvecm create cluster01 #cluster01 — имя кластера, поменять потом невозможно!
pvecm status # проверяем, что все хорошо
На узле node02:
pvecm add 10.10.10.1 # добавляем node2 в наш кластер
Кластер создан.
Беремся за drbd (к примеру наше хранилище будет располагаться на /dev/sdb:
На обоих узлах:
fdisk /dev/sdb
n -> p -> 1 -> enter -> enter
t -> 8e
w
Раздел мы создали.
Можно ставить drbd8-utils, но не тут то было. Версия drbd в ядре 8.3.10, а в репозитории drbd8-utils версии 8.2.7, что очень не хорошо. Будем компелять, благо это недолго:
cd ~
apt-get install git-core git-buildpackage fakeroot debconf-utils docbook-xml docbook-xsl dpatch xsltproc autoconf flex
mkdir drbd
cd drbd
git clone http://git.drbd.org/drbd-8.3.git
cd drbd-8.3
git checkout drbd-8.3.10
dpkg-buildpackage -rfakeroot -b -uc
cd ..
dpkg -i drbd8-utils_8.3.10-0_amd64.deb
На один установили. Можно повторить на втором, или перетащить полученный пакет и просто его установить. Решать Вам.
Разбираемся с конфигами drbd:
На обоих:
nano /etc/drbd.d/global_common.conf
Все удаляем и пишем:
global { usage-count no; }
common { syncer { rate 30M; } }
nano /etc/drbd.d/r0.res
resource r0 {
protocol C;
startup {
wfc-timeout 0; # non-zero might be dangerous
degr-wfc-timeout 60;
become-primary-on both;
}
net {
cram-hmac-alg sha1;
shared-secret «oogh2ouch0aitahNBLABLABLA»;
allow-two-primaries;
after-sb-0pri discard-zero-changes;
after-sb-1pri discard-secondary;
after-sb-2pri disconnect;
}
on node01 {
device /dev/drbd0;
disk /dev/sdb1;
address 10.10.10.1:7788;
meta-disk internal;
}
on node02 {
device /dev/drbd0;
disk /dev/sdb1;
address 10.10.10.2:7788;
meta-disk internal;
}
}
Стартуем на обоих узлах drbd
/etc/init.d/drbd start
drbdadm create-md r0
drbdadm up r0
!!! Только на одном узле (node01): !!!
drbdadm — —overwrite-data-of-peer primary r0
watch cat /proc/drbd #наблюдаем пока синхронизируются узлы до Primary/Primary UpToDate/UpToDate
На обоих узлах:
nano /etc/lvm/lvm.conf
# Меняем строчку filter = [ «a/.*/» ] на
filter = [ «r|^/dev/sdb1|», «a|^/dev/sd|», «a|^/dev/drbd|» ,»r/.*/» ]
!!! Только на одном узле (node01): !!!
pvcreate /dev/drbd0
pvscan # in order to check
vgcreate drbdvg /dev/drbd0 # имя drbdvg можете поставить свое
Далее идем в интерфейс proxmox
Data Center > Storage > Add > LVM group
ID: drbd
Volume group: drbdvg
Shared: yes
ID выбираете сами, поменять невозможно.
Уже можно создавать виртуальные машинки (обязательно в закладке hdd укажите storage: drbdvg).
Можно запускать и наслаждаться миграцией.
Если Вам этого достаточно, дальше можно не читать.
Но мне необходим был HA, поэтому мучения продолжаются.
Создаем конфиг кластера (node01):
cp /etc/pve/cluster.conf /etc/pve/cluster.conf.new
я привел его к такому виду:
cat /etc/pve/cluster.conf
<?xml version=»1.0″?>
<cluster config_version=»10″ name=»cluster»>
<cman expected_votes=»1″ keyfile=»/var/lib/pve-cluster/corosync.authkey» two_node=»1″/>
<fencedevices>
<fencedevice agent=»fence_manual» name=»human»/>
</fencedevices>
<clusternodes>
<clusternode name=»node01″ nodeid=»1″ votes=»1″>
<fence>
<method name=»single»>
<device name=»human» nodename=»node01″/>
</method>
</fence>
</clusternode>
<clusternode name=»node02″ nodeid=»2″ votes=»1″>
<fence>
<method name=»single»>
<device name=»human» nodename=»node02″/>
</method>
</fence>
</clusternode>
</clusternodes>
</cluster>
# config_version=»10″ обязательно увеличиваем каждый раз, когда меняем содержимое
Что мы здесь видим:
Устройство fence — ручной переключатель (возможны другие варианты, от упса до коммутатора).
Fence — в общем это такой механизм, который гарантированно вырубит отвалившийся узел, чтобы не допустить возможности их параллельной работы (что в случае drbd однозначно приведет к поломке синхронизации дисков и ручного разгребания каши на них).
В этом примере гарантом изоляции является человек, что тоже не очень, но оставим это на будущее.
Идем в интерфейс и применяем настройки кластера: Datacenter -> HA -> Activate
Правим, удалив комментарий в последней строчке на обоих узлах:
nano /etc/default/redhat-cluster-pve
выполним на обоих узлах:
fence_tool join
Наш домен fence готов.
Если есть вирт.машинка подключаем ее к HA кнопкой add (указываем id машинки). Если нет, создаем и подключаем.
Почти все. Идем в сервер(node01) -> Services запускаем службу RGManager. Должна запуститься наша машинка. Повторяем запуск RGManager на node02.
Все. Можем гасить node01 машинка переберется на node02.
!!! Обязательно !!!
Если у вас к vm подключен инсталяционный cd, или подключена консоль, отключитесь, иначе кина не будет.
P.S.
Для ручного fencin-га:
Запускаем vn на node01
Гасим node01
Идем на node02
Говорим, что 100% уверены, что узел 1 не работает: fence_ack_manual node01
Говорим, что на 1000500% уверены введя «absolutely»
машинка заведется на node02