2. Настройка EVPN L2 VXLAN

Итак, мы разобрались с underlay-сетью. Давайте приступим к настройке самого интересного - EVPN.

В этой части мы предположим, что наши клиенты находятся в одной IP-подсети. Следовательно, они должны иметь связность друг с другом на втором уровне. Для этого нам необходимо взять все четыре широковещательных домена и объединить их в единый VN-сегмент с идентичным VNI. Это самый простой вариант работы EVPN/VXLAN и его мы настроим первым, так как он является некой "базой" для всех последующих сценариев и режимов работы.

Отдельных нейборов для BGP-сессий для EVPN мы прописывать не будем, а просто активируем AFI L2VPN, SAFI EVPN в рамках уже установленных IPv4-BGP-сессий, которые мы создавали для underlay. Таким образом и Underlay и EVPN будут работать в рамках одной и той же сессии и с одними и теми же соседями.

RFC 8365 описывает две модели сервиса, или, если сказать проще - две модели маппинга EVPN Instance (EVI) на L2-домены, в которых живут конечные клиенты. Первый способ - VLAN-Based, когда на каждый отдельный VLAN на устройстве создается отдельный инстанс EVPN и, следовательно, отдельная таблица MAC-VRF. Таким образом Route target в EVPN будет идентифицировать конкретный L2-домен, и для каждого L2-домена потребуется свой Route Distinguisher и Route Target. Второй способ - VLAN-Aware Bundle, когда множество VLAN'ов мапятся на один EVPN-инстанс. Route target в таком случае идентифицирует уже не конкретный L2-домен, а "тенанта" и все его VLAN'ы. В модели VLAN-Aware Bundle MAC-VRF разбивается на подтаблицы, которые содержат MAC-адреса, принадлежащие конкретным VNI. Внутри MAC-VRF они не смешиваются, так как каждому MAC соответствует свой идентификатор VNI (похоже на то, как работает VLAN-Aware Bridge в Linux). Для идентификации конкретного L2-домена в маршрутах EVPN заполняется поле Ethernet Tag ID, в которое и подставляется номер VNI. Подробнее о моделях сервиса можно прочитать здесь: RFC 8365.

Что же нам выбрать?

VLAN-Based:

  • За: Простая и наглядная конфигурация, маппинг 1 к 1 всего: VLAN -> VNI -> MAC-VRF -> RD/RT. Очень наглядно и удобно.

  • Против: На каждый VLAN создается собственный MAC-VRF. Конфигурация уникальных RD/RT на каждый L2-домен (ну RD ладно, он и автоматически неплохо прописывается). RT же лучше задавать вручную - во-первых, нам важно какое-то осмысленное значение, во-вторых могут быть сюрпризы с автоназначением RT, если железки будут их генерировать в разном формате. Меньше всего хочется траблшутить проблемы, вызванные какими-то несовпадениями RT. Вообщем, RT лучше задать вручную.

  • Против: Из первого пункта вытекает (потенциально) большая загруженность плоскости управления из-за необходимости обработки целой кучи отдельных EVI (MAC-VRF). Например, тысяча VLAN'ов будет равняться тысяче MAC-VRF.

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

VLAN-Aware:

  • за: На все VLAN'ы конкретного клиента мы создаем один MAC-VRF, один RD и один RT. VLAN'ы отделяются друг от друга внутри MAC-VRF с помощью под-таблиц. Плоскость управления обрабатывается проще (в теории). Плоскость управления понимает, какой подтаблице принадлежит маршрут (MAC) с помощью поля Ethernet Tag ID в маршруте, в которое помещается значение VNI. На плоскости данных принадлежность определяется номером VNI.

  • против: VTEP'ы будут принимать маршруты даже для тех VLAN'ов тенанта, которые на них не настроены (RT-то совпадает!). Но большой ли это минус? К сожалению, не готов ответить. Будем считать, что он просто есть, а его значительность определит каждый для себя лично.

