ucarp: повышаем отказоустойчивость.

Со временем, когда офисная сеть разрастается, приходиться задумываться о резервировании серверов, информации. Если у вас большая корпорация, то вы скорее всего будете использовать кластерные решения. А что делать, если у вас нет средств для этого? Ответ на этот вопрос даёт утилита ucarp.

Примечание: если ваше оборудование поддерживает VRRP, то лучше использовать его (более гибкий, больше возможностей), нежели CARP.

Если у вас FreeBSD 10 и не работает нормально carp, то это скорее всего известная проблема. С другой стороны, есть так же проблемы  в 9.Х

0) Введение

Что же такое ucarp? Представим, что у вас есть 2 сервера и вы хотите, что бы в случае выхода одного из них, в работу вступал другой. За этим следит демон ucarp. В нужный момент он подменяет IP-адреса у резервного сервера на те, которые были у основного. Примем такие понятия: master — основной, backup — резервный сервера. Сам ucarp поддерживает 2 режима preempt: YES и NO.

YES означает (он устанавливается на master’e ) что, при выходе master’a его место займёт backup. Если после ремонта master включить в сеть, то ему обратно будут переданы полномочия «главного».

NO означает, что текущий master будет оставаться им так долго, как это возможно. То есть если backup перехватил полномочия master’a, то обратно master получит свои полномочия только после выхода из строя backup’a.

В данной статье я буду настраивать с preempt=»NO» (по умолчанию).

Схема работы: имеем 2 сервера с адресами (нужны для связки) 10.0.3.11, 10.0.3.12 и IP-адрес, который будет использоваться как основной для доступа 10.0.3.15. Время переключения 10 секунд. Запускать будем как демоны

1) Установка.

Установка достаточно проста: обновляем порты и делаем следующее:

#cd /usr/ports/net/ucarp && make install clean

После установки создасться только стартовый скрипт в /usr/local/etc/rc.d. Никаких конфигов, манов не будет. Доступна будет лишь справка по команде ucarp -h.

2) Параметры

Ниже приведу некоторые важные параметры. Остальные можно посмотреть через ucarp -h.

ucarp_if - физический интерфейс, который будет слушать ucarp
ucarp_vhid - ID для принадлежности серверов к одной группе (1-255)
ucarp_src - IP адрес сервера
ucarp_addr - общий адрес, который и будет подхватываться
ucarp_advbase - время переключения в секуднах
ucarp_upscript - скрипт, который выполняется при установке сервера master'om
ucarp_downscript - скрипт, который выполняется при установке сервера backup'om

3) Настройка.

Настройка master’a и backup’a ничем существенным не отличается (кроме ip— адресов и имён интерфейсов). В любом случае ниже привожу конфиги:

===master===

Добавляем в /etc/rc.conf

ucarp_enable="YES"
ucarp_if="rl0"
ucarp_vhid="5"
ucarp_pass="dumbp4ss"
ucarp_preempt="NO"
ucarp_facility="daemon"
ucarp_src="10.0.3.11"
ucarp_addr="10.0.3.15"
ucarp_advbase="10"
ucarp_upscript="/scripts/ucarp.up"
ucarp_downscript="/scripts/ucarp.down"

Создаём файл конфигурации /usr/local/etc/ucarp.conf

/usr/local/sbin/ucarp \
-i rl0 \
-v 5 \
-p dumbp4ss \
-f daemon \
-B -P -z \
-s 10.0.3.11 \
-a 10.0.3.15 \
-u /scripts/ucarp.up \
-d /scripts/ucarp.down \
-b 10

Скрипт поднятия интерфейса (не забываем сделать его исполняемым) ucarp  /scripts/ucarp.up

#!/bin/sh
source /usr/local/etc/ucarp.conf
/sbin/ifconfig rl0 alias 10.0.3.15/32

Скрипт перевода в режим down интерфейса (не забываем сделать его исполняемым) /scripts/ucarp.down

#!/bin/sh
source /usr/local/etc/ucarp.conf
/sbin/ifconfig rl0 -alias 10.0.3.15

