четверг, 17 февраля 2011 г.

Строим кластер на связке DRBD+Pacemaker+OpenVZ+NFS+Zabbix


Все это чудо будет крутиться на Debian 64
Сперва подготавливаем систему:
aptitude update
aptitude upgrade
apt-get install psmisc ntp ntpdate ssh
Включаем форвард:
nano /etc/sysctl.conf
net.ipv4.ip_forward=1
sysctl -p
Создаем общую папку, куда будет монтироваться DRBD устройство и от куда по NFS клиенты будут забирать данные:
mkdir /NFS
В роли OpenVZ я решил использовать Proxmox. Его вебку тупо не нужно допиливать)))
Открываем sources.list:
nano /etc/apt/sources.list
И добавляем вот эти строчки:
# PVE packages provided by proxmox.com
deb http://download.proxmox.com/debian lenny pve
Теперь нам необходимо получить ключик:
wget -O- "http://download.proxmox.com/debian/key.asc" | apt-key add -
Делаем апдейт:
aptitude update
Так как Proxmox поставляет свое ядро, то сперва ищем последнюю версию:
aptitude search pve
Устанавливаем:
aptitude install pve-kernel-2.6.32-4-pve
aptitude install pve-headers-2.6.32-4-pve
То же самое проделываем с вебкой:
aptitude search proxmox
aptitude install proxmox-ve-2.6.32
Не забываем поправить груб:
nano /boot/grub/grub.cfg (old version: nano /boot/grub/menu.lst)
Перезагружаемся в наше ядро 2.6.32-4-pve

Настраиваем наши сетевые интерфейсы:
nano /etc/network/interfaces
# network interface settings
auto lo
iface lo inet loopback

#auto eth0
#iface eth0 inet static
iface eth0 inet manual

auto vmbr0
iface vmbr0 inet static
          address 192.168.0.11
          netmask 255.255.255.0
          gateway 192.168.0.72
          bridge_ports eth0
          bridge_stp off
          bridge_fd 0

auto venet0
iface venet0 inet static
        address  192.168.2.11
        netmask  255.255.255.0

auto eth1
iface eth1 inet static
    address 192.168.1.11
    netmask 255.255.255.0