Лично мне больше симпатичен и нагляден подход VLAN-Based, поэтому его и будем настраивать.

BUM-трафик будем рассылать с помощью механизма Ingress Replication (копируем пришедшие от клиента BUM-пакеты и рассылаем их копии юникастом на удаленные VTEP, на которых есть соответствующий VNI). Таким образом нам не понадобится дополнительно организовывать маршрутизацию мультикаст-трафика в underlay-сети.

Определимся с адресацией для клиентов. В рамках нашего L2-сервиса мы поместим всех наших клиентов в один широковещательный домен, то есть обеспечим им связность друг с другом на 2-ом уровне. Помним, что линки между коммутаторами у нас L3, а, следовательно, без VXLAN-туннелирования нам не обойтись.

Каждый клиент будет находиться в VLAN 100 на своем коммутаторе.

Клиент
MAC
IP/Mask

Client-1

02:01:00:00:00:01

192.168.100.1/24

Client-2

02:01:00:00:00:02

192.168.100.2/24

Client-3

02:01:00:00:00:03

192.168.100.3/24

Client-4

02:01:00:00:00:04

192.168.100.4/24

Ассоциация VLAN:VNI

VLAN
VNI

100

1100

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

Топология:

Топология L2 VXLAN

Настройка

Я подробно опишу конфигурацию только для Spine-1 и Leaf-1. Все остальные коммутаторы будут настроены максимально похоже и для них будут приведены лишь распечатки нужных команд.

Настройка Spine-1

В принципе, вся настройка на Spine сведется к активации address-family EVPN и включению поддержки расширенных комьюнити, которые нам необходимы для передачи route-target'ов, которые из себя и представляют эти самые расширенные комьюнити. Без Route target'ов ни один Leaf не установит информацию о хостах в свой MAC-VRF, так как именно по RT определяется, какому MAC-VRF должна принадлежать данная маршрутная информация.

Сразу получаем в консоль сообщение, как ресетнулись наши BGP-сессии:

Ну и на этом настройка Spine-1 закончена. Переходим к Spine-2 :)

Настройка Spine-2

Все ровно то же самое.

Настройка Leaf-1

А вот тут уже начинается интересное.

Во-первых, создадим VLAN 100, где сидит Client-1:

Теперь настроим физический порт, в который подключен клиент. Здесь мы задаем описание порта и указываем, что порт принадлежит VLAN 100, и трафик должен отправляться и приниматься нетегированным. Также мы включаем интерфейс (до этого он был административно отключен).

Теперь настроим интерфейс VXLAN. Здесь мы указываем, что VTEP Source IP-адрес нужно брать с интерфейса Loopback0 (помните, тот самый 10.1.1.1, который мы анонсируем в underlay). Этот IP-адрес будет использоваться как внешний Source IP в VXLAN-пакетах. Далее мы задаем соответствие VLAN 100 к VNI 1100, как бы соединяя их перемычкой или мостом. Трафик из VLAN 100 при выходе из VXLAN-интерфейса должен инкапсулироваться в VNI 1100 и наоборот, при получении пакета из overlay-сети, мы декапсулируем его из VXLAN и направляем в порты VLAN'а 100.

Теперь настроим нашу MAC-VRF:

Немножко пояснения. Значение RD (Route Distinguisher) нужно для того, чтобы зауникалить маршруты к одному и тому же префиксу, но которые принадлежат разным VRF. Чтобы BGP не пытался выбрать какой-то один из них как best path и установить только его в FIB, мы и делаем эти маршруты уникальными с помощью задания значения RD. RD можно задавать в нескольких форматах, и они описаны в RFC, но, по сути, BGP не парсит эту информацию и не пытается разобрать структуру RD - для него это просто некое значение, делающее конкретный маршрут уникальным.

