= bubbalog =Дневникът на моето стадо

UildShiiP Cluster Project: модул1 – Apache HA Cluster

Sunday 16.08.2009 21:33 EET · Публикувано от в = Cluster =, = FreeBSD =, = HA-cluster =

Както вече споменах в началния пост по въпроса, реших да се захвана да градя клъстър под FreeBSD в домашни условия. Че и име му измислих… Еми как може така, от цялото четене поне разбрах, че всеки клъстър си има име – къде от величаене, къде от улигофрения… Та и моя получи своето – UildShiiP – който ме познава ще го разбере веднага от къде иде и какво означава, за останалите… това  ще остане една тъмна мистерия.

Както и да е, време е да се погваля – след една седмица упорито четене (при ниво на знанията в началото 0), преди около час най-накрая запуснах в работещ вариант първия модул от проекта – High Availability Apache cluster.

Самото изпълнение е на 2 машини с инсталиран Heartbeat и синхронизирани с rsync през ssh. Двете машини трябва да имат по 2 мрежови интерфейса – единия са връзка с мрежата и втори усукана двойка за директна връзка за синхронизация и контролни пакети между двата нода на клъстъра. Техните конфигурации са съответно:

  • node1:
eth0 192.168.1.101 (нормална 192.168.1.х мрежа)
eth1 10.0.0.1 (директна мрежа за Heartbeat)
  • node2:
eth0 192.168.1.102 (нормална 192.168.1.х мрежа)
eth1 10.0.0.2 (директна мрежа за Heartbeat)

Преди да започнете за окомплектовате всичко обаче е нужно да се инсталират някои неща, които сега или на по късен етап биха потрябвали за изграждането на системата. Тъй като за повечето съм писал в друга статия, а за останалите няма нищо специфично, ето само списък с нужните според мен неща за този модул:

/usr/ports/sysutils/heartbeat
/usr/ports/net/rsync
/usr/ports/www/apache22
/usr/ports/lang/php5
/usr/ports/lang/php5-extensions
/usr/ports/databases/phpmyadmin

Също така направете директориите за documentroot при Apache и такава, в която ще съхранявате свойте скриптове и специални файлове.

1. Конфигурация на Heartbeat

Информацията по въпроса е доста оскъдна и предимно за Linux, а за FreeBSD няма нищо относно самата конфигурация, а само за проблеми при настройката. Това което ни трябва заедно с примерните конфигурационни файлове обаче не е в нета, а в инсталационната директория на самия Heartbeat на машината – /usr/local/share/doc/heartbeat. Копирайте ha.cf, haresources и authkeys в /usr/local/etc/ha.d/

#cd /usr/local/share/doc/heartbeat
#cp ha.cf /usr/local/etc/ha.d/
#cp haresources /usr/local/etc/ha.d/
#cp authkeys /usr/local/etc/ha.d/

Сега отворете /usr/local/etc/ha.d/ha.cf и редактирайте следните редове

  • bcast <NIC> – кой адаптер ще се исползва за Heartbeat. Сменете с името на вашия адаптер
  • keepalive 2 – времето в секунди между 2 проверки
  • warntime 10 – времето в секунди преди в лоовете да се обяви, че проверката закъснява
  • deadtime 30 – времето в секунди преди да бъде обявен нода за “мъртъв”
  • initdead 120 – времето в секунди преди да срартира системата след зареждане на ОС. Като правило трябва да е не по-малко от 2 пъти “deadtime”
  • auto_failback off -след  пропадане на мастер нода бекъпа заема неговото място като мастер. При зададена опция on (по подразбиране ако реда е коментиран в конфигурацията), след зареждане на ОС-а мастера заема отново мястото си като мастер, а моментния мастер се изтегля като бекъп. При зададена опция off, след като се зареди ОС-а, бившия мастер остава бекъп, и се синхронизира с моментния мастер. За нашите нужди тази опция трябва да е именно off.
  • node ime_na_node1 -името на първия нод в клъстъра. Проверява се с “uname -n”
  • node ime_na_node2 -името на втория нод в клъстъра. Проверява се с “uname -n”