Перезагружаем сервис:
/etc/init.d/networking restart
Proxmox установлен, вот основные команды:
pveca -l                   - Показать состояния кластера
pveca -c                   - Создать новый кластер, а ноду на которой выполнили команду сделать мастером
pveca -s -h IPmaster - Синхронизироваться с мастером
pveca -d ID               - Удалить ноду из кластера
pveca -a -h IPmaster - Добавить ноду в кластер
pveca -m                 - Сделать мастером
В первом файле конфигурация кластера, во втором ключи доступа:
nano /etc/pve/cluster.cfg
nano /root/.ssh/known_hosts
Устанавливаем DRBD:
apt-get install drbd8-utils
Чистим конфиг:
> /etc/drbd.conf
И приступаем к настройке:
nano /etc/drbd.conf
Содержание моего drbd.conf:
global { usage-count yes; }
common { syncer { rate 200M; } }
resource drbd0 {
protocol C;
startup {
                    wfc-timeout 15;
                    degr-wfc-timeout 60;
}
net {
                    cram-hmac-alg sha1;
                    shared-secret "ВАШ_ПАРОЛЬ";
                    ping-timeout 20;
}
on node1 {
                    device /dev/drbd0;
                    disk /dev/sdb5;
                    address 192.168.0.11:7789;
                    meta-disk internal;
}
on node2 {
                    device /dev/drbd0;
                    disk /dev/sdb5;
                    address 192.168.0.12:7789;
                    meta-disk internal;
}
disk {
                    on-io-error   detach;
}
handlers {
                    fence-peer "/usr/lib/drbd/crm-fence-peer.sh";
}
Либо копируем drbd.conf на вторую ноду или делаем все тоже самое.

Затираем разделы, если есть необходимость:
dd if=/dev/zero of=/dev/sdb5 bs=1M count=128
Стартуем на обоих нодах:
/etc/init.d/drbd start
На обоих нодах:
drbdadm create-md drbd0
drbdadm up drbd0
На ноде, которую решили сделать мастером:
drbdadm -- --overwrite-data-of-peer primary drbd0
Наблюдаем за процессом любой из команд:
watch cat /proc/drbd
watch /etc/init.d/drbd status
По необходимости:
mkfs.ext3 /dev/drbd0
Останавливаем DRBD на обеих нодах, так как дальше им будет управлять Pacemaker:
/etc/init.d/drbd stop
И удаляем DRBD с автозагрузки по той же причине, что и чуть выше:
update-rc.d drbd remove
Устанавливаем сам Pacemaker:
apt-get install pacemaker
Обязательно включаем Corosync:
nano /etc/default/corosync
START=yes
Генерируем ключ. Для генерации необходимо жать на клавиши или двигать мышку.
corosync-keygen
Копируем с генерированный ключ на все ноды, которые будут в кластере:
(Не забываем про добавляемые ноды уже в готовый кластер)
scp /etc/corosync/authkey root@192.168.0.1X:/etc/corosync/authkey
chmod 400 /etc/corosync/authkey
На всех нодах в corosync.conf изменить нужные строки, как показано ниже:
nano /etc/corosync/corosync.conf
token:          5000
token_retransmits_before_loss_const: 20
join:           1000
consensus:      7500
bindnetaddr: 192.168.0.0 # На свою подсеть, класс С, вида Х.Х.Х.0
Запускаем Corosync на всех нодах
/etc/init.d/corosync start
Может я и переборщил, но я банально шлепаю в начало в тот скрипт, который использую вот такие строчки, что бы не ругался на не установку:
nano /usr/lib/ocf/resource.d/linbit/drbd
OCF_ROOT=/usr/lib/ocf
export OCF_ROOT=/usr/lib/ocf

nano /usr/lib/ocf/resource.d/heartbeat/IPaddr2
OCF_ROOT=/usr/lib/ocf
export OCF_ROOT=/usr/lib/ocf

nano /usr/lib/ocf/resource.d/heartbeat/Filesystem
OCF_ROOT=/usr/lib/ocf
export OCF_ROOT=/usr/lib/ocf
#OCF_RESKEY_device=/dev/drbd0
#OCF_RESKEY_directory=/NFS
#OCF_RESKEY_fstype=ext3

nano /usr/lib/ocf/resource.d/heartbeat/nfsserver
OCF_ROOT=/usr/lib/ocf
export OCF_ROOT=/usr/lib/ocf
DEFAULT_INIT_SCRIPT="/etc/init.d/nfs-kernel-server"

nano /usr/lib/ocf/resource.d/heartbeat/.ocf-binaries
PATH="$PATH:/usr/lib/ocf"
Практически закончили....
Сейчас будем описывать что, где, когда и при каких условиях должно стартовать.

Сперва установим редактор по умолчанию, если нравиться vi можете пропустить это:
export EDITOR=/bin/nano
echo "export EDITOR=/bin/nano" >> .bashrc
После выполнение следующей команды появится пустой файл:
crm configure edit
Выходим и ждем секунд двадцать...

Снова выполняем эту команду:
crm configure edit
И видим что то типо этого:
node node1
node node2
property $id="cib-bootstrap-options" \
                    dc-version="1.0.9-74392a28b7f31d7ddc86689598bd23114f58978b" \
                    cluster-infrastructure="openais" \
                    expected-quorum-votes="2"
Если что то подобное, то все пока идет отлично....

Маленько забегу наперед. Возможно вы повнимательнее меня, но все же!
Нужно обратить внимание вот на такую примерно запись:
target-role="started"
И если за место "started" стоит "stoped", то ресурс не стартанет, соответственно.
Либо удаляем эту строчку либо меняем "stoped" на "started"
Опять же обращаем внимание на тонкость иначе вас не выпустит с конфига...

Не правильное описание ресурса:
property $id="cib-bootstrap-options" \
                    dc-version="1.0.9-74392a28b7f31d7ddc86689598bd23114f58978b" \
                    cluster-infrastructure="openais" \
                    expected-quorum-votes="2" \
Правильное описание ресурса:
property $id="cib-bootstrap-options" \
                    dc-version="1.0.9-74392a28b7f31d7ddc86689598bd23114f58978b" \
                    cluster-infrastructure="openais" \
                    expected-quorum-votes="2"
Символ "\" означает перевод строки и ожидание продолжения.

Если кому то принципиально дальнейший поряд вывода на мониторе ресурсов, то добавляем примитивы в нужной последовательности.

Далее пошли мои примитивы. Имена можно менять. Событиями варьировать))))
crm configure
primitive resDRBD ocf:linbit:drbd params drbd_resource="drbd0" drbdconf="/etc/drbd.conf" op start timeout=240s op stop timeout=100s
ms msDRBD resDRBD meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
location loc_msDRBD_3 msDRBD -inf: node3
location loc_msDRBD_4 msDRBD -inf: node4
property stonith-enabled=false
configure property no-quorum-policy="ignore"
bye
Вот эти строчки по идеи лишнии:
location loc_msDRBD_3 msDRBD -inf: node3
location loc_msDRBD_4 msDRBD -inf: node4
У меня просто DRBD пытался запуститься на этих нодах, на которых DRBD вообще не сконфигурирован.
crm configure
primitive resFS ocf:heartbeat:Filesystem params device="/dev/drbd0" directory="/NFS" fstype="ext3" op start timeout=60s op stop timeout=60s
colocation fs_on_master inf: resFS msDRBD:Master
order fs_after_drbd inf: msDRBD:promote resFS:start
bye
...Небольшое отступление....
Устанавливаем NFS на ноды где поднят DRBD:
apt-get install nfs-kernel-server
update-rc.d nfs-kernel-server remove
update-rc.d nfs-common remove
Правим этот файлик так же на обоих нодах, где установлен DRBD:
nano /etc/exports
/NFS/ 192.168.0.0/255.255.255.0(rw,no_root_squash,no_all_squash,sync)
...Продолжаем...
crm configure
primitive NFSserver ocf:heartbeat:nfsserver params nfs_init_script="/etc/init.d/nfs-kernel-server" nfs_notify_cmd="/sbin/rpc.statd" nfs_shared_infodir="/var/lib/nfs/" nfs_ip="192.168.0.10" op start timeout=40s
colocation nfs_on_master inf: NFSserver msDRBD:Master
order nfss_after_vipp inf: vIPp:start NFSserver:start
bye
Этот ресурс я выделил отдельно от стальных нод, все таки это DRBD Slave, мне так захотелось))
crm configure
primitive NFSclient ocf:heartbeat:Filesystem params device="192.168.0.10:/NFS" directory="/NFS" fstype="nfs" options="nolock" op start timeout=60s op stop timeout=60s
colocation mnt_nfsc_slave inf: NFSclient msDRBD:Slave
order slave_after_master inf: NFSserver:start NFSclient:start
bye
Единственно "НО", для вновь добавляемой ноды придется создавать отдельный ресурс:
crm configure
primitive NFSnodeX ocf:heartbeat:Filesystem params device="192.168.0.10:/NFS" directory="/NFS" fstype="nfs" options="nolock" op start timeout=60s op stop timeout=60s
location loc_nfsnX NFSnodeX inf: nodeX
order nfsnX_after_nfss inf: NFSserver:start NFSnodeX:start
bye
...где х - это номер ноды...