Route target'ы нужны для того, чтобы принимающий VTEP знал, в какой VRF установить ту или иную маршрутную информацию. Политика экспорта из VRF на анонсирующем VTEP должна совпадать с политикой импорта в VRF назначения на принимающем VTEP. Например VTEP1 анонсирует маршруты для некоего EVI с export RT 1:1. VTEP2 установит их именно в тот MAC-VRF, на который настроена политика import RT 1:1. Если же такого MAC-VRF нет (ни на одном MAC-VRF не настроена политика import RT 1:1), то такой маршрут установлен на локальном VTEP не будет.

Значит, в блоке выше мы настраиваем MAC-VRF для VLAN 100. Route Distinguisher зададим как auto, потому что механизм генерации RD у аристы по умолчанию нас вполне устраивает (LoopbackIP:VID). Далее мы задаем route-target как 100:100 (как на импорт, так и на экспорт), таким образов уникально обозначив конкретный MAC-VRF в пределах нашей фабрики. Ну и напоследок даем указание распространять в EVPN информацию о всех изученных локально хостах в данном VLAN.

Теперь включим AF EVPN в настройках процесса BGP и активируем отсылку расширенных комьюнити:

Общий вид наших настроек EVPN:

Всё. Остальные коммутаторы Leaf настраиваем по тому же принципу. Буду приводить только распечатку настроек EVPN для Leaf-2 и Leaf-3.

Настройка Leaf-2

Настройка Leaf-3

На этом настройку можно считать законченной. Сейчас все клиенты должны иметь связность друг с другом на 2-ом уровне.

Проверки

На коммутаторах посмотрим, правильно ли применились наши настройки, все ли маршруты в наличии. Также мы должны убедиться, что все клиенты видят друг друга на 2-ом уровне. Чтобы это сделать, проверим связность клиентов пингами и посмотрим ARP-таблицы.

Проверка Spine-1

Посмотрим общее состояние BGP:

Все в порядке. С каждым соседом у нас установилась сессия в L2VPN EVPN.

Проверим, какие маршруты мы получаем в AFI EVPN:

Что мы тут видим? Во-первых, от каждого лифа мы получаем по одному IMET RT-3 маршруту. RT-3 генерируется для каждого VNI отдельно и дает понять остальным EVPN-пирам в фабрике, что данный VTEP заинтересован получать BUM-трафик для конкретного VNI (который указывается в IMET-маршруте). Мы получаем по одному RT-3 маршруту от каждого лифа.

Также мы видим четыре маршрута MAC/IP RT-2, которые используются для анонсирования информации о достижимости хостов в overlay-сети. MAC-адреса здесь - адреса наших клиентов.

Посмотрим на них подробнее, сначала на RT-3:

Каждый VTEP выказал свою заинтересованность в получении BUM-трафика для VNI 1100.

И по MAC/IP RT-2 маршрутам:

Все принадлежат VNI 1100, Route Target тот, который мы настроили: 100:100, благодаря чему наши Leaf'ы смогут импортировать маршруты в нужный MAC-VRF.

Проверка Spine-2

Вкратце пробежимся по Spine-2. Тут мы должны увидеть примерно то же самое, что и на Spine-1

Посмотрим общее состояние BGP:

Все в порядке. С каждым соседом у нас установилась сессия в L2VPN EVPN.

Проверим, какие маршруты мы получаем в AFI EVPN:

Проверка Leaf-1

Общая информация:

Маршруты BGP для EVPN:

Обратите внимание на AS-PATH - трафик пойдет через Spine, а затем к конечному лифу.

Проверим наш EVI:

Здесь мы видим важную строчку - Local VXLAN IP address, а именно тот IP-адрес, который будет служить Source IP для VXLAN-пакетов.

Видим маппинг VLAN 100 на VNI 1100.

Видим, что плоскость управления для VXLAN у нас - EVPN.

Видим IP-адреса удаленных VTEP'ов, с которыми у нас построены туннели. Это Leaf'ы Leaf-2 и Leaf-3. Помним, что туннели мы строим VTEP<->VTEP (то есть Leaf-Leaf), а не как в BGP - Leaf-Spine.

Проверим L2-таблицу форвардинга:

