It-e.RU
Цифровой двигатель вашего бизнеса.

Отказоустойчивость FreeBSD с помощью устройства carp

Отказоустойчивость FreeBSD с помощью устройства carp

Устройство CARP (Common Address Redundancy Protocol) пришло в FreeBSD из OpenBSD. Это протокол избыточности, который позволяет нескольким системам, находящимся в одной логической и физической сети иметь одновременно один и тот же адрес, при этом эти системы могут быть взаимозаменяемыми или разделяющими нагрузку на сервис.


Устройство CARP (Common Address Redundancy Protocol) пришло в FreeBSD из OpenBSD. Это протокол избыточности, который позволяет нескольким системам, находящимся в одной логической и физической сети иметь одновременно один и тот же адрес, при этом эти системы могут быть взаимозаменяемыми или разделяющими нагрузку на сервис. Запустим интерфейс carp: соберем ядро с опцией:

    device carp

либо подгрузим модулем: и в /boot/loader.conf:

if_carp_load="YES"

Теперь необходимо определить каким образом будет работать наш кластер. Для этого необходимо настроить значения системных переменных sysctl в файле /etc/sysctl.conf:

net.inet.carp.allow - Разрешить работу с carp пакетами, включено по умолчанию.
net.inet.carp.preempt - Посылать сигнал отключения интерфейсов carp, при штатном отключении системы. 
                        По умолчанию выключено.
net.inet.carp.log - Значение 0 - выключает любое логирование. Значение 1 - включает логирование порченых 
                    carp пакетов. Любое значение больше 1 - включает логирование состояния интерфейсов carp. 
                    По умолчанию значение 1.
net.inet.carp.arpbalance - Включает балансировку трафика, используя протокол arp. По умолчанию выключено.
net.inet.carp.suppress_preempt - OID доступный только для чтения, показывающий состояние главного узла. 
                                 Значение 0 означает, что активен главный узел. Каждое изменине увеличивает 
                                 значение OID.

Вообщем, если коротко, то для работы кластера в режиме мастер-бекап необходимо переменной net.inet.carp.preempt дать значение 1. Для работы же в режиме распределения нагрузки, переменной net.inet.carp.arpbalance дать значение 1.

Настроим rc.conf на системе 1:

cloned_interfaces="carp0"
ifconfig_carp0="vhid 1 advskew 0 pass my_password 192.168.2.10 255.255.255.0"

Настроим rc.conf на системе 2:

cloned_interfaces="carp0"
ifconfig_carp0="vhid 1 advskew 10 pass my_password 192.168.2.10 255.255.255.0"

 

  • vhid - это номер группы, в которой работает интерфейс
  • pass - это пароль для аунтификации в группе
  • advskew - это вес конкретной системы в группе, чем ниже , тем главнее

 

Перезагружаемся... Видим ifconfig carp0 на мастер системе:

carp0: flags=49 metric 0 mtu 1500
	inet 192.168.2.10 netmask 0xffff0000 
	carp: MASTER vhid 1 advbase 1 advskew 0

ifconfig carp0 на запасной системе:

carp0: flags=49 metric 0 mtu 1500
	inet 192.168.2.10 netmask 0xffff0000 
	carp: BACKUP vhid 1 advbase 1 advskew 10

Теперь рассмотрим настройку carp командами в консоли

 

  • Как ранее описывалось, настроим загрузку carp