Если есть необходимость, вдруг что то не запустилось, перезагружаем Corosync:
/etc/init.d/corosync stop
/etc/init.d/corosync start
На DRBD мастере выполняем:
mv /var/lib/nfs/ /NFS/
ln -s /NFS/nfs/ /var/lib/nfs
mv /etc/vz/conf /NFS/vz/conf
ln -s /NFS/vz/conf /etc/vz/conf
mv /etc/vz/dists /NFS/vz/dists
ln -s /NFS/vz/dists /etc/vz/dists
mv /etc/vz/names /NFS/vz/names
ln -s /NFS/vz/dists /etc/vz/dists
На остальных нодах:
rm -fr /var/lib/nfs/
ln -s /NFS/nfs/ /var/lib/nfs
rm -fr /var/lib/vz/
ln -s /NFS/vz/ /var/lib/vz
rm -fr /etc/vz/conf
ln -s /NFS/vz/conf /etc/vz/conf
rm -fr /etc/vz/dists
ln -s /NFS/vz/dists /etc/vz/dists
rm -fr /etc/vz/names
ln -s /NFS/vz/names /etc/vz/names
Далее, использую основные команды Proxmox, настраиваем наш кластер:
pveca -l                   - Показать состояния кластера
pveca -c                   - Создать новый кластер
pveca -s -h IPmaster - Синхронизироваться с мастером
pveca -d ID               - Удалить ноду из кластера
pveca -a -h IPmaster - Добавить ноду в кластер
pveca -m                   - Сделать мастером
...Тут мастером можно сделать любой компьютер - это не принципиально...