Здесь мы видим, что Leaf-1 знает, как добраться до остальных клиентских хостов.

Проверка Leaf-2

Общая информация:

Маршруты BGP для EVPN:

Все выглядит в порядке.

Проверка Leaf-3

Тоже все выглядит в порядке :)

Проверка связности между клиентами

Проверять будем таким образом. Сначала мы на клиенте делаем пинг другого клиента (физически находящегося за другим Leaf'ом). Затем смотрим в tcpdump и проверяем, что трафик действительно уходит и приходит инкапсулированным в VNI 1100.

На всякий случай приведу настройки каждого клиента:

Запустим пинг с Client-1 до Client-4. Вот как будет это выглядеть на топологии:

Захватываем трафик в Wireshark и смотрим, в каком виде ходят пакеты. На интерфейсе eth3 на Leaf-1 (к которому подключен Client-1), пакеты ICMP Request и ICMP Reply выглядят так:

Запрос: SRC_MAC - MAC Client-1, DST_MAC - MAC Client-2.

SRC_IP - IP Client-1, DST_IP - IP Client-2

Ответ: SRC_MAC - MAC Client-2, DST_MAC - MAC Client-1.

SRC_IP - IP Client-2, DST_IP - IP Client-1

Обычный IP-трафик, без каких-либо инкапсуляций.

А теперь посмотрим на интерфейс Ethernet1 на Leaf-1, который смотрит в Spine-1. В каком виде здесь мы увидим наш ICMP-обмен?

Тут мы уже видим инкапсуляцию в VNI 1100 - это VNI. Разберем первый кадр. OUTER_SRC_MAC: аппаратный MAC Leaf-1, OUTER_DST_MAC: MAC-адрес Spine-1. OUTER_SRC_IP: Loopback-адрес Leaf-1 (он же VTEP IP), OUTER_DST_IP: Loopback-адрес Leaf-2 (он же VTEP IP). OUTER_DST_UDP_PORT: 4789 - well-known порт VXLAN. VNI: 1100: VXLAN VNI L2-домена, в котором живут клиенты, обменивающиеся ICMP-трафиком. INNER_SRC_MAC: MAC Client-1. INNER_DST_MAC: MAC Client-2. INNER_SRC_IP: IP-адрес Client-1. INNER_DST_IP: IP-адрес Client-2.

Разберем второй кадр (с ответом). OUTER_SRC_MAC: аппаратный MAC Spine-1, OUTER_DST_MAC: MAC-адрес Leaf-1. OUTER_SRC_IP: Loopback-адрес Leaf-2 (он же VTEP IP), OUTER_DST_IP: Loopback-адрес Leaf-1 (он же VTEP IP). OUTER_DST_UDP_PORT: 4789 - well-known порт VXLAN. VNI: 1100: VXLAN VNI L2-домена, в котором живут клиенты, обменивающиеся ICMP-трафиком. INNER_SRC_MAC: MAC Client-2. INNER_DST_MAC: MAC Client-1. INNER_SRC_IP: IP-адрес Client-2. INNER_DST_IP: IP-адрес Client-1.

На интерфейсе Ethernet1 на Leaf-2 мы видим, что пакеты приходят инкапсулированными:

А на интерфейсе Ethernet3, в который подключен Client-2, пакеты декапсулируются и идут как стандартный IP:

Мы убедились, что пинги ходят инкапсулированными в VXLAN с VNI 1100.

Кратко проверим связность между остальными клиентами:

Client-1 -> Client-2

Client-1 -> Client-3

Client-2 -> Client-1

Client-2 -> Client-3

Client-2 -> Client-4

Client-3 -> Client-1

Client-3 -> Client-2

Client-3 -> Client-4

Client-4 -> Client-1

Client-4 -> Client-2

Client-4 -> Client-3

И проверим ARP-таблицы:

Мы убедились, что клиенты видят друг друга на 2-ом уровне. Можем переходить к настройке маршрутизации между VNI :).

Last updated