Следващата стъпка е конфигурирането на ресурсите, като редактирате haresources и прибавите (в нашия случай)

ime_na_node1 192.168.1.10 apachectl

като “ime_na_node1” е името на нода на който се подкарва инициално сървъра, “192.168.1.10” е виртуалния адрес на който отговаря сървъра, а “apachectl” е командата която подкарва апаха. Не конфигурирайте виртуалния адрес на клъстъра от друго място! Трябва да се отбележи, че подкарваните команди трябва да могат да се управляват със “start” и “stop“,  именно за което тук не може да се използва стандартната команда /usr/local/etc/rc.d/apache22, която стартира апаха от команден ред с “onestart“. Другата особеност е, че Heartbeat търси стартиращи скриптове само в

/etc/ha.d/resource.d
/etc/rc.d/init.d

който проблем се решава просто с поставянето на символичен линк към apachectl:

ln -s /etc/ha.d/resource.d/apachectl /usr/local/sbin/apachectl

Тук обаче се появи още един стар мой проблем при стартирането на апаха, което май се оказа постоянен синдром –  [warn] (2)No such file or directory: Failed to enable the ‘httpready’ Accept Filter. Решението както съм писал и преди (но хайде да не цъкате само по препратки) е редактирането на /boot/defaults/loader.cnf и корекцията на следните 2 реда на:

accf_data_load=”YES” # Wait for data accept filter
accf_http_load=”YES” # Wait for full HTTP request accept filter

Третата стъпка е редактирането на authkeys според който се автентикират един-друг двата нода. Опциите за автентикация са crc, md5 и sha1, а формата за файла е

auth <number>
<number> <authmethod> [<authkey>]

При директна връзка между двата нода спокойно може да използвате crc. Ако сте малко параноичен или не използвате директен кабел, но искате да адите CPU натовареностаможе да използвате md5. Ако нямате угризения за заемания ресурс може да използвате sha1, който разбира се е и най-тръден за разбиване.

С това основната конфигурация на Heartbeat достатъчна за да тръгне системата е завършена. Уверете че haresources и authkeys са еднакви и на двата нода! Има разбира се още опции за конфигуриране, но това оставям на вас.

2. Конфигуриране на rsync

Втората част от клъстъра е конфигурирането на адекватна сихронизация на директориите в които се съдържат сайтовете. Тъй като вече сме инсталирали нужните портове, време е да се пристъпо към конфигурирането. Първата стъпка е генерирането на частен и публичен ключ са свръзка през ssh, като това трява да се изпълни през акаунта, чрез който ще става синхронизацията, тъй като FreeBSD по подразбиране не може да се логнете директно като root, няма да може да използваме този акаунт за синхронизация, а това означава, че самия потребител трябва да има правя за четение и писане в съответните синхронизирани директории. Това става с командата

#ssh-keygen -d

което ще генерира в /usr/home/usr_homedir/.ssh 2 файла:

  • id_dsa – частния ключ
  • id_dsa.pub – публичния ключ

сега копирайте публичния ключ, като изпълните следните 2 команди:

#cd /usr/home/usr_homedir/.ssh
#cp id_dsa.pub authorized_keys2
#chmod 400 authorized_keys2

след което копирайте цялата доректория .ssh на втория нод, като използвате scp – secure copy през ssh във вида “scp /local/dir /remote/dir“:

scp -r -P xxx /usr/home/user_homedir/.ssh/ remote_user@remoteIP:/usr/home/user_homedir/.ssh

където опцията “-r” е за копиране на директория, а опцията “-P xxx” е за определяне на порта през който комуникира ssh и ако не сте го сменяли (добра идея е да се смени веднага след инсталация на ОС-а) няма нужда да я ползвате. Важно също така е да се спомене, че последния слеш “/” на локалния път е абсолютно задължителен, а на отдалечения – да го няма, в противен случай на отдалечения нод ще получите след копиране ~/.ssh/.ssh. Този последен слаш указва ако го има да копира само контента на директорията, а ако го няма копира цялата директория като обект заедно със всичко в нея. След като всичко е копирано може да се пробвате да се логнете към другия нод и би трябвало директно да ви логне без да ви пита за парола.