Кластер готов, настроен, и работает. Осталось настроить систему мониторинга...
Мне приглянулся Zabbix поэтому буду использовать его...

На сервере, а так как он на одном из DRBD устройств - на обоих DRBD устройств выполняем:
apt-get install zabbix-server-mysql zabbix-agent zabbix-frontend-php
На других нодах достаточно:
apt-get install zabbix-agent
Удаляем на DRBD устройствах с автозагрузки Zabbix сервер, так как стартовать будем через Pacemaker:
update-rc.d zabbix-server remove
И останавливаем соответственно тоже на обоих DRBD устройствах:
/etc/init.d/zabbix-server stop
Теперь самое сложное, для меня по крайней мере. Так как я не силен в написание скриптов, то пришлось прибегнуть к небольшой хитрости. Смотрим ниже:
cp -f /usr/lib/ocf/resource.d/heartbeat/pingd /usr/lib/ocf/resource.d/heartbeat/zabbix-server
nano /usr/lib/ocf/resource.d/heartbeat/zabbix-server
OCF_ROOT=/usr/lib/ocf
export OCF_ROOT=/usr/lib/ocf
В самое начало соответствующих функций добавляем свои команды на стар и стоп Zabbix сервера:
pingd_start() {
/etc/init.d/zabbix-server start
Оставляем родной код
}
pingd_stop() {
/etc/init.d/zabbix-server stop
Оставляем родной код
}

А теперь опишем наш ресурс в Pacemaker:
crm configure
primitive Zabbix ocf:heartbeat:zabbix-server params dampen="60s" host_list="127.0.0.1" op monitor interval="20s" timeout="120s"
colocation zabbix_on_master inf: Zabbix resFS
order zabbix_after_fs inf: resFS:start Zabbix:start
bye
А теперь маленький тюнинг:
nano /etc/php5/apache2/php.ini
date.timezone = "Asia/Yekaterinburg"
memory_limit = 256M
post_max_size = 32M
upload_max_filesize = 16M
max_execution_time = 600
max_input_time = 600

