4. Настройка EVPN Multihoming
Второй и третий уровень в нашей EVPN-сети мы настроили, но что если на наших клиентах крутятся Очень Важные Сервисы, и нам необходимо зарезервировать подключение для таких серверов не только на уровне линка, но и на уровне коммутатора?
Нам на помощь придет родная встроенная функциональность для подключения клиента к VTEP множественными линками - EVPN Multihoming. Также его еще называют "ESI Multihoming" или "ESI LAG". Все эти термины обозначают одно и то же. EVPN Multihoming может работать как в режиме All-Active (все линки могут быть активны и передавать unicast-трафик одновременно) или в режиме Single-Active, когда активен только один линк, а второй находится в горячем резерве.
В отличие от проприетатных решений на основе MLAG, EVPN Multihoming не требует отдельного peer-link и не накладывает жесткого ограничения на максимальное количество PE-устройств, обслуживающих multihomed-систему (хотя количество поддерживаемых устройств для организации резервируемого подключения зависит от реализации у конкретного вендора). Также в теории должна наличествовать межвендорная совместимость, но это в теории, а практика, увы, зачастую доказывает обратное. Однако у EVPN Multihoming есть и недостаток - огромное количество дополнительных маршрутов RT-1 (в дополнение к RT-4), а ASIC'и не резиновые :)
Multihomed-системой со стороны клиента может выступать как L3-узел (сервер, маршрутизатор), так и L2-узел (коммутатор). В том случае, когда клиентской системой является коммутатор, и при этом используется модель работы All-Active, то линки, ведущие к VTEP'ам, обязательно должны быть аггрегированы в LAG. Либо же, если LAG использовать не представляется возможным, в конкретном VLAN должен быть одновременно активен только один линк.
Для работы Multihoming в EVPN задействуются два новых типа маршрутов: RT-1 (Ethernet Auto-Discovery Route) и RT-4 (Ethernet Segment Route). RT-1 помогает VTEP'ам динамически обнаруживать соседей, подключенных в один и тот же сегмент (+ эта информация используется для организации функциональности ECMP, предотвращения возникновения L2-петель и т.д.). RT-4 нужен для организации выбора Designated Forwarder'а для сегмента - то есть VTEP'а, который в режиме работы Multihoming All-Active будет иметь право передавать BUM-трафик в сегмент.
Сегмент в данном случае - это набор линков, ведущих к одной и той же клиентской системе. Или, иначе, набор линков, которыми конкретная клиентская система подключается к EVPN-сети. Каждый сегмент в EVPN имеет идентификатор ESI (Ethernet Segment Identifier). Single-homed-сегмент всегда имеет ESI 0. Multi-homed-сегмент имеет ESI > 0.
В стандартном сценарии на multihomed-клиенте настраивается обычный агрегированный канал - LAG, например, на основе широко применяемого протокола 802.3ad (LACP).
Клиенты, адреса и топология
Здесь нам снова придется немножко изменить нашу топологию. От каждого клиента дополнительно пробросим еще один линк в сторону дублирующего Leaf'а. Первого и второго клиента мы посадим в один L2-домен, третьего и четвертого клиента посадим в другой L2-домен.