Настриваем резервирование сетевого адреса.

  • Настроим переменные sysctl:
        sysctl net.inet.carp.preempt=1
    
    в /etc/sysctl.conf
        net.inet.carp.preempt=1
    
  • Настроим сетевой адрес, принадлежащим одной сети, интерфейса каждого из группы.
  • Создаем интерфейс carp и присваеваем ему сетевой адрес. Именно этот адрес и будет резервироваться в порядке в соответствии с значением параметра advskew
  • системе 1
        ifconfig carp0 create
        ifconfig carp0 vhid 1 advskew 0 pass my_password 192.168.2.10 255.255.255.0
    
    системе 2
        ifconfig carp0 create
        ifconfig carp0 vhid 1 advskew 10 pass my_password 192.168.2.10 255.255.255.0
    
    Перерь сетевой адрес 192.168.2.10 255.255.255.0, будет резервироваться системой 2. При этом значение carp будет меняться на MASTER.

    Настраиваем распределение нагрузки.

  • Настроим переменные sysctl:
        sysctl net.inet.carp.arpbalance=1
    
    в /etc/sysctl.conf
        net.inet.carp.arpbalance=1
    
  • Настроим сетевой адрес, принадлежащим одной сети, интерфейса каждого из группы.
  • Создаем интерфейс carp и присваеваем ему сетевой адрес. Именно этот адрес и будет резервироваться в порядке в соответствии с значением параметра advskew
  • системе 1
        ifconfig carp0 create
        ifconfig carp0 vhid 1 advskew 0 pass my_password 192.168.2.10 255.255.255.0
    
    системе 2
        ifconfig carp0 create
        ifconfig carp0 vhid 1 advskew 10 pass my_password 192.168.2.10 255.255.255.0
    
    Терерь на сетевой адрес 192.168.2.10 255.255.255.0 системы 1 и 2 будут отвечать по очереди.

    Можно применять несколько интерфейсов carp для обеспечения резервирования и балансировки. То есть в режиме резервирования, вы делаете 2 интерфейса - один мастер, второй слейв. Соответвенно, получаются 2 адреса, которые зарезервированы и сервис работает между ними. В режиме балансировки также делаете 2 интерфейса, но в разными значениями advskew.

    Дополнительно: синхронизация серверов при изменении состояния интерфейса carp.

    Просто резервирования адресов часто не хвататет, необходимо резервировать данные, с которыми работает резервируемый сервис. Поэтому можно синхронизировать системы, например, через rsync. А можно выполнять некие скрипты при изменении состояния интерфейсов.

  • Проверим, что все необходимые директории подключены в файле /etc/devd.conf
  •     # grep directory /etc/devd.conf
        # Each “directory” directive adds a directory to the list of
        directory “/etc/devd”;
        directory “/usr/local/etc/devd”;
    

     

  • vi /usr/local/etc/devd/do_notify.conf ( ОЧЕНЬ ВАЖНО: файл обязательно должен иметь суффикс .conf )
  •     notify 30 {
        match “system” “IFNET”;
        match “subsystem” “carp0″;
        match “type” “LINK_UP”;
        action “/usr/local/scripts/notify.sh up”;
        };
        notify 30 {
        match “system” “IFNET”;
        match “subsystem” “carp0″;
        match “type” “LINK_DOWN”;
        action “/usr/local/scripts/notify.sh down”;
        };
    

     

  • vi /usr/local/scripts/notify.sh
  •     #!/bin/sh
    
        state=$1
        echo `date` $state >> /var/log/carp_state.log
    

     

  • /etc/rc.d/devd restart

  • Скрипты можно выполнять, например, при подключении ресурса HAST. В FreeBSD 9 пока что, к сожалению, не работает ucarp с vlan, поэтому и родилась это небольшое дополнение и эта заметка.
    Надеюсь кому-то этот труд будет полезен.

 


Пожалуйста, уважайте труд автора, при копировании материалов сохраняйте ссылку на источник!

Комментарии (3)

  1. Ярослав:
    сен 20, 2013 at 05:59

    Прокомментируйте пожалйста разницу в настройке "резервирование сетевого адреса" и "распределение нагрузки" В данный момент я вижу абсолютно идентичную настройку. Ваше "распределение нагрузки" работает как "резевирование адреса" и net.inet.carp.arpbalance не помогает в этом случае.

  2. makky:
    сен 23, 2013 at 09:14

    Заметка писалась по ману в практическими примерами. Вот выдержка из мана, которая вас интересует:

    When the hosts receive an ARP request for 192.168.1.10, the source IP
    address of the request is used to compute which virtual host should
    answer the request. The host which is master of the selected virtual
    host will reply to the request, the other(s) will ignore it.

    This way, locally connected systems will receive different ARP replies
    and subsequent IP traffic will be balanced among the hosts. If one of
    the hosts fails, the other will take over the virtual MAC address, and
    begin answering ARP requests on its behalf.

    То есть обе машины или сколько их в кластере будут отвечать с одним и тем же виртуальным адресом. Очень важно понимать, что арп-балансировка будет работать только в локальной сети, потому что только локально ходят arp-пакеты. То есть локальная машина, обратившись к вашему кластеру, получила ответ от какой-то из нод, и записала это в своей таблице физических адресов. Следующий пакет уже будет балансироваться. В глобальной сети такое не пройдёт, поэтому и придуманы балансировщики. То есть смысл в том, что у каждого хоста физические значение адреса вашего кластера будет разным. Глубоких тестов такой настройки с различным сетевым оборудованием я не проводил, но думаю, что оно, для такой конфигурации, также требует настройки.

    За замечание спасибо, я видимо плохо пояснил значение этой переменной - исправлю.

  3. ssergey:
    авг 14, 2014 at 10:04

    Доброго времени
    на системе
    uname -a
    FreeBSD srv 10.0-RELEASE FreeBSD 10.0-RELEASE #2:
    выдало следущее:
    root@srv[/root]# /etc/rc.d/devd restart
    Stopping devd.
    Waiting for PIDS: 498.
    Starting devd.
    devd: Cannot parse /usr/local/etc/devd/do_notify.conf at line 2
    ./etc/rc.d/devd: WARNING: failed to start devd







Разрешённые теги: <b><i><br>Добавить новый комментарий: