Стойкий админ. Строим отказоустойчивые сети в Linux с keepalived

VRRP, несмотря на неясную ситуацию с патентами Cisco, остается стандартным протоколом для горячего резервирования маршрутизаторов. Популярный в системах семейства BSD протокол CARP свободен от патентных ограничений, но статус стандарта и поддержка со стороны многих поставщиков имеют свои преимущества — есть по крайней мере теоретическая возможность сменить поставщика незаметно для пользователей сети. Мы рассмотрим, как настроить отказоустойчивый маршрутизатор на основе Linux. В качестве реализации VRRP мы будем использовать keepalived.

Протокол VRRP

VRRP расшифровывается как Virtual Redundancy Router Protocol. Группа физических маршрутизаторов объединяется в один виртуальный. Каждый участник группы может находиться в трех состояниях: неопределенном (initialize), основном (master) и резервном (backup). У всех участников в настройках присутствует один или несколько виртуальных адресов. У основного эти адреса присвоены сетевой карте, а у остальных — просто ждут своего часа.

Прежде всего нужно сказать, что VRRP работает поверх IP, а не напрямую поверх канального уровня. Если быть точным, он использует групповой (multicast) адрес 224.0.0.18. Поскольку multicast по умолчанию не маршрутизируется, взаимодействие возможно только в пределах одной физической сети.

Это значит, что, помимо общего виртуального адреса, каждому маршрутизатору на каждом сетевом интерфейсе, где ты настраиваешь VRRP, должен быть присвоен основной, с которого он будет отправлять соседям служебные пакеты.

Нужно сразу сказать, что основной (служебный) адрес совсем не обязан быть из одной сети с виртуальными. Если у тебя недостаточно публичных адресов для тех сетевых карт, которые смотрят в интернет, ты вполне можешь использовать частные адреса из RFC 1918 в качестве служебных. Ну, если настройки твоего провайдера этого не запрещают.

У каждой группы маршрутизаторов есть VRID — Virtual Router Identifier. Это просто число в диапазоне от 1 до 255. С каждой группой может быть ассоциирован один или несколько виртуальных адресов. На уровне протокола список адресов передается, но только для отладочных целей. Процесс VRRP их никак не использует, тем более что передаются они без маски подсети, так что за идентичностью настроек виртуальных адресов нужно следить самому.

Группы с разным VRID друг с другом не взаимодействуют, поэтому в одной физической сети может быть несколько независимых групп резервирования, главное — настроить.

При загрузке или первичной настройке VRRP участники группы оказываются в неопределенном состоянии (initialize) и выбирают, кому быть основным, а кому резервным. В настройках VRRP можно указать приоритет (priority) — маршрутизатор с наибольшим приоритетом выигрывает выборы.

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

Маршрутизатор, который выбрали основным, присваивает своей сетевой карте виртуальные адреса и начинает рассылать остальным пакеты VRRP advertisement. Таким способом он сообщает, что еще жив и работоспособен.

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

Что будет, если бывший основной маршрутизатор вернется к жизни? Все зависит от опции preempt в настройках. Если она включена, то он снова инициирует выборы и вернет себе былую славу. Если нет, так и останется резервным.

Включать или не включать preempt — дело вкуса. С одной стороны, с этой опцией легко предсказать, какой маршрутизатор в данный момент основной, а с другой — переключений состояния, а значит, и потерянных пакетов будет больше. Я обычно включаю, но свое мнение никому не навязываю.

Настраиваем keepalived

Перейдем от теории к практике. В первую очередь нам потребуется пакет keepalived. Его функциональность шире, но сегодня мы сосредоточимся именно на VRRP. Этот пакет есть в репозиториях у всех популярных дистрибутивов, так что с его установкой сложностей быть не должно.

Сценарий будет такой: два маршрутизатора, rtr-master со служебным адресом 192.0.2.1 и rtr-backup с адресом 192.0.2.2. В качестве виртуального адреса возьмем 192.0.2.254, а VRID установим в 10. Будем считать, что служебные адреса настроены на сетевом интерфейсе eth0.

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

Даниил Батурин: @dmbaturin Координатор проекта VyOS (https://vyos.io), «языковед», функциональщик, иногда сетевой администратор

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

  • Отказоустойчивость маршрутизатора(ов) это очень хорошо. А вот как отказоустойчиво физически подключить к двум маршрутизаторам одного (двух, трёх...) интернет провайдеров? Если через какой то промежуточный коммутатор то разве мы просто не переносим единственную точку отказа на этот самый коммутатор, тем самым никак не решая вопрос отказоустойчивости?

    • отказоустойчивость это комплекс мер

    • В самом простом варианте можно сделать отдельное физическое соединение между маршрутизаторами (можно с LACP для большей отказоустойчивости) и сделать им маршруты друг через друга с большей метрикой, чем у маршрута через провайдера.

    • С одной стороны, в статье рассматривается отказоустойчивость именно маршрутизаторов. И, если уж есть потребность в построении VRRP - наверное и провайдеров уже есть несколько.

      С другой:
      а) коммутатор, конечно будет еще одной точкой отказа. Если провайдер один - возможно есть смысл получить от него же второй физический линк - по другой витой паре или второму волокну, оговорив вопрос наличия двух маршрутизаторов. Таким образом вы перенесете точку отказа на коммутатор провайдера. А от работоспособности его Вы и так зависите.

      б) если провайдеров несколько - то есть смысл использовать стек коммутаторов ядра, в который заводить lacp от каждого провайдера и уже к этому стеку подключать маршрутизаторы (тоже по lacp), на которых и поднимать VRRP. Однако это дополнительные затраты.