IRB-интерфейсы на Leaf'ах:
Leaf-1
192.168.10.254/24
10
Leaf-2
192.168.10.254/24
10
Leaf-2
192.168.20.254/24
20
Leaf-3
192.168.20.254/24
20
MAC, IP-адреса, VLAN, VNI клиентов, подключенных к Leaf-устройствам:
Client-1
02:00:00:00:01:bb
192.168.10.1/24
10
Client-2
02:00:00:00:02:bb
192.168.10.2/24
10
Client-3
02:00:00:00:03:bb
192.168.20.3/24
20
Client-4
02:00:00:00:04:bb
192.168.20.4/24
20
VXLAN:
10
1010
1:1010
20
1020
1:1020
L3VNI для VRF1 будет назначен на VNI 1000, RT будет 1:1000.
Идентификаторы ESI, LACP MAC'и и route target'ы для RT-4:
Client-1
0000:0000:0000:0000:0001
00:00:00:00:00:01
02aa.aaaa.0001
Client-2
0000:0000:0000:0000:0002
00:00:00:00:00:02
02aa.aaaa.0002
Client-3
0000:0000:0000:0000:0003
00:00:00:00:00:03
02aa.aaaa.0003
Client-4
0000:0000:0000:0000:0004
00:00:00:00:00:04
02aa.aaaa.0004
Настройка
Опять же, настройка Spine у нас никак не меняется, поэтому снова описывать ее не будем. Давайте сразу перейдем к настройке лифов. Сбросим на них настройки overlay, то есть вернемся к тому состоянию, когда у нас был настроен underlay - я приведу начальную конфигурацию для каждого лифа, и оттуда уже начнем настраивать.
Настройка Leaf-1
Начальная конфигурация, с которой мы начинаем настройку (настроен underlay):
А теперь к настройке EVPN.
Создадим VLAN 10, в котором будут у нас сидеть Client-1 и Client-2:
Создадим клиентский VRF и сразу включим для него маршрутизацию:
Создадим LAG-интерфейсы, которые будут смотреть в сторону клиентов. В сторону каждого из клиентов на этом лифе будет смотреть одна нога (вторая будет на соседнем Leaf'е - ведь у нас ESI LAG):
Здесь мы выполняем важные для функционирования multihoming настройки, поэтому давайте поподробнее остановимся на том, что мы вообще здесь делаем.
Помимо перевода интерфейса в режим VLAN 10 Untagged, мы здесь задаем MAC-адрес LACP-канала с помощью команды lacp system-id. Он должен быть одинаковым на обоих Leaf'ах-членах Port-Channel'а. Это нужно для того, чтобы клиент считал, что оба его LAG-линка ведут к одному устройству (он ведь ничего не знает ни про какие мультихоминги, для него канал выглядит как совершенно обычный агрегированный канал).
Также в этой секции мы задаем две настройки, связанные с multihomed-Ethernet-сегментом: идентификатор сегмента (ESI) и Route target сегмента. Идентификатор сегмента будет уникально обозначать данный линк как часть глобально (в рамках фабрики) уникального набора линков, ведущих к одной и той же клиентской multihomed-системе, или даже, точнее, к одному клиентскому подключению (сайту). Благодаря ненулевому идентификатору сегмента наши VTEP'ы будут четко понимать, кто еще из EVPN-пиров смотрит в этот же сегмент, или, другими словами, подключен к этой же клиентской системе.
На основе идентификатора сегмента будет сгенерирован маршрут RT-1 (Ethernet Auto-Discovery Route), который будет использоваться VTEP'ами для обнаружения соседей, смотрящих в этот же сегмент, с целью предотвращения закольцовывания BUM-трафика и для ECMP. ECMP означает следующее: неважно, с какого VTEP'а был получен RT-2 маршрут: другие VTEP'ы в фабрике будут знать, что трафик до конкретной системы в конкретном Ethernet-сегменте можно отправить на любой VTEP, имеющий подключение к этому же самому Ethernet-сегменту. Такое поведение называется Aliasing. В случае использования схемы Single-Active, линки до дублирующих VTEP'ов будут использоваться как резервные.
Также в этой секции мы задаем ES-Import Route Target. Назначение этого комьюнити требуется для генерации и приема маршрутов RT-4 (Ethernet Segment Route). Благодаря этому комьюнити VTEP'ы, подключенные к одному сегменту, будут импортировать маршруты RT-4, относящиеся к этому ESI.
Вообще, маршрут RT-4 нужен для того, чтобы VTEP'ы, подключенные к одному сегменту, смогли выбрать Designated Forwarder'а, то есть VTEP, которому будет разрешено пересылать BUM-трафик в ES-сегмент (нужно для предотвращения дублирования BUM-трафика в сторону клиентской системы, ведь все VTEP'ы, подключенные к сегменту, получат из overlay-сети, от удаленного VTEP, по отдельной копии BUM-пакета, и в обычной ситуации каждый бы отправил свою копию в сторону клиента).
Здесь особенно важно помнить, что VTEP'ы, не являющиеся DF, не имеют права отправлять трафик в сегмент, но на BUM-трафик, полученный из сегмента, от multihomed-клиента, подобных ограничений не налагается, и такой трафик может быть передан без какой-бы то ни было оглядки на статус DF/Non-DF. Более того, существует еще правило, называемое "локальным предпочтением" (local bias). Оно гласит, что VTEP имеет право пересылать BUM-трафик, полученный с собственных физических access-портов, в локально подключенный multihomed-сегмент вне зависимости от своего статуса DF/Non-DF. Что, в-общем-то, логично. Зачем гонять трафик по фабрике, когда мы физически подключены к сегменту назначения, а трафик, который нужно переслать в сегмент, был порожден нашими же локальными клиентами?
На этом настройки, связанные непосредственно с Multihoming, закончены :). Идем дальше.
Назначим физические линки к клиентам в Port-Channel'ы (сделаем их членами LAG):
"mode active" означает, что мы будем активно пытаться установить LACP-соседство вместо того, чтобы пассивно ожидать, пока нас позовут его оформить с другой стороны :).
Настроим IRB-интерфейсы, нужно для обеспечения маршрутизации из нашего VNI. Задаем IP-адрес шлюза по умолчанию (он же Static Anycast Gateway). Этот интерфейс назначаем в наш VRF1:
Настраиваем плоскость данных VXLAN. Указываем, откуда брать Source IP для VXLAN-пакетов (с Loopback'а), задаем соответствие vlan 10 и vni 1010. Создаем L3VNI путем назначения VRF1 на "виэнайку" 1000.
Зададим Anycast MAC для наших IRB-интерфейсов. В нашей схеме Anycast IP/Anycast MAC он должен быть одинаковым на всех IRB-интерфейсах конкретного VNI:
Включим отсылку расширенных комьюнити для EVPN (Route Target'ы, всякие Router's MAC'и и т.д.):
Пропишем для нашего MAC-VRF, относящегося к VLAN 10, соответствующий RD и RT (RD, точнее, не пропишем, а попросим Аристу генерировать его автоматически). Включим распространение информации о локально подключенных хостах в EVPN с помощью команды redistribute learned.
Активируем AFI/SAFI EVPN для нашего процесса MP-BGP:
Ну и последнее - зададим RD и RT для нашей L3VNI:
Общий вид настроек, которые мы только что задали:
Всё. Остальные коммутаторы Leaf настраиваем по той же схеме. Буду приводить только общий вид настроек, без объяснения каждой конкретной опции, чтобы не повторяться об одном и том же.
Настройка Leaf-2
Начальная конфигурация:
Конфигурация с настроенным overlay и multihoming'ом, согласно нашим задачам.
Лишь вкратце скажу, что мы на Leaf-2 на клиентских портах Po1 и Po2 настраиваем вторую ногу LAG для клиентов, которые также подключены к Leaf-1, а на портах Po3 и Po4 - одну из ног для клиентов Client-3 и Client-4.
Настройка Leaf-3
Начальная конфигурация:
Конфигурация overlay с подключением клиентов с услугой multihoming:
На этом лифе мы настраиваем вторую ногу LAG для клиентов Client-3 и Client-4.
Приведу еще настройки клиентов. Тут ничего необычного - виртуалки на основе Alpine Linux, настройки выполнены в файле /etc/network/interfaces, создан LACP LAG на двух интерфейсах, смотрящих в разные VTEP'ы.
Настройка Client-1
Настройка Client-2
Настройка Client-3
Настройка Client-4
Проверки
Предлагаю не проверять сейчас каждую мелочь, а проверить только основной статус BGP (соседство), проверим маршруты RT-1, RT-2, RT-4, разберем, все ли в порядке с нашими ESI, а потом проверим пингами доступность всех клиентов друг до друга. И напоследок - погасим по очереди один и другой линк на одном из клиентов и проверим, будет ли отрабатывать переход трафика с упавшего линка на уцелевший.
С учетом того, что Spine с точки зрения мультихоминга нас особенно не интересуют, давайте сразу проверять лифы.
Проверка Leaf-1
Давайте в первую очередь проверим состояние LAG'ов для наших клиентов: Client-1:
Client-2:
Каналы до клиентов подняты, все, вроде бы, в порядке.
Маршрутов BGP у нас сейчас должно быть достаточно большое количество, поэтому давайте проверим их по отдельности.
RT-3:
IMET-маршруты мы должны увидеть от каждого VTEP'а для каждого VNI. Тут в принципе все предсказуемо - один IMET мы генерируем сами (VNI 1010), две штуки получаем от Leaf-2 (10.1.1.2) - ведь у него настроены VNI 1010 и VNI 1020. Подробней тут смотреть не вижу смысла. А, ну и ECMP тоже присутствует, как и должно быть - у нас ведь два Spine, через которые мы ходим до других Leaf'ов.
RT-1 (Ethernet A-D Route):
Вот тут посмотрим поподробнее. VTEP'ы должны сгенерировать по одному маршруту RT-1 для каждого EVI и еще один RT-1 общий для Ethernet-сегмента (без привязки к EVI).
Каждый маршрут несет в себе идентификатор сегмента - ESI. Видим маршруты, сгенерированные для VNI, а также маршруты с VNI: 0 - это маршруты, сгенерированные для ESI, то есть общие для сегмента. Маршрут per-ESI нужен для обеспечения функциональности fast convergence & mass withdrawal: если у нас падает линк в сегмент, мы отзываем данный маршрут, и все другие VTEP'ы понимают, что любые EVI, доступные в данном сегменте через этот VTEP, становятся недоступными, и трафик слать через этот VTEP в них не стоит. нужно скорректировать next-hop'ы для всех маршрутов, касающихся данного ESI, а если подходящих VTEP'ов не осталось, инвалидировать эти маршруты.
Взглянем еще раз кратко, чтобы убедиться, что все маршруты на месте (так будет нагляднее):
RT-4 (Ethernet Segment route):
Здесь мы можем видеть наш RT "ES-Import-RT", который позволяет нашему VTEP'у импортировать маршруты RT-4 только для тех сегментов, которые на нем настроены.
Обычный вывод:
RT-2 (MAC/IP Advertisment route)
Ну и посмотрим подробно на маршруты MAC/IP, чтобы убедиться, что идентификатор ESI в них соответствует тому, что мы настроили:
Клиенты видны в своих персональных ESI-сегментах, с чем их и поздравляем.
Остальные проверки
Проверим, как выглядит наш EVI:
Здесь появились некоторые новые сущности - а именно, мы видим ES-Import RT, заданный для сегмента, режим Multihoming'а - All-Active (режим по умолчанию), также из интересного мы здесь видим, какой из VTEP'ов является Designated Forwarder'ом для конкретного сегмента, а который им не является.
Тут вроде бы ничего неожиданного.
Видим, что с 10.1.1.3 у нас нет общих VNI, поэтому пересылать на него BUM-трафик мы не будем (туннель flood не построен).
Посмотрим L2 RIB:
Видно двух наших локально подключенных клиентов. За своими Port-Channel'ами.
Проверим таблицу маршрутизации VRF1:
Видим, что клиенты из VNI 1020 доступны через транзитный L3VNI 1000 по нескольким путям (Leaf-2 и Leaf-3).
Проверка Leaf-2
Проверим состояние LAG'ов для наших клиентов:
Наши LAG'и работают :)
Пройдемся по маршрутам:
RT-3
RT-1
RT-4
И RT-2
Остальное
EVI:
Все выглядит в порядке.
L2RIB:
Все 4 клиента видны как локальные.
Таблица маршрутизации:
Обе сети у нас являются локально подключенными, поэтому здесь весьма пусто, никаких интересных прилетевших по BGP маршрутов нет.
Проверка Leaf-3
Проверим состояние LAG'ов для наших клиентов:
Наши LAG'и работают :)
Пройдемся по маршрутам:
RT-3
RT-1
RT-4
RT-2
Остальное
EVI:
Все выглядит в порядке.
L2RIB:
Таблица маршрутизации:
Client-1 и Client-2 видны за Leaf-1 и Leaf-2.
Проверка связности между клиентами
Проверять будем таким образом. Сначала мы на клиенте делаем пинг всех других клиентов (проверим таким образом передачу трафика intra-VNI и inter-VNI). После этого мы запустим пинг с Client-1 до Client-4, а на Client-4 попеременно будем отключать оба линка и проверять, что трафик перетекает на уцелевший линк.
Client-1
ping Client-2 (intra-VNI)
ping Client-3 (inter-VNI)
ping Client-4 (inter-VNI)
ARP-таблица Client-1:
Видим Client-2, находящегося с нами в одном сегменте, а также свой шлюз.
Client-2
ping Client-1 (intra-VNI)
ping Client-3 (inter-VNI)
ping Client-4 (inter-VNI)
ARP-таблица:
Client-3
ping Client-1 (inter-VNI)
ping Client-2 (inter-VNI)
ping Client-4 (intra-VNI)
ARP-таблица:
Client-4
ping Client-1 (inter-VNI)
ping Client-2 (inter-VNI)
ping Client-3 (intra-VNI)
ARP-таблица:
Проверка резервируемости
Давайте запустим на Client-1 пинг Client-4, а затем на Client-4 сначала отключим одну ногу, затем включим ее обратно и отключим вторую. Пинги должны восстановиться после некоторого периода.
Сначала проверим, через какую ногу идет пинг:
Это интерфейс "eth0" на Client-4.
На "eth1" трафика нет.
Пинг идет таким путем:

Теперь отключим eth0:

Пинг прервался, но после некоторого (длительного) перерыва - восстановился. Что ж поделаешь, виртуалки...
Посмотрим, идет ли трафик теперь по eth1:
Идет! Путь трафика изменился на такой:

То есть резервируемость у нас работает.
С чистой совестью переходим к последней части нашей настройки - инжектированию внешних маршрутов в overlay-сеть.
Last updated