#ssh remote_node_IP

Единствено, ако се логвате за пръв път еднократно ще ви попита за проверка на хост ключа. Ако всичко мине добре значи сте готови за последната стъпка.

Последната стъпка е слагането на скрипт за синхронизация на двете машини. Именно тук става нужна настройката auto_failback off , която казва на падналия мастер нод да се завърне след стартиране като бекъп, а не да заеме пак мастер позицията. Целта на занятието е, да не се генерира излишен трафик и да стане объркване. Като начало бях изработил скрипт, който първоначално проверява дали машината е мастър или бекъп, и ако е мастър – генерира md5sum на наблюдаваната директория и я копира на втория нод. Съответно, втория нод ако се открие като бекъп сравнява копирания чексум с този на неговата директория и ако е еднаква излиза от скрипта, ако не е – се синхронизира. Е да ама не, това работи до някое време и след амнайстата проба просто отказа да генерира еднакви чексуми и се ъпдейтваше при всяко стартиране на скрипта. След малко четене обаче се оказа, че тази моя md5sum проверка е напълно излишна, защото самия rsync прави такава проверка и копира само тези файлове които са променени или нови и при поставена опция “–delete” трие тези файлове които са му в повече – сиреч има ги на бекъпа, а на мастера са изтрити в момента на синхронизацията. Чисто и без генериране на излишен трафик. Тук е момента да споделя, че колкото упътвания изчетох, на всяко едно пишеше с големи дебели букви: Използването на опцията “–delete” може да е много опасно, боравете с нея много внимателно! И… така се появи и окончателния вариант на скрипта, който аз използвам. За самите опции към командите може да проверите в man страниците. Самия скрипт си е написан от мен, така че ако нешо не сработи – може мен да псувате.

#!/bin/sh
stat=`/usr/local/etc/ha.d/resource.d/IPaddr <virtualIP> status|awk ‘{print $1}’`
if [ $stat = running ]
then
echo “This is MASTER node!”
else
echo “This is BACKUP node!” && \
echo “Synchronizing BACKUP:” &&\
rsync -avz -e “ssh -p <port>” –delete master_node_IP:/remote/sync/dir/ /local/sync/dir
fi

Ами това е. Следва само да сложите скрипта в crontab и да определите на какъв интервал искате да се прави синхронизацията, но това вече си е изцяло ваше  решение с оглед на обема данни който ще тече по жицата.

Следваща спирка – да успея да се преборя с MySQL клъстъра, но това – от утре, за тази седмица ми стига безсъние и днеска мисля да си се наспя с кеф.

P.S.: Ето и малко предистория, която може да е полезна на някой. В началото на експериента започнах с един прост carp виртуални интерфейси на FreeBSD, NFS сървър/клиент и безумно мислене как да синхронизирам цялата тази пущина. Сам по себе си, carp не се подкарва ниkаk трудно – прекомпилира се кърнъла:

# cd /usr/src/sys/i386/conf
# cp GENERIC GENERIC-CARP
# echo “device carp” >> GENERIC-CARP
# config GENERIC-CARP
# cd ../compile/GENERIC-CARP
# make depend
# make
# make install
# make clean
# shutdown -r now

настройвате да се свалят всички carp интерфейси, ако някой от физическите падне, за да може друга машина да поеме трафика

sysctl net.inet.carp.preempt=1

а после просто се добавят 2 реда в /etc/rc.conf

cloned_interfaces=”carp0″
ifconfig_carp0=”vhid 1 advskew 100 pass <parola> 192.168.1.50/24″

където vhid е номер на виртуалната мрежа в която работи интерфейса, advskew е приоритета на дадената машина (колкото по-малък номер – толкова по-висок приоритет има), <parola> се заменя с парола, с която да се автентикират съответните машини, и накрая – виртуалното IP и префикса на което ще отговаря интерфейса. Тук трябва да се отбележи, че редовете в /etc/rc.conf  трябва да са еднакви при всички машини, като се променя номера за приоритет на всяка от тях. Ако искате да добавите повече  виртуални интерфейси просто трябва да ги изброите и да прибавите съответните редове за тях в /etc/rc.conf