===backup===

Добавляем в /etc/rc.conf

ucarp_enable="YES"
ucarp_if="rl0"
ucarp_vhid="5"
ucarp_pass="dumbp4ss"
ucarp_preempt="NO"
ucarp_facility="daemon"
ucarp_src="10.0.3.12"
ucarp_addr="10.0.3.15"
ucarp_advbase="10"
ucarp_upscript="/scripts/ucarp.up"
ucarp_downscript="/scripts/ucarp.down"

Создаём файл конфигурации /usr/local/etc/ucarp.conf

/usr/local/sbin/ucarp \
-i rl0 \
-v 5 \
-p dumbp4ss \
-f daemon \
-B -P -z \
-s 10.0.3.12 \
-a 10.0.3.15 \
-u /scripts/ucarp.up \
-d /scripts/ucarp.down \
-b 10

Скрипт поднятия интерфейса (не забываем сделать его исполняемым) /scripts/ucarp.up

#!/bin/sh
source /usr/local/etc/ucarp.conf
/sbin/ifconfig rl0 alias 10.0.3.15/32

Скрипт перевода в режим down интерфейса (не забываем сделать его исполняемым) /scripts/ucarp.down

#!/bin/sh
source /usr/local/etc/ucarp.conf
/sbin/ifconfig rl0 -alias 10.0.3.15

так получилось, что у меня на обеих серверах оказались одинаковые сетевушки rl0. В вашем же случае — они могут быть разными, будьте внимательны!

4) Запуск и проверка работы.

Теперь запускаем ucarp на обеих серверах:

#/usr/local/etc/rc.d/ucarp start

Через 10 секунд должен подняться алиас на master’e. Смотрим ifconfig на обеих серверах:

===на master’e===

$ ifconfig rl0

rl0: flags=8843 metric 0 mtu 1500
options=8
ether 00:80:1e:10:77:63
inet 10.0.3.11 netmask 0xffffff00 broadcast 10.0.3.255
inet 10.0.3.15 netmask 0xffffffff broadcast 10.0.3.15
media: Ethernet autoselect (10baseT/UTP)
status: active

===на backup’e===

$ ifconfig rl0

rl0: flags=8843 metric 0 mtu 1500
options=8
ether 00:15:f2:de:d5:73
inet 10.0.3.12 netmask 0xffffff00 broadcast 10.0.3.255
media: Ethernet autoselect (10baseT/UTP)
status: active

Как видим, на master’e появился алиас.

При первом запуске master/backup выбираются случайным образом. Если хотите конкретно указать, кто должен быть кем, сначала запустите ucarp на master’e, затем на backup’e.

А вот, что отображается в /var/log/messages при переключении:

Mar  3 17:49:16 srv1 ucarp[1025]: [WARNING] Switching to state: BACKUP
Mar  3 17:49:16 srv1 ucarp[1025]: [WARNING] Spawning [/scripts/ucarp.down rl0 10.0.3.15]
Mar  3 17:49:46 srv1 ucarp[1025]: [WARNING] Switching to state: MASTER
Mar  3 17:49:46 srv1 ucarp[1025]: [WARNING] Spawning [/scripts/ucarp.up rl0 10.0.3.15]

5) Ложка дёгтя.

1) Есть одна ложка дёгтя в этой бочке мёда: если остановить службы (корректно) ucarp на обеих серверах, то общий IP пропадёт. Если же просто прибить процес ucarp — то алиас останеться. Это происходит по тому, что при остановке службы выполняется скрипт ucarp.down, в котором явно прописано удалять алиас.

Лучше всего поставить какую-то проверку на запуск этой службы и проверку доступности IP.

2) При изменении шлюза, сессии обрываются. Что бы такого не происходило — нужно использовать pfsync.

3) Если вы используете IPSec, то для этих целей нужно дополнительно использовать sasyncd.

Примечание.

