1)Итак написал свой скрипт /etc/ha.d/resource.d/cluster:
#!/bin/bash
#Узлы кластера
nodes='ADAM EVA'
#Запущенные домены на узле ADAM
ADAM='mt'
#Запущенные домены на узле ADAM
EVA='ast zer'
#Аргументы командной строки
command=$1
for node in $nodes; do
if [ "$node" = "$(uname -n)" ];then
SELF=$node
else
PEER=$node
fi
done
#Функция через которую выполняю каманды, а она отслеживает где должны выполняться команды на локальном хосте или по ssh
function line {
command=$1 #команда
node=$2 #Получаем имя узла на котором находимся сейчас
if [ "$node" = "$(uname -n)" ]; then #Работать с доменами на локальной машине
#echo "(running command '$command' on localhost)"
$command
else #Работать с доменами на удаленной машине через ssh
#echo "(running command '$command' on remote node '$node')"
ssh root@$node $command
fi
}
function ping_node {
ping -c1 -w1 $1 1>/dev/null 2>&1
}
function is_migration {
case "$(drbdadm cstate $1)" in
Connected|SyncSource|SyncTarget)
return 0
;;
*)
return 1
echo "$1 is disconnected, NOT safe to migrate"
;;
esac
}
function is_status_domain {
node=$1
domain=$2
output=($(line "virsh list --all" $node | grep $domain))
echo ${output[2]}
}
function disk {
mode=$1 #start|stop
node=$2
resource=$3
case $mode in
"start")
line "drbdadm primary $resource" $node 2>&1
;;
"stop")
line "drbdadm secondary $resource" $node 2>&1
;;
esac
echo $(line "drbdadm role $resource" $node 2>&1) $(line "drbdadm cstate $resource" $node 2>&1)
}
function print_status {
echo -e "Узел\tДомен\tХозяин\tDRBD роль\t\tDRBD состояние\tСостояние"
domains=$(echo ${!SELF} ${!PEER})
for domain in $domains; do #Перебираем массив доменов
for NODE in $nodes; do
if echo ${!NODE} | grep $domain 1>/dev/null; then
x="*"
else
x=""
fi
role=$(line "drbdadm role $domain" $NODE 2>&1)
cstate=$(line "drbdadm cstate $domain" $NODE 2>&1)
domstate=$(is_status_domain $NODE $domain)
echo -e "$NODE\t$domain\t$x\t$role\t$cstate\t$domstate"
done
done
}
function start_domains {
#Обрабатываем входные параметры
case $(echo $1) in
all)
#Запускаем на этом узле все домены
domains=$(echo ${!SELF} ${!PEER})
;;
*)
#Запускаем домены локальной машины
domains=${!SELF}
;;
esac
for domain in $domains; do
echo "Стартую домен $domain на узле $SELF..."
echo -n "Поиск домена $domain на локальном узле ($SELF): "
case $(is_status_domain $SELF $domain) in
"работает")
echo "Домен уже работает"
continue
;;
"приостановлен")
echo "Домен приостановлен"
echo -n "Восстанавливаю сотояние домена $domain на локальном узле ($SELF): "
echo $(line "virsh resume $domain" $SELF)
continue
;;
"выключен")
echo "Домен выключен"
echo -n "Переключаю режим DRBD ресурса $domain на узле $SELF: "
echo $(disk start $SELF $domain)
echo -n "Запускаю домен $domain на локальном узле ($SELF): "
echo $(line "virsh start $domain" $SELF)
continue
;;
*)
echo "Домен не определен"
echo -n "Анализирую возможность живой миграции с узла $PEER: "
#Проверяем несколько условий, если хотя бы одно ложно то живая миграция не возможна
#1)Пингуем узел 2)Проверяем cstate диска DRBD
if ping_node $PEER && is_migration $domain; then
#Все нормально живая миграция возможна
echo "yes"
#Проверяем состояние домена на удаленном узле
echo -n "Проверяю состояние домена $domain на узле $PEER: "
case $(is_status_domain $PEER $domain) in
"работает")
echo "работает"
echo "Миграция..."
#Переводим DRBD диск домена в состояние Primary
echo -n "Переключаю режим DRBD ресурса $domain на узле $SELF: "
echo $(disk start $SELF $domain)
echo -n "Запускаю живую миграцию домена $domain с узла $PEER на узел $SELF: "
output=$(line "virsh migrate --live $domain qemu+ssh://$SELF/system" $PEER 2>&1)
if [ "$output" == "" ]; then
echo "ок"
else
echo $output
fi
echo -n "Переключаю режим DRBD ресурса $domain на узле $PEER: "
echo $(disk stop $PEER $domain)
continue
;;
"приостановлен")
echo "приостановлен"
echo -n "Разрушаю домен $domain на узле $PEER: "
echo $(line "virsh destroy $domain" $PEER)
if [ "$(is_status_domain $PEER $domain)" == "выключен" ]; then
echo -n "Удаляю определение домена $domain на узле $PEER"
echo $(line "virsh undefine $domain" $PEER)
fi
echo -n "Переключаю режим DRBD ресурса $domain на узле $PEER: "
echo $(disk stop $PEER $domain)
;;
"выключен")
echo "выключен"
echo -n "Удаляю определение домена $domain на узле $PEER"
echo $(line "virsh undefine $domain" $PEER)
echo -n "Переключаю режим DRBD ресурса $domain на узле $PEER: "
echo $(disk stop $PEER $domain)
;;
*)
echo "не обнаружен"
echo -n "Переключаю режим DRBD ресурса $domain на узле $PEER: "
echo $(disk stop $PEER $domain)
;;
esac
else
echo "down"
fi
echo -n "Переключаю режим DRBD ресурса $domain на узле $SELF: "
echo $(disk start $SELF $domain)
echo -n "Создаю домен $domain на узле $SELF: "
echo $(line "virsh create /home/cluster/$domain.domain" $SELF)
esac
done
}
function stop_domains {
#Обрабатываем входные параметры
case $(echo $1) in
all)
#Запускаем на этом узле все домены
domains=$(echo ${!SELF} ${!PEER})
;;
*)
#Запускаем домены локальной машины
domains=${!SELF}
;;
esac
for domain in $domains; do
echo "Останавливаю домен $domain на узле $SELF..."
echo -n "Поиск домена $domain на узле $SELF: "
case $(is_status_domain $SELF $domain) in
"работает")
echo "Домен работает"
echo -n "Останавливаю домен $domain на узле $SELF: "
echo $(line "virsh shutdown $domain" $SELF)
local n=0
while [ $n -lt 5 ]; do
if [ "$(is_status_domain $SELF $domain)" == "работает" ]; then
echo -n "."
sleep 1
else
echo "ok"
break
fi
n=$(expr $n + 1)
done
if [ "$(is_status_domain $SELF $domain)" == "работает" ]; then
echo " timeout"
echo -n "Разрушаю домен $domain на узле $SELF: "
echo $(line "virsh destroy $domain" $SELF)
if [ "$(is_status_domain $SELF $domain)" == "выключен" ]; then
echo -n "Удаляю определение домена $domain на узле $SELF"
echo $(line "virsh undefine $domain" $SELF)
fi
fi
echo -n "Переключаю режим DRBD ресурса $domain на узле $SELF: "
echo $(disk stop $SELF $domain)
continue
;;
"приостановлен")
echo "Домен приостановлен"
echo -n "Разрушаю домен $domain на узле $SELF: "
echo $(line "virsh destroy $domain" $SELF)
if [ "$(is_status_domain $SELF $domain)" == "выключен" ]; then
echo -n "Удаляю определение домена $domain на узле $SELF"
echo $(line "virsh undefine $domain" $SELF)
fi
echo -n "Переключаю режим DRBD ресурса $domain на узле $SELF: "
echo $(disk stop $SELF $domain)
continue
;;
"выключен")
echo "Домен выключен"
echo -n "Удаляю определение домена $domain на узле $SELF"
echo $(line "virsh undefine $domain" $SELF)
echo -n "Переключаю режим DRBD ресурса $domain на узле $SELF: "
echo $(disk stop $SELF $domain)
continue
;;
*)
echo "Домен не определен"
echo -n "Переключаю режим DRBD ресурса $domain на узле $SELF: "
echo $(disk stop $SELF $domain)
continue
;;
esac
done
}
function usage {
echo "Usage: $0 CFG start|stop|status"
exit 1
}
#Обработчик переданных аргументов
case $command in
start)
start_domains $2
;;
stop)
stop_domains $2
;;
status)
print_status
;;
*)
usage
;;
esac