cloned_interfaces=”carp0 carp1 carp2 … carpN”
ifconfig_carp0=…
ifconfig_carp1=…
ifconfig_carp2=…

ifconfig_carpN=…

Конфигурацията на NFS също не е никак сложна. За сървъра прибавяте в /etc/rc.conf

nfs_server_enable=”YES”
nfs_server_flags=”-u -t -n 4″
mountd_flags=”-r”

където на първия ред се указва да се пуска сървъра при зареждане на системата, на втория да работи на UDP и TCP портовете (-u -t), както и да пусне 4 демона (-n 4), а на третия ред се казва на mountd  да стартира заедно с NFS сървъра. После прибавете на ръка ако го няма /etc/exports и в него опишете споделените директории

/share/dir -alldirs -maproot=0 192.168.0.20 192.168.0.21 192.168.1.0/24(rw)

където -alldirs показва да се експортнат всеички поддиректории, -maproot=0 – за да поже root-a да променя отдалечената файлова система и следват изброени хостове и мрежи, които ще имат достъп до ресурса

За клиента е аналогично:

nfs_client_enable=”YES”
nfs_client_flags=”-u -t -n 4″

като при клиента се добавят и редове за маунтване в /etc/fstab

server-IP:/share/dir /mnt/point nfs rw 0 0

Защо го зарязах ли? Ами да си призная не ми хареса идеята с тоя NFS и маунтването – ял съм го дебел с подобми изпълнения, само че на SAMBA. Отделно от много време не съм голям привърженик на прекомпилирането на ядро – много време и игра за нещо което може да се направи доста по-нежно и елегантно по другначин. Не можах и да се сетя как точно да синхронизирам цялата боза. Бекъпа може да се синхронизира чудесно с мастъра, но когато мастъра падне и някой пише нещо в това време по бекъпа, когато мастъра се дигне той веднага заема мястото си на мастер, като съответно се игнорират промените по бекъпа, а когато почне синхронизацията на мастера с бекъпа и в същото време някой продължи да пише по него, особено и ако трафика е по тежък… мисля, че ще стане една адска боза. Ето е това отношение Heartbeat ми се струва много по подходяща система за High Availability.

2 коментара за “UildShiiP Cluster Project: модул1 – Apache HA Cluster”

  1. Даниел says:

    Все пак, конфигурацията с carp никак не е за изхвърляне, ако ти трябват повече от две машини. Едва ли е оправдано за домашни цели обаче.

    Може да разделиш файловата система от сървъра, примерно с NFS. Нормалната работа на apache не създава кой знае какви грижи на NFS.

    Та за целта ти е нужно:
    1. NFS сървър, който може да ти е отделен HA проект :)
    2. Два или повече сървъра с apache. Сървърите монтират файловата система с документите на Apache по мрежата.
    3. Може да ги резервираш или с heartbeat или с carp — последното разбира се е по-чисто решение.

    Само идея.

  2. Ами да си призная, това са първите ми стъпки по направлението. От около половин година яко се запалих по клъстърите, но като самоук и без познати в сферата е доста тегаво :). Трудно се намира информация, особено пък и за FreeBSD, но малко по малко напредвам. Това което е проблем също е броя на тестовите машини. Това което предлагаш е интересно, но нямам толкова машини да го подкарам реално, иначе – би било интересно да го реализирам. Но… както казах, доста съм се запалил по темата и сега събирам сносни стари машинки за подобни цели. От няколко дена съм се зачел и за изчислителните клъстъри… Само време да има :) Мерси за идеята, задължително ще се тества, имам нужда от такива напътствия от време на време.

Остави коментар

Писането на кирилица е задължително!
Коментари, които не са на кирилица ще бъдат изтрити без предупреждение.
Всеки коментари съдържащи 1 или повече линка, ще бъдат публикувани след одобрение.