1) Вместо up/down скриптов можно использовать утилиту ifstated (портированную из OpenBSD), которая находиться в /usr/ports/net/ifstated. Она очень функциональная. Подробнее о ней можно прочесть из man.

2) А ещё можно использовать udev для мониторинга интерфейса ucarp:

$less /etc/devd.conf
...

notify 30 {
match "system"		"IFNET";
match "subsystem"	"carp0";
match "type"		"LINK_UP";
action "/scripts/ucarp_switch.sh active";
};

notify 30 {
match "system"          "IFNET";
match "subsystem"       "carp0";
match "type"            "LINK_DOWN";
action "/scripts/ucarp_switch.sh backup";
};

Дополнение

Аналогичный функционал имеет демон relayd, который был изобретён для OpenBSD и портированный во FreeBSD. Он умеет мониторить сетевые хосты, балансировать нагрузку и выступать в роли прокси-сервера.

Опубликовано с разрешения журнала root.ua

ucarp: повышаем отказоустойчивость.: 13 комментариев

  1. Добрый

    Bsd’ый carp умеет еще и балансировать, а ucarp могёт? Вы не пробовали случаем?

    1. skeletor Автор записи

      Не пробовал, но если вы попробуете — обязательно отпишитесь.

      1. Добрый

        Да я все найти не могу есть ли балансировка у ucarp’а вообще, или же нету((( весь инет прерыл ничего не нашел! Такое впечатление что только у bsd carp’а эта функция есть.

  2. Николай

    Совсем не понятно следующее:
    — зачем в BSD, при наличии device carp ( можно на него сделать KLDLOAD, но вот собирать придется) использовать UCARP. потому как
    — UCARP не делает общего мака ( получаем простой от обновления ARP кешей)
    — UCARP не умеет балансить нагрузку ( CARP от BSD это делает вполне корректно — правда на основе маков)
    — UCARP либо не интегрируется, либо интегрируется не тривиально ( не нашел как) с PF
    — UCARP не корректно работает с ifstated при более чем одном резервированном адресе на машине.
    — У многих сервисов ( пример postfix и bind ) не возможно корректно примапить сервисы к адресу UCARP в состоянии backup

    1. skeletor Автор записи

      >>> — UCARP не делает общего мака ( получаем простой от обновления ARP кешей)
      что мешает присваивать МАС+IP сразу в скрипте?
      >>> — UCARP не умеет балансить нагрузку ( CARP от BSD это делает вполне корректно – правда на основе маков)
      Ну, как бы, это его не основная задача.
      >>> — UCARP либо не интегрируется, либо интегрируется не тривиально ( не нашел как) с PF
      что за интеграция? используйте якоря
      >>> — UCARP не корректно работает с ifstated при более чем одном резервированном адресе на машине.
      Не пробовал, не в курсе: может так и на самом деле, а может проблема только у вас. Для каких целей используете ifstarted? Разве нельзя это сделать через rc.conf?
      >>> — У многих сервисов ( пример postfix и bind ) не возможно корректно примапить сервисы к адресу UCARP в состоянии backup
      А в чём сложность перезапустить сервис после появления нового ИПа?

      Итого, из приведённого выше, особых преимуществ не увидел. Разве что, можно запихнуть в ядро, что бы работало быстрее + балансировка.

  3. Николай

    Идея менять мак на лету просто потрясающа! особенно учитывая что все варианты UP/DOWN скиптов срабатывают ПОСЛЕ переключения. — то есть вы получите либо ( на тупых китайских свитчах — срабатывание LBD и один из портов будет погашен) либо на, приличных свитчах, очень матерную запись в логи.
    Балансить нагрузку — очень важный бонус, который позволяет выдержать в ЧНН состояние почтового релея для клиента, можно это решить конечно балансером, только вопрос стоимости решения вылезет на первое место.
    PF — и PFSYNC используют очень часто когда создают фермы доступа ( nat) фермы, фаерволы ( можно продолжать анализировать состояние соединения, открытого на другом сервере) .
    про ifstated — не только у меня, но не копал глубоко.
    Дернуть сервис ? — извините… почта перевзлетает менее секунды, радиус когда много конфигов и большие БД — до 10 секунд, BIND когда на нем много зон первичных — до 20 секунд… — это деградация сервиса, осознанно допущенная. К которой надо добавить время обработки CARP сообщений..
    Цели — запасные сервера всего что попалось под руку в стуктуре провадера доступа Интернет и Телефонии.
    ifstated все же следит за состоянием интерфейса, rc.conf, вроде бы, описывает систему и переменные старта..
    А преимущество одно — скорость обработки + если сервис в ядре, то вероятность выпасть с рабочей машины почти 0

    1. skeletor Автор записи

      ucarp — это не Enterprice решение, учтите. И попытки получить 0% downtime вообще не стоит рассматривать. Обычно для таких целей простой до 3-5 минут считается нормальным. И не надо требовать от ucarp сильно многого, он не рассчитан на это. Это раз.
      Во-вторых, проблему с MAC-адресами — можно решить нормально. Тупые свичи никак на это не отреагируют (проверено). А умные — можно настроить на нужные МАСи, а так же политику порта.
      В третьих, требовать от него балансировку — неправильно, так как он этого просто не умеет. Так что упрёки — не к месту.
      В чётвёртых, если используете carp/ucarp, учтите первую рекомендацию. Более того, тупо использовать тот же bind в такой схеме, как минимум неправильно. Логичнее использовать bind+mysql (перегрузка идёт считанные секунды) или powerdns (тоже самое) или nsd.

      ПС. Если же хотите получить 0% downtime, то carp/ucarp вам точно не подходит. А если есть небольшая погрешность, то с остальными недостатками можно смириться.
      Я не пытаюсь сказать, что он лучше. Просто есть ситуации, когда он вообще не применим.

  4. Николай

    на предмет что все carp и им подобные не промышленное, спор будет с кошкой — vrrp считается вполне промышленным решением для некоторых случаев.
    SLA 100% несбыточная мечта, но осознанно вводить дополнительное время простоя — мягко выражаясь не логично.
    Про свитчи — не совсем так, можно на нормальном железе вполне можно сплясать нечто, что позволит не заметить оного флапа, а вот на китайцах — не факт ( могу показать noname железку которая будет ловить петлю, при этом она в любой части сети, когда пути разные будет вести себя так).
    Про bind+SQL — я не знаю сколько бы у меня грузилось из файла, такое время получается именно из базы. ( и на очень приличном железе).. а менять его, когда наличествует множество view — не на что ..
    А про погрешность — если у меня bind успевает подхватится за время меньшее стандартного повтора по таймуту, то сервис не потерян, если не успевает — есть потеря.
    А весь смысл моих слов — нафига использовать покупной молоток ( внешний порт) , когда такой же, но с более удобной ручкой и встроенной отверткой есть в комплекте инструмента.. ( модуль ядра)

    1. skeletor Автор записи

      Я писал тогда про него, так как не знал про carp.

      А вообще, дублирование того же DNS’a множеством slave’ов полностью решает проблемы падения и недоступности master’a 🙂 Точно так же можно дублировать и другой сервис, тот же exim/postfix позволяют это делать в режиме master-slave.

  5. Николай

    Чего — то зацепило, почитал доки потестировал .. , очень короткие выводы ( системы голые — не тюнились FreeBSD 9.0 32)
    — производительности хватает у обоих с избытком на большинство сервисов, раньше явно ляжет сервис, который они обслуживают.
    — из неожиданных и забытых плюсов UCARP — позволяет гонять внешний адрес используя фейки как адреса интерфейсов. ( о множестве плюсов ядреного CARP я тут долго писал) .
    Про сервера DSN — можно наставить кучу slave ( у нас их 4- ре ), только куча тупых клиентов ( замечено за роутерами Asus), если им введено два DNS будут долбиться по очереди — время ответа ощутимо возрастет.. ( это про кешируюшие сервера). Авторитативные стоят в схеме 2+1 ( скоро все это перееедет на схему в двумя серыми серверами и одним внешним — станет проще).
    Что я не помню — чтобы postfix или exim могли нормально гонять между собой IP ( сервис именно исходящей почты SMTP out). Ну и входящую на MX полагаться можно, но стоит минимизировать ( очень тупые бывают политики перепосыла)..

    P.S. умение UCARP обходится только одним адресом ( который и бегает между интерфейсами) — дорогого стоит .. ( особенно когда провайдер жаден)

  6. Николай

    Может пригодтся ( в формате Wiki, писалось очень давно) — отдаю:), хотя это чтение man и двух статей..

    Нижеизложенное  в части конфигурирования  применимо и проверялось на FreeBSD

    == Что такое  CARP ==

    CARP — Common Address Redundancy Protocol.  Протокол создан для использования одного IP адреса в одном сегменте сети несколькими машинами в режиме отказоустойчивости. Идеи CARP взяты  из протокола VRRP v2, который описан стандартом RFC2338.

    == Общие принципы работы протокола ==

    При работе протокола методами  голосования из всех маших, находящихся в группе избыточности назначается мастер, который и отвечает на все запросы  к отказоусточивому IP адресу. Для работы с этим  адресом  выделяется отдельный MAC адрес. В одном  езернет сегменте  может быть не более 254 групп отказоустойчивости. 

    == Конфигурирования для запуска ==

    CARP работает как модуль ядра.

    Внимание — модуль не собран  по умолчанию, то есть  без пересборки ядра или отдельной сборки модуля,  не может быть запущен  при помощи kldloadПри сборке есть только один  параметр — ‘device CARP’, указываюший вкомпилить модуль в ядро.

    == Системные  перемененные, от которых зависит поведение  модуля ==

    (указаны значение, рекомендованные  для «боевой»  эксплуатации)

    net.inet.ip.same_prefix_carp_only=0  запрещает находится в одной группе адресам из разных шикоровешательных сегментов.net.inet.carp.allow=1 принимать  входящие пакеты  CARPnet.inet.carp.preempt=1 разрешает взаимное  резевирование  хостовnet.inet.carp.log=1 уровень логирования (0-нет, 2-  смена состояний CARP, 1 -ошибочные пакеты передачи) net.inet.carp.arpbalance=1 разрешает работу  с резервированием MAC адреса ( сохранение  IP будет сопровождаться сменой  MAC адреса) net.inet.carp.=0 по умолчанию хост стартует  с параметром Backup

    Внимение, параметры  являются изменяемыми в процессе  работы системы ( не «read only»), но все эти параметры считиваются модулем  при  загрузке системы, то есть  при изменении этих параметров, для изменения поведение  потребуется выгрузить/загрузить модуль.

    == Конфигурирование  CARP для запуска. ==

    ===== Замечания, и параметры конфигурирования: =====

    CARP создается как отдельный  интерфес и относится к клонированным интерфейсам. В отличии  от реализаций  CARP  в других OS во FreeBSD не предусмотрен  параметр carpdevice, а привязка  CARP  к физическому или  виртуальному интерфейсу осуществляется по роутингу.

    ===== Доступные  параметры  для конфигурирования: =====

    carpN —  имя виртуального интерейса ( n от 1 до 255)vhid — номер группы избычтости (не имеет отношения  к приоритетам срабатывания),  все  интерфейсы одной  группы избыточности на  на всех хостах должны иметь равный vhid)pass — пароль для  шифрования передаваемой  информации advbase — интервал обновлений  группы  — время через которое  текущий мастер отправляет извещения о своем  существовании в секундах ( от  1  до 240) по умолачнию 1  advskew- задержка  в попытке объявить себя MASTER ( в секудах) —  параметр должен  быть не меньше чем  (advbase)-  позволяет  контролировать порядок взятия на себя MASTER для интерфейса. По умолчанию 2.

    ===== записи в rc.conf  для запуска (пример) =====

    Задача — создать три  CARP интерфейса, которые  всегда будут работать на хосте1, а  при его отказе  переходить на хост2, интерфейсы избыточности: 10.1.1.1, 10.1.2.1. 10.1.3.1

    предположим, что у нас  есть физический интрефейс em0 c ip 10.1.1.253/24, vlan1 и vlan2 соотвественно 10.1.2.253/24 и 10.1.3.253/24

    соответсвующая часть  rc.conf для хоста MASTER по умолчанию
    ifconfig_em0=»inet 10.1.1.253/24′
    cloned_interfaces=»vlan1 vlan2 carp1 carp2″
    ifconfig_vlan1=»inet 10.1.2.253/24 vlan 2 vlandev em0″
    ifconfig_vlan2=»inet 10.1.3.253/24 vlan 3 vlandev em0″
    ifconfig_carp1=»inet 10.1.1.1/24 vhid 1 pass mekmitasdigoat advskew 1″
    ifconfig_carp2=»inet 10.1.2.1/24 vhid 1 pass mekmitasdigoat advskew 1″
    ifconfig_carp3=»inet 10.1.1.1/24 vhid 1 pass mekmitasdigoat advskew 1″

    Для хоста BACKUP (описывать  физические  интерфейсы  не буду — ясно из примера)
    ifconfig_em0=»inet 10.1.1.254/24′
    cloned_interfaces=»vlan1 vlan2 carp1 carp2″
    ifconfig_vlan1=»inet 10.1.2.254/24 vlan 2 vlandev em0″
    ifconfig_vlan2=»inet 10.1.3.254/24 vlan 3 vlandev em0″
    ifconfig_carp1=»inet 10.1.1.1/24 vhid 1 pass mekmitasdigoat advskew 2″
    ifconfig_carp2=»inet 10.1.2.1/24 vhid 1 pass mekmitasdigoat advskew 2″
    ifconfig_carp3=»inet 10.1.1.1/24 vhid 1 pass mekmitasdigoat advskew 2″

    == Работа протокола ==

    При включении и активизации интерфейса, в зависимости от состояние  переменной net.inet.carp.suppress_preempt хост либо становится master ( при adwskew =1) либо бэкап ( если adwskew>1 или net.inet.carp.suppress_preempt=0).Хост назначенный в данным  момент MASTER  постоянно рассылает ( по всем  доступным  интерфейсам  с интервалом advdase) широковещательное  сообщение на адрес 224.0.0.18, в сообщение  содержится номер группы.Если хост назначенный BACKUP не получит  извещений от MASTER в течении времени  указанного  у него в конфигурации CARP как adwskew он  становится master — рассылает об этом широковещательное  сообщение  на тот же  224.0.0.18. при  осуствии  в течении времени  adwskew ответа что  кто — то  принимает на себя  фунции мастера и  у него меньше  adwskew —  рассылает широковещательное  сообщение  arp —  «ошибочный GW», по которому MAC адрес  CARP интерфейса  теперь находится на его порту.

    Если хост назначенный  Backup видит что широковещательные сообщения приходят с хоста у которого нижк adwskew  но сам  начинает рассылать сообщения о  желании стать MASTER для CARP.

    MAC адрес «боевого» CARP интерфейса выглядит как 00:00:5e:00:01:xx где xx это vhid carp группы ( интересно все же копаться в исходниках)

    == Остлеживание изменения состояния CARP ==

    Задача: В случае, если в какой-то из групп CARP выходит из строя основной хост, и какой-то из резервных хостов принимает на себя роль основного (MASTER), то необходимо отослать об этом уведомление через Nagios. Также необходимо отсылать уведомления при возвращении резервного хоста в состояние (BACKUP).

  7. aprogrammer

    Спасибо за статью. Очень полезная штука — настраивал под Ubuntu (http://sysadm.pp.ua/linux/carp-ubuntu.html) кластер из трех серверов — до сих пор на проде работает. Не подскажите, если ли возможность(технология) для geodistributed redundent IP, может сталкивались ? Заранее спасибо.

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *