Отказоустойчивые службы при помощи CARP

    Краткое введение


    Про сам протокол очень хорошо написанно в википедии. Кому интересны подробности и история — туда. В двух словах о нём можно сказать так: это протокол избыточности, который позволяет двум или более компьютерам в одной подсети иметь одновременно один и тот же IP адрес, при этом возможна настройка этой группы компьютеров как взаимозаменяемые (главный компьютер отключился/сломался – вместо него сразу же принимается за работу другой, у которого приоритет выше) и так по кругу, обеспечивая тем самым почти 100% доступность служб. СARP является «родным» для OpenBSD, FreeBSD и NetBSD. На линуксе с ядром выше 2.4 доступен через ucarp.

    Немного сумбурно, но в дальнейшем, надеюсь, ситуация прояснится.

    Окружение


    Для данного описания мною использовался Debian GNU/Linux 4.0 под VMWare ESX. Тестировать же будем сервис вебсервера Apache.

    Начало. Инсталяция


    Первым делом ставим ucarp. Под дебианом все предельно просто:

    apt-get install ucarp


    Инсталяция из сорсов тоже не должна вызвать особых сложностей

    wget download.pureftpd.org/pub/ucarp/ucarp-1.2.tar.bz2
    tar jxf ucarp-1.2.tar.bz2
    cd ucarp-1.2
    ./configure
    make
    make install


    Заодно ставим и вебсервер

    apt-get install apache2


    Конфигурация UCARP


    Основная часть конфигурации общая как для мастера так и для слейва (отличия расмотрим отдельно)

    Прежде всего создадим .conf файл в котором пропишем параметры для старта ucarp и конфигурации виртуальных интерфейсов

    mkdir /etc/ucarp
    touch /etc/ucarp/ucarp.conf


    /etc/ucarp/ucarp.conf:

    # Интерфейс на котором будет запущен ucarp
    UCARP_INTERFACE=eth0

    # Виртуальный интерфейс которому будет присвоен виртуальный ip кластера
    UCARP_IF_ALIAS=eth0:0

    # Действительный ip интерфейса. Естественно для каждого узла он будет своим.
    UCARP_SRCIP=172.16.0.11

    # CARP ID виртуального сервера
    UCARP_VHID=1

    # Интервал для сравнения узлов, в секундах.
    # Чем он меньше, тем выше приоритет слейва
    UCARP_ADVBASE=1

    # Пароль дла hmac шифрования соединения (посредством sha1).
    UCARP_PASS=geheim

    # Виртуальный ip по которому будет доступен кластер
    UCARP_ADDR=172.16.0.1

    # Маска нашего сегмента сети
    UCARP_MASK=255.255.0.0

    # Путь к скриптам которые будут запущены при активации/деактивации узла
    UCARP_UPSCRIPT=/etc/ucarp/ucarp-up.sh
    UCARP_DOWNSCRIPT=/etc/ucarp/ucarp-down.sh


    Теперь пришло время написать скрипты которые будут поднимать виртуальный интерфейс когда управление(статус мастера) будет переходить к текущему хосту и наоборот.

    cd /etc/ucarp
    touch ./ucarp-up.sh
    touch ./ucarp-down.sh


    /etc/ucarp/ucarp-up.sh

    #!/bin/bash
    source /etc/ucarp/ucarp.conf
    ifconfig $UCARP_IF_ALIAS $UCARP_ADDR netmask $UCARP_NETMASK


    /etc/ucarp/ucarp-down.sh

    #!/bin/bash
    source /etc/ucarp/ucarp.conf
    ifconfig $UCARP_IF_ALIAS down


    ucarp-up.sh будет запущен при активации узла. Параметры для алиаса, виртуального интерфейса, адреса и маски берутся из файла ucarp.conf. Как только узел теряет статус мастера, запускается ucarp-down.sh и виртуальный интерфейс отключается.

    Следующим шагом создаём скрипт для запуска самого UCARP (альтернативно можно создать инит-скрипт). Скрипт назовём start.sh и положим в /etc/ucarp.

    source /etc/ucarp/ucarp.conf

    ucarp /
    --interface=$UCARP_INTERFACE /
    --srcip=$UCARP_SRCIP /
    --vhid=$UCARP_VHID /
    --pass=$UCARP_PASS /
    --advbase=$UCARP_ADVBASE /
    --preempt /
    --addr=$UCARP_ADDR /
    --daemonize /
    --upscript=$UCARP_UPSCRIPT /
    --downscript=$UCARP_DOWNSCRIPT


    Первая строчка подключает наш конфиг ucarp.conf, все переменные берутся от туда. Опция --daemonize запускает UCARP в режиме демона. Важной является опция --preemt которая будет присутствовать только для мастера. Последним шагом делаем наши скрипты запускаемыми из под рута

    chmod 0700 /etc/ucarp/*.sh


    Что бы начать тестирование я склонировал MasterVm и внёс изменения в следующие параметры

    — ip адресс
    — Hostname
    — UCARP_SRCIP в /etc/ucarp/ucarp.conf

    также в файле /var/www/apache2-default/index.html указал название сервера, чтобы знать на какой узел попадаю.

    Поехали


    Запускаем мастера и слейва с помощью скрипта /etc/ucarp/start.sh. Так как мы указали параметер --daemonize никаких сообщений выведено не будет. Через ifconfig на мастере видем запущеный виртуальный интерфейс:

    eth0      Link encap:Ethernet  HWaddr 00:22:15:6a:80:d8
              inet addr:172.16.0.11  Bcast:172.16.255.255  Mask:255.255.0.0
              inet6 addr: fe80::250:56ff:fe82:352c/64 
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:402618 errors:0 dropped:0 overruns:0 frame:0
              TX packets:9019 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000
              RX bytes:34064624 (32.4 MiB)  TX bytes:623570 (608.9 KiB)
              Interrupt:177
    
    eth0:0    Link encap:Ethernet  HWaddr 00:22:15:6a:80:d8
              inet addr:172.16.0.1  Bcast:172.20.255.255  Maske:255.255.0.0
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              Interrupt:177


    На слейве никакого виртуального интерфейса, естественно нет, он будет запущен только при передачи статуса мастера. Статус узла ucap пишет в /var/log/syslog. Выглядит это приблизительно так:

    На мастере:

    Nov 26 03:49:17 vmdebian01 ucarp[2327]: [WARNING] Switching to state: MASTER
    Nov 26 03:49:17 vmdebian01 ucarp[2327]: [WARNING] Spawning [/etc/ucarp/ucarp-up.sh eth0]


    На слейве

    Nov 26 03:50:24 vmdebian02 ucarp[3802]: [WARNING] Switching to state: BACKUP
    Nov 26 03:50:24 vmdebian02 ucarp[3802]: [WARNING] Spawning [/etc/ucarp/ucarp-down.sh eth0]


    При обращении к виртуальному ip оказываемся на сервере номер 1 (запущеному как мастер). При отключении мастера от сети, слейв тут же меняет свой статус и запускает интерфейс который доступен по ip/mac кластера. Перезагрузка страницы в броузере показывает, что мы уже на сервере номер 2. При подключении мастера всё возвращается на свои места.

    Итог


    конечно всё вышесказанное является упрощёной версией конфигурации ucarp. в реальной жизни прийдётся также подумать и о синхронизации уровня приложений, сессий если это вебсервер, файлов в случае фтп и т.п.
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 25

      +1
      Еще есть очень классная штука — Heartbeat )
        0
        Вещщщ, однажды настраивал.)))
          0
          все бы ничего, но: получаеться что один сервер бездельничает. Если бы сделать так, что бы, например, база данных работала со slave-а, а все остальные службы с master — было бы замечательно :)
            0
            heartbeat позволяет это сделать. Правда с 2 узлами в кластере получится, что каждый из них должен во время сбоя держать нагрузку обоих.
            Но если такое недопустимо — всегда можно сделать резервирование по схеме n+1
          –2
          А какие свитчи поддерживают carp? Там же вроде одинаковые маки используются и свитч при этом не должен сойти с ума.
            +1
            Одинаковые маки не используются. Свич марштрутизирует по arp. У свича должен быть отключен port-security.
              0
              так узел отвечает arp'ом только когда ему передаётся управление. а мастер шлёт мультикаст по которому узлы определяют, что он еще жив. мастер загнулся, слейв управление перехватил, arp оповещение послал, таблицы обновились и по новой. стоит отметить, что переключение всё равно занимает время, не долгое, но может хватить, чтобы потерять пару пакетов.
              0
              чем лучше keepalived?
                0
                он не лучше, он — альтернатива. выбирает в конечном итоге админ. эмпиричиски.
                  0
                  лицензией
                    0
                    плохо что ТОЛЬКО лицензией
                  0
                  А как с этим делом в solaris?
                    0
                    В Солярисе это возложено на плечи Sun Cluster/OHAC. Есть еще ILB, но он пока только в dev билде opensolaris-а
                    0
                    поясните пожалуйста, как один из слейвов должен узнать что ему пора бы подняться?
                    и второй вопрос: как скопище слейвов поделят между собой право стать мастером?
                      +1
                      Мастер-хост группы регулярно рассылает объявления по сети, с целью оповестить остальные машины группы, что он все еще работоспособен. В случае, если резервной машиной объявление не будет получено в течение заданного интервала, то она перехватывает функции мастер-хоста (та из них, которая имеет меньшие значения UCARP_ADVBASE).
                        0
                        спасибо. теперь всё ясно!
                          0
                          Кстати, Вы говорите, что переключение происходит не мгновенно. С какой периодичностью происходит опрос, и настраивается ли это? Есть ли механизмы, позволяющие полностью исключить потерю пакетов (хитрые свичи или еще что-нибудь)?
                            +1
                            Полностью исключить потерю пакетов при любой аварии не сможет никто :)
                            Если есть такая задача, то лучше поглядет в сторону cisco content gateway. А если посчитаете их слишком дорогими — то может быть проще смириться с потерей пакетов? :)
                              0
                              Понятно, спасибо :). Пока что такой задачи не стоит, но я уверен, что она через какое-то время может возникнуть.
                              0
                              опрос — не совсем точное понятие. слейв не спрашивает мастера, он получает от него пакеты. если в определённый момент пакет не пришёл — тогда и нужно спешить на помощь. «определённый момент» настраиваится опцией --deadratio=NUM. Где num по умолчанию равен 3.
                          –1
                          Сначала прочитал как «CRAP».)))
                            0
                            Хитрый вопрос вдогонку.

                            Вот переключили мы IP. А у нас в сети стоит не тупой хаб, а средней интеллектуальности свитч, кеширующий маршруты по MAC-адресу. Данный пакет решает эту ситуацию?
                              0
                              ucarp посылает arp update, так что средней интеллектуальности свитч поймет, что IP переключился. Главное чтобы не было port-security и IP мог работать на новом порту.
                                0
                                Спасибо
                              0
                              Необходимо отметить, что данное решение работает только если мастер никак не отвечает по сети и никак не помогает когда система «прогнулась» под нагрузкой или не работает приложение. То есть например в случае reverse proxy возможна ситуация когда сервер захлебнется от большого кол-ва конектов, но при этом будет исправно отвечать на ARP при этом выключить его через carp не будет никакой возможности из-за --preempt. Единственный выход в подобной ситуации выключать мастер физически например порт на свиче.

                              Мы используем CARP в связке с внешним арбитром, который следит за тем что мастер сервер работает на уровне приложения и таким образом подстраховывает от описаного мною случая.

                              Only users with full accounts can post comments. Log in, please.