Рубрики
Без рубрики

OpenWRT failover или домашняя высокая доступность.

Высокая доступность?!! Дома?!! Да, заголовок звучит странно, но если Вы поддерживаете дома какой-то сервис, то возможно подобные мысли уже посещали и Вас. Давайте на минутку представим себе этакого крутого гика, который горит желанием хостить сайт у себя дома и взглянем на мир его глазами…

Сайт-заглушка поможет обеспечить высокую доступность

Размышления, доступность — зачем?

Конечно, если у нас есть дома публичный сайт, доступный через сеть Интернет, то нам просто необходимо иметь хорошую доступность и максимальный аптайм для него. Так что, нам ни в коем случае нельзя обижать поисковых ботов и допускать бесследную пропажу нашего сайта из Сети. Но давайте сразу договоримся, что денег на покупку всяких вкусных «плюшек» у нас нет и надо все реализовать своими силами. Наш бюджет, в лучшем случае, несколько сотен рублей в месяц. Кроме того, мы же живем не одни и кто-то еще периодически прибирает наш творческий порядок, попутно разбирая завалы из жестких дисков, контроллеров, старой денди и обязательно задевая пару из тысяч разбросанных по полу проводов. Такой подход тоже оказывает негативное влияние на работоспособность сайта. А ведь и мы иногда отключаем свои компьютеры, чтоб покопаться в них и быть может пропылесосить.

Планируем нашу высокую доступность

Итак, в простейшем варианте, наша цель заключается в обеспечении максимально высокого аптайма сайта в домашних условиях. Для начала мы отбросим все решения с резервированием сайта в пределах нашего дома, все-таки у нас не датацентр Tier 3 :). А значит нам надо поддерживать копию нашего сайта где то в «Интернетах». Тут нам на помощь может прийти, к примеру, дешевый хостинг или VPS. Также, предполагается что Интернет у нас дома раздается роутером, прошитым OpenWRT или же другой подобной прошивкой.

И реализуем доступность

Первым делом, нам необходимо разместить копию сайта на хостинге. Конечно еще будет необходимо настроить синхронизацию между Вашим домашним сайтом и его копией, но так как этот процесс сильно зависит от архитектуры сайта, то я пожалуй пропущу размышления о том, как это можно сделать и, в простейшем случае, порекомендую просто делать не копию, а сайт-заглушку, т.е. просто одну страничку со словами о нахождении сайта на техобслуживании и HTTP кодом 503.

Во вторых, реализуем механизм переключения на копию сайта в случае недоступности оригинала. Идея будет такая — через заданные промежутки времени мы проверяем доступность нашего сайта и в случае падения переводим все запросы к нему на сайт-копию. Для этого мы зайдем на роутер по ssh (или telnet) и создадим следующий скрипт:

#!/bin/sh
## Сперва зададим ряд настроек
# Определим заголовок HTTP Host для нашего сайта
HTTP_HOST="www.mysite.ru"
# Наш сайт открывается по этому адресу
HTTP_URL="http://myserver/"
# Доступность будем проверять, пытаясь найти следующую строчку в содержимом сайта
SITE_CONTENT='This is my cool site'
# Если недоступен то перенаправим все запросы на этот адрес
FAILOVER_IP="1.1.1.1"
# И на этот порт
FAILOVER_PORT="80"
# Имя WAN интерфейса роутера
WAN_IF=`uci get network.wan.ifname`


## Проверим, есть ли в iptables правила перенаправляющие запросы на сайт-копию
FAILOVER_RULE_DNAT=`iptables -L -n -t nat | grep "^DNAT.*0\.0\.0\.0/0.*$FAILOVER_IP.*80"`
FAILOVER_RULE_ACCEPT=`iptables -L -n | grep "^ACCEPT.*0\.0\.0\.0/0.*$FAILOVER_IP.*80"`

## В зависимости от этих правил мы определяем переключены ли мы на запасной IP или нет
if [[ "$FAILOVER_RULE_DNAT" ]] && [[ "$FAILOVER_RULE_ACCEPT" ]]
then
    FAILOVER="yes"
else
    FAILOVER="no"
fi

## Проверим работает ли сайт-оригинал
if [[ "`wget -O - --header 'host: $HTTP_HOST' $HTTP_URL 2>&1 | grep \"$SITE_CONTENT\"`" ]]
then
    MAINTENANCE="no"
else
    MAINTENANCE="yes"
fi

## Если оригинал не работает и мы не переключились на копию, то выполняем переключение
## Если же сайт работает, но мы переключены, то убираем переключение
if [[ $MAINTENANCE = "yes" ]] && [[ $FAILOVER = "no" ]]
then
    iptables -t nat -A prerouting_rule -i $WAN_IF -p tcp --dport www -j DNAT --to-destination $FAILOVER_IP:$FAILOVER_PORT
    iptables -A forwarding_rule -i $WAN_IF -p tcp --dport www -d $FAILOVER_IP -j ACCEPT
    logger -t FAILOVER "Looks like website down! Failing over to failover page!"
elif [[ $MAINTENANCE = "no" ]] && [[ $FAILOVER = "yes" ]]
then
    iptables -t nat -D prerouting_rule -i $WAN_IF -p tcp --dport www -j DNAT --to-destination $FAILOVER_IP:$FAILOVER_PORT
    iptables -D forwarding_rule -i $WAN_IF -p tcp --dport www -d $FAILOVER_IP -j ACCEPT
    logger -t FAILOVER "Website up! Failing back to primary site!"
fi

 Теперь, все что осталось, это добавить запуск этого скрипта в cron, выполняем команду crontab -e  и добавляем следующую строку:

*/1 * * * * /root/bin/http_failover.sh

Вот и все! Спасибо за внимание! Успехов в достижении высокой доступности!

Добавить комментарий

Ваш адрес email не будет опубликован.