Теперь переносим Zabbix на DRBD устройство:
Создаем папку:
mkdir /NFS/zabbix
На DRBD мастере:
mv /var/lib/mysql/zabbix /NFS/zabbix/db
ln -s /NFS/zabbix/db /var/lib/mysql/zabbix
mv /usr/share/zabbix /NFS/zabbix/web
ln -s /NFS/zabbix/web /usr/share/zabbix
На DRBD слейве:
rm -fr /var/lib/mysql/zabbix
ln -s /NFS/zabbix/db /var/lib/mysql/zabbix
rm -fr /usr/share/zabbix
ln -s /NFS/zabbix/web /usr/share/zabbix
ОБЯЗАТЕЛЬНО проделайте следующие команды на DRBD устройствах для удовлетворения симлинком в zabbix-frontend:
ln -s /usr/share/javascript /NFS/zabbix/javascript
ln -s /usr/share/fonts /NFS/zabbix/fonts
Следующие строчки вообще ни как не повлияли на процесс, но я их выполнил:
nano /NFS/zabbix/web/conf/zabbix.conf.php
$ZBX_SERVER = '192.168.0.10';
Осталось настроить уведомление о событиях:
touch /NFS/zabbix/alert.d/zabbix_sendemail
chmod 755 /NFS/zabbix/alert.d/zabbix_sendemail
nano /NFS/zabbix/alert.d/zabbix_sendemail
Вот родной пример настройки: http://www.zabbix.com/forum/showpost.php?p=25993&postcount=3
Тут переведенный, я просто не буду описывать весь процесс: http://habrahabr.ru/blogs/sysadm/81630/
Мой скрип:
#!/bin/sh
export smtpemailfrom=ИМЯ@ДОМЕН.ru
export zabbixemailto="$1"
export zabbixsubject="$2"
export zabbixbody="$3"
export smtpserver=smtp.gmail.com
export smtplogin=ИМЯ@ДОМЕН.ru
export smtppass=ПАРОЛЬ
export metod="tls=yes"
export port=587
/NFS/zabbix/alert.d/sendEmail.pl -f $smtpemailfrom -t $zabbixemailto -u $zabbixsubject -m $zabbixbody -s $smtpserver:$port -xu $smtplogin -xp $smtppass -o $metod
Учтите одно но:
zabbixemailto="$1" - ПРАВИЛЬНО
zabbixemailto=$1 - НЕ ПРАВИЛЬНО
Не забываем кавычки, без них тупо не работает!!!
Качаете скрип отправки с офсайта: http://caspian.dotconf.net/menu/Software/SendEmail/
Распаковываем зипчик и переносим, нам только он нужен, sendEmail.pl в /NFS/zabbix/alert.d/
Вроде бы все. Сервер готов. Осталось настроить агентов на всех серверах.
Так как у меня сервер может быть на одном из трех адресов, ну малоли общий IP не поднимется по каким то причинам, сделал вот такие манипуляции:
nano /etc/zabbix/zabbix_agent.conf
Server=192.168.0.10
nano /etc/zabbix/zabbix_agentd.conf
Server=192.168.0.10,192.168.0.11,192.168.0.12
Hostname=192.168.0.10,192.168.0.11,192.168.0.12
Следующий шаг можно пропустить. Я захотел даже агентов поместить в Pacemaker:
cp -f /usr/lib/ocf/resource.d/heartbeat/pingd /usr/lib/ocf/resource.d/heartbeat/zabbix-agent
nano /usr/lib/ocf/resource.d/heartbeat/zabbix-agent
OCF_ROOT=/usr/lib/ocf
export OCF_ROOT=/usr/lib/ocf
В начало секции:
pingd_start() {
/etc/init.d/zabbix-agent start
Оставляем родной код
}
pingd_stop() {
/etc/init.d/zabbix-agent stop
Оставляем родной код
}
Описываем наш примитив:
crm configure
primitive ZabbixA ocf:heartbeat:zabbix-agent params dampen="60s" host_list="127.0.0.1" op monitor interval="20s" timeout="120s"
clone ZabbixAgent ZabbixA
colocation zabbix_on_master inf: ZabbixAgent resFS
order zabbixagent_after_fs inf: resFS:start ZabbixAgent:start
bye
Ну и, соответственно, удаляем агента с автозагрузки:
update-rc.d zabbix-agent remove
Пока все...
Жду вопросов, дополнений и критики...
Все учту и добавлю в статью!

PS: Особую благодарность выражаю человеку с ником VanDyke с форуме sysadmins.ru за очень активное участие, основное даже так скажу)))
PSS: Если тема кому то интересна, то милости просим: http://sysadmins.ru/topic270287.html

Комментариев нет:

Отправить комментарий