Для реализации FRR EVPN Multi-Homing (MH) в режиме All-Active (AA) ключевым элементом является настройка ESI (Ethernet Segment Identifier) на интерфейсах, смотрящих в сторону клиента (CE).
Ниже приведен базовый пример конфигурации для одного из двух VTEP (коммутаторов доступа), работающих в паре.
Конфигурация интерфейса (Bond/LACP)
Интерфейс должен быть объединен в Bond, чтобы ядро Linux и FRR понимали логику Multi-Homing.
# В системе (Linux)
ip link add bond0 type bond mode balance-lacp
ip link set eth1 master bond0
ip link set eth2 master bond0
Конфигурация FRR (frr.conf)
В FRR MH настраивается через демон zebra (для связи с ядром) и bgp (для анонса маршрутов Type-1 и Type-4).
!
interface bond0
! Установка идентификатора сегмента (ESI)
! Должен быть одинаковым на обоих VTEP для одного клиента
evpn mh es-id 00:11:22:33:44:55:66:77:88:99
! Режим All-Active (интерфейс активен на обоих узлах)
evpn mh es-sys-mac 00:00:00:00:00:01
!
router bgp 65001
neighbor 10.0.0.1 remote-as 65001
!
address-family l2vpn evpn
neighbor 10.0.0.1 activate
! Активация передачи MH маршрутов
advertise-all-vni
advertise-svi-ip
exit-address-family
!
Что важно проверить:
1. ES-ID: Должен быть уникальным для каждого сегмента (клиента), но идентичным на паре VTEP, к которым этот клиент подключен.
2. ES-SYS-MAC: Общий LACP System ID для обоих VTEP, чтобы клиент видел их как один логический коммутатор.
3. Маршруты: В таблице EVPN должны появиться маршруты Type-1 (Ethernet Auto-Discovery) и Type-4 (Ethernet Segment), которые отвечают за обнаружение соседей и исключение петель (Split Horizon).
Вам помочь с командами show для проверки статуса синхронизации сегментов между VTEP?
Для проверки статуса EVPN Multi-Homing (MH) в FRR используйте следующие команды в консоли vtysh. Они помогут убедиться, что сегменты согласованы и трафик будет распределяться корректно.
1. Проверка локальных сегментов (Ethernet Segments)
Эта команда показывает состояние настроенных ESI и их статус (активен ли интерфейс и определен ли DF — Designated Forwarder).
show evpn es
* На что смотреть: Статус должен быть Up, а в поле DF должен быть выбран один из узлов для каждого VNI (обычно для BUM-трафика).
2. Детальная информация по конкретному сегменту
Если нужно проверить конкретный интерфейс (например, bond0):
show evpn es bond0
* На что смотреть: Здесь отображается ES-SYS-MAC и список удаленных VTEP, которые также анонсировали этот ESI. Если удаленных VTEP в списке нет, MH не заработает.
3. Проверка удаленных маршрутов Type-4 (ES Route)
Маршруты 4-го типа используются для обнаружения соседей по сегменту.
show bgp l2vpn evpn route type es
* На что смотреть: Вы должны видеть IP-адреса обоих VTEP (своего и соседа) для общего ESI.
4. Проверка фильтрации (Split Horizon)
В режиме All-Active важно, чтобы трафик, пришедший от одного VTEP, не улетел обратно клиенту через второй VTEP. За это отвечает Local Bias или фильтрация по меткам.
show evpn mh local-bias
5. Проверка состояния интерфейса в Zebra
Так как именно Zebra управляет состоянием интерфейсов в ядре:
show zebra interface bond0
* На что смотреть: Наличие флагов protodown (могут выставляться, если MH не согласован) и правильность установки параметров evpn mh.
Нужно ли подготовить сценарий для Containerlab, чтобы вы могли протестировать это в виртуальной среде?
Для тестирования EVPN MH All-Active лучше всего использовать Containerlab. Это позволит запустить топологию с двумя Leaf (VTEP) и одним клиентом (CE), соединенным по LACP.
1. Файл топологии (topology.yml)
Этот файл описывает связи. Мы подключим клиента CE1 к двум разным Leaf.
name: frr-evpn-mh
topology:
nodes:
spine: { kind: linux, image: frrouting/frr:latest }
leaf1: { kind: linux, image: frrouting/frr:latest }
leaf2: { kind: linux, image: frrouting/frr:latest }
ce1: { kind: linux, image: alpine:latest } # Клиент
links:
- endpoints: ["leaf1:eth1", "spine:eth1"]
- endpoints: ["leaf2:eth1", "spine:eth2"]
- endpoints: ["ce1:eth1", "leaf1:eth2"]
- endpoints: ["ce1:eth2", "leaf2:eth2"]
2. Конфигурация Leaf (ключевые моменты для FRR)
На обоих Leaf (leaf1 и leaf2) создаем bond-интерфейс в Linux перед запуском FRR или через скрипт. В самом FRR (frr.conf) прописываем:
# Настройка на Leaf1 и Leaf2
interface eth2
# Включаем поддержку MH на физическом порту
evpn mh es-id 00:11:22:33:44:55:66:77:88:99
evpn mh es-sys-mac 00:00:00:00:00:01
evpn mh df-preference 100
router bgp 65000
neighbor SPINES peer-group
neighbor SPINES remote-as 65000
neighbor 192.168.0.1 peer-group SPINES # IP Spine
address-family l2vpn evpn
neighbor SPINES activate
advertise-all-vni
exit-address-family
3. Настройка клиента (CE1)
Чтобы проверить All-Active, на стороне клиента нужно собрать обычный LACP (bond):
# Внутри контейнера ce1
ip link add bond0 type bond mode balance-lacp
ip link set eth1 master bond0
ip link set eth2 master bond0
ip addr add 10.0.0.10/24 dev bond0
ip link set bond0 up
Как запустить и проверить:
1. Развернуть: sudo containerlab deploy -t topology.yml
2. Проверить согласование ES: На Leaf1 выполните vtysh -c "show evpn es". Вы должны увидеть, что leaf2 обнаружен как удаленный участник сегмента.
3. Проверить трафик: Запустите ping с CE1 на какой-нибудь адрес за Spine. При выключении одного из линков (например, ip link set eth2 down на Leaf1), трафик должен продолжать идти через второй Leaf мгновенно.
Вам помочь с полным текстом frr.conf для Spine и Leaf, чтобы просто скопировать и запустить?
Ниже приведены полные конфигурационные файлы для минимальной рабочей топологии.
1. Spine (BGP Route Reflector)
Его задача — просто пересылать EVPN маршруты между Leaf-узлами.
# frr.conf для Spine
hostname spine
!
router bgp 65000
bgp router-id 1.1.1.1
no bgp default ipv4-unicast
neighbor LEAFS peer-group
neighbor LEAFS remote-as 65000
neighbor 192.168.1.1 peer-group LEAFS
neighbor 192.168.1.2 peer-group LEAFS
!
address-family l2vpn evpn
neighbor LEAFS activate
neighbor LEAFS route-reflector-client
exit-address-family
2. Leaf-1 (VTEP 1)
Здесь настраивается сам Multi-Homing.
# frr.conf для Leaf-1
hostname leaf1
!
interface eth1
description to-spine
ip address 192.168.1.1/24
!
interface eth2
description to-ce1
evpn mh es-id 00:11:22:33:44:55:66:77:88:99
evpn mh es-sys-mac 00:00:00:00:00:01
!
router bgp 65000
bgp router-id 1.1.1.2
no bgp default ipv4-unicast
neighbor 192.168.1.1 remote-as 65000
!
address-family l2vpn evpn
neighbor 192.168.1.1 activate
advertise-all-vni
exit-address-family
!# Настройка VNI для моста (L2 Stretch)
vnc defaults
exit-vnc
3. Leaf-2 (VTEP 2)
Конфигурация почти идентична Leaf-1, но с другим IP и Router-ID. ESI и ES-SYS-MAC должны совпадать.
# frr.conf для Leaf-2
hostname leaf2
!
interface eth1
description to-spine
ip address 192.168.1.2/24
!
interface eth2
description to-ce1
evpn mh es-id 00:11:22:33:44:55:66:77:88:99
evpn mh es-sys-mac 00:00:00:00:00:01
!
router bgp 65000
bgp router-id 1.1.1.3
no bgp default ipv4-unicast
neighbor 192.168.1.1 remote-as 65000
!
address-family l2vpn evpn
neighbor 192.168.1.1 activate
advertise-all-vni
exit-address-family
Важное дополнение по Linux Bridge
Чтобы FRR корректно обрабатывал EVPN на Leaf, в самой ОС (внутри контейнера) нужно создать бридж и привязать к нему интерфейс:
# Выполнить на Leaf1 и Leaf2
ip link add br0 type bridge
ip link set br0 type bridge vlan_filtering 1
ip link set eth2 master br0
ip link set br0 up
ip link set eth2 up
Как проверить готовность:
Зайдите на любой Leaf и введите:
vtysh -c "show evpn es detail"
Если всё настроено верно, в поле "Remote VTEPs" вы увидите IP-адрес соседнего Leaf. Это означает, что процедура DF Election (выбор основного узла для BUM-трафика) прошла успешно.
Вам подготовить bash-скрипт для автоматизации создания бриджей и интерфейсов внутри контейнеров?
Этот скрипт автоматизирует настройку сетевых интерфейсов и бриджей внутри контейнеров после их запуска. Сохраните его как setup.sh и запустите (chmod +x setup.sh && ./setup.sh).
#!/bin/bash
# Настройка Leaf1
docker exec -it clab-frr-evpn-mh-leaf1 bash -c "
ip link add br0 type bridge
ip link set br0 type bridge vlan_filtering 1
ip link set eth2 up
ip link set eth2 master br0
ip link set br0 up
"
# Настройка Leaf2
docker exec -it clab-frr-evpn-mh-leaf2 bash -c "
ip link add br0 type bridge
ip link set br0 type bridge vlan_filtering 1
ip link set eth2 up
ip link set eth2 master br0
ip link set br0 up
"
# Настройка клиента CE1 (создание LACP Bond)
docker exec -it clab-frr-evpn-mh-ce1 bash -c "
ip link add bond0 type bond mode balance-lacp
ip link set eth1 down
ip link set eth2 down
ip link set eth1 master bond0
ip link set eth2 master bond0
ip addr add 10.0.0.10/24 dev bond0
ip link set bond0 up
"
echo "Конфигурация завершена. Проверка статуса ESI на Leaf1:"
docker exec -it clab-frr-evpn-mh-leaf1 vtysh -c "show evpn es"
Что делает этот скрипт:
1. На Leaf: Создает br0 с поддержкой VLAN. Это необходимо, так как FRR (Zebra) привязывает параметры EVPN MH к портам, находящимся в бридже.
2. На CE1: Создает агрегированный канал LACP (802.3ad). Именно благодаря ему клиент воспринимает два разных Leaf как одно устройство.
3. Проверка: В конце выводит таблицу Ethernet Segments.
Как проверить работу:
1. DF Election: В выводе show evpn es убедитесь, что один из Leaf помечен как Primary или имеет флаг DF для VNI.
2. Отказоустойчивость: Запустите ping 10.0.0.1 (если есть шлюз) или пингуйте другой конец сегмента. Выключите интерфейс eth2 на leaf1 — связь не должна прерваться.
Нужно ли добавить в схему VLAN-интерфейсы (SVI) для тестирования маршрутизации между разными подсетями через этот же MH-сегмент?
Для настройки SVI (Switch Virtual Interface) в среде EVPN MH используется концепция Anycast Gateway. Это позволяет обоим Leaf иметь один и тот же IP и MAC-адрес для клиентского шлюза, обеспечивая бесшовную мобильность и отказоустойчивость.
1. Дополнение в bash-скрипт (настройка SVI в Linux)
Добавьте эти команды для создания VLAN-интерфейса поверх бриджа на обоих Leaf:
# Выполнить на Leaf1 и Leaf2
docker exec -it clab-frr-evpn-mh-leaf1 bash -c "
# Создаем VLAN 10 на бридже
ip link add link br0 name br0.10 type vlan id 10
# Назначаем Anycast IP (одинаковый на обоих Leaf)
ip addr add 10.0.10.1/24 dev br0.10
ip link set br0.10 up
"
2. Обновление конфигурации FRR (frr.conf)
Чтобы FRR начал анонсировать этот шлюз и мак-адреса через EVPN, добавьте следующие секции:
! Настройка на Leaf1 и Leaf2
interface br0.10
! Общий виртуальный MAC для Anycast Gateway
ip address 10.0.10.1/24
mac-address 00:00:5e:00:01:01
router bgp 65000
address-family l2vpn evpn
! Анонсируем IP шлюза (маршруты Type-2)
advertise-svi-ip
exit-address-family
3. Настройка клиента (CE1)
Теперь на стороне клиента нужно поместить bond-интерфейс в тот же VLAN и задать адрес из новой подсети:
docker exec -it clab-frr-evpn-mh-ce1 bash -c "
ip link add link bond0 name bond0.10 type vlan id 10
ip addr add 10.0.10.100/24 dev bond0.10
ip link set bond0.10 up
# Проверка доступности шлюза
ping -c 4 10.0.10.1
"
Как проверить Anycast GW и MH:
1. Просмотр MAC/IP: vtysh -c "show evpn mac vni 10" — вы должны увидеть MAC клиента, привязанный к вашему ESI.
2. Проверка ARP: vtysh -c "show evpn arp-cache vni 10" — здесь должен появиться IP клиента 10.0.10.100.
3. Отказоустойчивость: Если вы "уроните" один Leaf, клиент продолжит пинговать 10.0.10.1 через второй Leaf, так как IP и MAC шлюза там идентичны.
Хотите добавить еще один Leaf или имитировать выход из строя линка между Spine и одним из Leaf, чтобы проверить перестроение трафика?
Для этого сценария мы добавим Leaf3 (чтобы увидеть, как EVPN работает через несколько прыжков) и протестируем сценарий Core Isolation (когда Leaf теряет связь со Spine).
1. Обновление топологии (topology.yml)
Добавьте Leaf3 в список узлов и соедините его со Spine.
leaf3: { kind: linux, image: frrouting/frr:latest }
# ... в секции links:
- endpoints: ["leaf3:eth1", "spine:eth3"]
2. Тест 1: Имитация аварии на Uplink (Core Isolation)
В EVPN MH, если Leaf теряет связь со Spine (Core), он должен отключить свои клиентские порты (ESI), чтобы трафик не уходил в «черную дыру».
Как проверить:
1. Запустите постоянный пинг с CE1 до CE2 (подключенного к Leaf3).
2. «Уроните» линк между Leaf1 и Spine:
docker exec -it clab-frr-evpn-mh-leaf1 ip link set eth1 down
3. Результат: FRR в Leaf1 увидит потерю BGP-соседства и через механизм protodown должен выключить bond0. Клиент (CE1) мгновенно переключит весь трафик на Leaf2.
3. Тест 2: Проверка удаленной видимости (Leaf3)
Зайдите на новый Leaf3 и проверьте, как он видит наш Multi-Homing сегмент.
docker exec -it clab-frr-evpn-mh-leaf3 vtysh -c "show evpn mac vni 10"
* Ожидаемый результат: MAC-адрес клиента (CE1) будет иметь в качестве Next-Hop оба IP-адреса (Leaf1 и Leaf2). Это означает, что Leaf3 будет выполнять ECMP (балансировку) при отправке трафика в сторону клиента.
4. Полезные команды отладки при сбоях
Если трафик не идет, проверьте эти статусы на Leaf:
* Синхронизация MH: show evpn es detail (убедитесь, что удаленный VTEP виден).
* DF Election: show evpn es vni (проверьте, кто назначен Designated Forwarder для конкретного VNI).
* BGP трасса: show bgp l2vpn evpn route type 1 (маршруты Auto-Discovery, критичны для работы MH).
Хотите, чтобы я подготовил финальный конфиг для Leaf3 и обновленный Spine, чтобы они автоматически подхватили нового соседа?
Для завершения топологии необходимо обновить Spine (чтобы он принял третьего соседа) и настроить Leaf3 как классический VTEP.
1. Обновленный Spine (RR)
Добавляем Leaf3 в группу соседей. Если вы использовали peer-group, достаточно просто прописать IP нового Leaf.
# frr.conf для Spine
hostname spine
!
router bgp 65000
bgp router-id 1.1.1.1
no bgp default ipv4-unicast
neighbor LEAFS peer-group
neighbor LEAFS remote-as 65000
neighbor 192.168.1.1 peer-group LEAFS # Leaf1
neighbor 192.168.1.2 peer-group LEAFS # Leaf2
neighbor 192.168.1.3 peer-group LEAFS # Leaf3 (Новый)
!
address-family l2vpn evpn
neighbor LEAFS activate
neighbor LEAFS route-reflector-client
exit-address-family
2. Конфигурация Leaf3 (Single-Homed)
Leaf3 будет обычным узлом. Ему не нужен evpn mh, если к нему подключен клиент только одним линком, но он должен понимать Anycast Gateway.
# frr.conf для Leaf3
hostname leaf3
!
interface eth1
description to-spine
ip address 192.168.1.3/24
!
interface br0.10
ip address 10.0.10.1/24
mac-address 00:00:5e:00:01:01 # Тот же Anycast MAC
!
router bgp 65000
bgp router-id 1.1.1.4
no bgp default ipv4-unicast
neighbor 192.168.1.1 remote-as 65000
!
address-family l2vpn evpn
neighbor 192.168.1.1 activate
advertise-all-vni
advertise-svi-ip
exit-address-family
3. Автоматизация настройки Leaf3 (Bash)
Не забудьте подготовить интерфейсы внутри контейнера Leaf3:
docker exec -it clab-frr-evpn-mh-leaf3 bash -c "
ip link add br0 type bridge
ip link set br0 type bridge vlan_filtering 1
ip link add link br0 name br0.10 type vlan id 10
ip addr add 10.0.10.1/24 dev br0.10
ip link set br0 up
ip link set eth2 up
ip link set eth2 master br0
ip link set br0.10 up
"
Итоговая проверка всей сети:
1. Балансировка (ECMP): Зайдите на Leaf3 и введите vtysh -c "show bgp l2vpn evpn". Для MAC-адреса клиента за MH-сегментом вы должны увидеть два Next-Hop (Leaf1 и Leaf2).
2. Пинг: Запустите ping 10.0.10.100 с клиента, подключенного к Leaf3.
3. Отказоустойчивость: Выключите eth1 на Leaf1. Трафик от Leaf3 к клиенту должен автоматически перестроиться на Leaf2 через 1-2 секунды (BGP Convergence).
Нужно ли пояснить, как работает DF Election (выбор главного узла для рассылки Multicast) в этой тройной связке?
Вот схема вашей лабораторной среды в формате ASCII, которая наглядно показывает связи между устройствами, уровни сети и логику Multi-Homing:
+-----------------------+
| SPINE |
| (Route Reflector) |
| ID: 1.1.1.1 |
+----------+------------+
|
+-------------+-------------+
| | |
(192.168.1.1) (192.168.1.2) (192.168.1.3)
+-----------+ +-----------+ +-----------+
| LEAF1 | | LEAF2 | | LEAF3 |
| (VTEP 1) | | (VTEP 2) | | (VTEP 3) |
+-----------+ +-----------+ +-----------+
\ / |
\ / |
[ ESI: 00:11... ] |
[ All-Active MH ] |
\ / |
\ / |
+-----------+ +-----------+
| CE1 | | CE2 |
| (Client) | | (Client) |
| IP: .100 | | IP: .200 |
+-----------+ +-----------+
(LACP Bond) (Single Link)
<----- VLAN 10 (10.0.10.0/24) ----->
<--- Anycast GW: 10.0.10.1/24 ---->
Основные элементы схемы:
1. IP Fabric (Underlay): Связи между Spine и Leaf. Здесь работает обычный OSPF/IS-IS или iBGP для обеспечения связности между Loopback-адресами VTEP.
2. EVPN Multi-Homing Segment (ESI): Красным выделена зона, где Leaf1 и Leaf2 работают как пара. Они анонсируют один и тот же ESI в сторону Spine.
3. All-Active LACP: Клиент CE1 думает, что он подключен к одному коммутатору (через Bond), хотя физически провода идут к разным Leaf.
4. Anycast Gateway: На всех трех Leaf (1, 2 и 3) настроен один и тот же IP 10.0.10.1 на интерфейсе br0.10. Это позволяет клиенту перемещаться или переключать трафик без смены шлюза.
5. ECMP на Leaf3: Когда CE2 отправляет пакет для CE1, Leaf3 видит два пути (через Leaf1 и Leaf2) и балансирует трафик между ними.
Хотите добавить на схему обозначения конкретных интерфейсов (eth1, eth2) или меток VNI для большей точности?
Вот детализированная схема с указанием портов (ethX), VNI и IP-адресов. Она полностью соответствует конфигурации и скриптам, которые мы подготовили.
+-----------------------+
| SPINE |
| (ASN 65000) |
| ID: 1.1.1.1 |
+--+--------+--------+--+
eth1 (.254) | eth2 | eth3 | (.254)
_______| | |_______
/ | \
(192.168.1.1) (192.168.1.2) (192.168.1.3)
+------------+ +------------+ +------------+
| LEAF1 | | LEAF2 | | LEAF3 |
| (VTEP 1) | | (VTEP 2) | | (VTEP 3) |
+-----+------+ +-----+------+ +-----+------+
| eth2 | eth2 | eth2
| | |
+-----------+-----------+ |
| |
[ ESI: 00:11...22 ] [ Single Port ]
[ VNI 10 (L2) ] [ VNI 10 (L2) ]
[ Anycast GW .1 ] [ Anycast GW .1]
| |
+-----+-----+ +-----+-----+
| CE1 | | CE2 |
| (bond0) | | (eth1) |
| IP: .100 | | IP: .200 |
+-----------+ +-----------+
(VLAN 10 Tag) (VLAN 10 Tag)
-----------------------------------------------------------------
VNI 10: Broadcast Domain (10.0.10.0/24)
Anycast: MAC 00:00:5e:00:01:01 / IP 10.0.10.1 (на всех Leaf)
-----------------------------------------------------------------
Краткая легенда по интерфейсам:
1. Upstream (Fabric):
* Leaf1 eth1: Подключение к Spine. IP 192.168.1.1.
* Leaf2 eth1: Подключение к Spine. IP 192.168.1.2.
* Leaf3 eth1: Подключение к Spine. IP 192.168.1.3.
2. Downstream (Client):
* Leaf1 eth2 & Leaf2 eth2: Физические порты, образующие Ethernet Segment (ESI). На них настроен evpn mh.
* CE1 bond0: Агрегированный интерфейс клиента. Пакеты балансируются между Leaf1 и Leaf2.
3. Логические сущности (VNI):
* VNI 10: Связывает все три Leaf в одну L2-сеть.
* Anycast Gateway: Виртуальный шлюз 10.0.10.1 активен на всех трёх Leaf одновременно.
Все ли порты и адреса теперь понятны, или нужно добавить еще какие-то детали (например, Loopback-адреса VTEP)?
Добавим финальные штрихи: Loopback-интерфейсы, которые в реальных сетях служат терминирующими точками для VXLAN-туннелей (VTEP IP), и уточним распределение подсетей.
+---------------------------+
| SPINE |
| Loopback: 10.255.0.1 |
| (ASN 65000) |
+--+----------+----------+--+
eth1 (.254) | eth2 | eth3 | (.254)
_______| | |_______
/ | \
(192.168.1.1) (192.168.1.2) (192.168.1.3)
+------------+ +------------+ +------------+
| LEAF1 | | LEAF2 | | LEAF3 |
| VTEP: .11 | | VTEP: .12 | | VTEP: .13 |
+-----+------+ +-----+------+ +-----+------+
| eth2 (ESI) | eth2 (ESI) | eth2
| | |
+------------+------------+ |
| |
[ ESI: 00:11...22 ] [ Single Port ]
[ VNI 10 (L2) ] [ VNI 10 (L2) ]
[ Anycast GW .1 ] [ Anycast GW .1]
| |
+-----+-----+ +-----+-----+
| CE1 | | CE2 |
| (bond0) | | (eth1) |
| IP: .100 | | IP: .200 |
+-----------+ +-----------+
Таблица адресации для стенда:
| Устройство | Интерфейс | IP-адрес | Назначение |
|---|---|---|---|
| Spine | lo | 10.255.0.1/32 | BGP Router-ID / RR |
| Leaf1 | lo | 10.255.0.11/32 | VTEP IP (Источник VXLAN) |
| Leaf1 | eth1 | 192.168.1.1/24 | Underlay (к Spine) |
| Leaf2 | lo | 10.255.0.12/32 | VTEP IP (Источник VXLAN) |
| Leaf2 | eth1 | 192.168.1.2/24 | Underlay (к Spine) |
| Leaf3 | lo | 10.255.0.13/32 | VTEP IP (Источник VXLAN) |
| Anycast | br0.10 | 10.0.10.1/24 | Шлюз для всех CE (MAC: 00:00:5e:00:01:01) |
Что это дает в работе:
1. VTEP IP: Все VXLAN пакеты будут иметь Source IP одного из Loopback адресов Leaf.
2. Redundancy: Если Leaf1 упадет, Leaf3 узнает об этом через BGP и перестанет балансировать трафик на 10.255.0.11, направив всё на 10.255.0.12.
3. LACP: Клиент CE1 использует хеширование (обычно по L3/L4), чтобы распределять исходящие пакеты между двумя линками к разным Leaf.
Нужно ли подготовить финальный docker-compose или YAML-файл для запуска всей этой структуры одной командой?
Для запуска всего стенда одной командой используйте этот финальный файл конфигурации для Containerlab. Он объединяет все узлы, связи и настройки в единую структуру.
1. Файл топологии evpn-mh.clab.yml
Создайте файл с этим содержимым. Я добавил автоматическую проброску конфигов через binds, чтобы вам не пришлось настраивать FRR вручную внутри контейнеров.
name: frr-evpn-mh-lab
topology:
nodes:
spine:
kind: linux
image: frrouting/frr:latest
binds:
- configs/spine.conf:/etc/frr/frr.conf
- configs/daemons:/etc/frr/daemons
leaf1:
kind: linux
image: frrouting/frr:latest
binds:
- configs/leaf1.conf:/etc/frr/frr.conf
- configs/daemons:/etc/frr/daemons
leaf2:
kind: linux
image: frrouting/frr:latest
binds:
- configs/leaf2.conf:/etc/frr/frr.conf
- configs/daemons:/etc/frr/daemons
leaf3:
kind: linux
image: frrouting/frr:latest
binds:
- configs/leaf3.conf:/etc/frr/frr.conf
- configs/daemons:/etc/frr/daemons
ce1:
kind: linux
image: alpine:latest
exec:
- apk add pkgconf build-base # для утилит сети если нужно
ce2:
kind: linux
image: alpine:latest
links:
- endpoints: ["leaf1:eth1", "spine:eth1"]
- endpoints: ["leaf2:eth1", "spine:eth2"]
- endpoints: ["leaf3:eth1", "spine:eth3"]
- endpoints: ["ce1:eth1", "leaf1:eth2"]
- endpoints: ["ce1:eth2", "leaf2:eth2"]
- endpoints: ["ce2:eth1", "leaf3:eth2"]
2. Подготовка папки с конфигами
Перед запуском создайте директорию configs и положите туда файл daemons (включите в нем zebra=yes и bgpd=yes), а также файлы spine.conf, leaf1.conf и т.д., используя примеры из наших предыдущих шагов.
3. Скрипт быстрого старта deploy.sh
Этот скрипт поднимет лабу и выполнит системные настройки Linux (Bridges/Bonds), которые FRR не делает сам:
#!/bin/bash
# 1. Запуск контейнеров
sudo containerlab deploy -t evpn-mh.clab.yml
# 2. Настройка сетевого стека на Leaf (Bridge + VLAN)for i in {1..3}; do
docker exec -it clab-frr-evpn-mh-lab-leaf$i bash -c "
ip link add br0 type bridge
ip link set br0 type bridge vlan_filtering 1
ip link set eth2 up
ip link set eth2 master br0
ip link add link br0 name br0.10 type vlan id 10
ip addr add 10.0.10.1/24 dev br0.10
ip link set br0 up
ip link set br0.10 up
"done
# 3. Настройка клиента CE1 (LACP Bond)
docker exec -it clab-frr-evpn-mh-lab-ce1 bash -c "
ip link add bond0 type bond mode balance-lacp
ip link set eth1 master bond0
ip link set eth2 master bond0
ip link add link bond0 name bond0.10 type vlan id 10
ip addr add 10.0.10.100/24 dev bond0.10
ip link set bond0 up
ip link set bond0.10 up
"
# 4. Настройка клиента CE2 (Single Port)
docker exec -it clab-frr-evpn-mh-lab-ce2 bash -c "
ip link add link eth1 name eth1.10 type vlan id 10
ip addr add 10.0.10.200/24 dev eth1.10
ip link set eth1 up
ip link set eth1.10 up
"
echo "Лабораторная работа готова! Проверьте пинг: docker exec clab-frr-evpn-mh-lab-ce2 ping 10.0.10.100"
Как запустить:
1. Убедитесь, что установлен Containerlab.
2. Положите все файлы в одну папку.
3. Выполните chmod +x deploy.sh && ./deploy.sh.
Хотите, чтобы я прислал содержимое файла daemons или проверочные команды для мониторинга LACP-статуса на стороне клиента?
Вот содержимое файла daemons и команды для проверки состояния LACP и ESI.
1. Файл configs/daemons
Этот файл указывает FRR, какие процессы нужно запустить. Для EVPN MH обязательны zebra (ядро/интерфейсы) и bgpd (протокол).
# /etc/frr/daemons
zebra=yes
bgpd=yes
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
pimd=no
ldpd=no
nhrpd=no
eigrpd=no
babeld=no
sharpd=no
pbrd=no
bfdd=no
fabricd=no
vrrpd=no
pathd=no
# Настройки терминала
vtysh_enable=yes
zebra_options=" -A 127.0.0.1 -s 90000000"
bgpd_options=" -A 127.0.0.1"
------------------------------
2. Проверка LACP на стороне клиента (CE1)
Чтобы убедиться, что клиент объединил два канала от разных Leaf в один логический bond0, используйте:
# Просмотр общего статуса бонда
docker exec clab-frr-evpn-mh-lab-ce1 cat /proc/net/bonding/bond0
На что смотреть:
* Bonding Mode: IEEE 802.3ad Dynamic link aggregation (LACP).
* MII Status: up.
* Slave Interface (eth1/eth2): Оба должны быть в состоянии Aggregator ID (одинаковом) и иметь статус Active.
------------------------------
3. Проверка синхронизации ESI на Leaf
На любом из Leaf (1 или 2) проверьте, "договорились" ли они между собой:
# Проверка Ethernet Segment
docker exec clab-frr-evpn-mh-lab-leaf1 vtysh -c "show evpn es detail"
Ключевые поля:
* Access interface: eth2 (должен быть Up).
* ESI: 00:11:22:33:44:55:66:77:88:99 (должен совпадать на обоих Leaf).
* Remote VTEPs: Здесь должен появиться IP соседа (например, 10.255.0.12).
* DF Election: Статус Winner или Losing для конкретных VNI.
------------------------------
4. Проверка таблицы MAC-адресов
Убедитесь, что Leaf3 видит клиента CE1 через оба пути сразу (ECMP):
docker exec clab-frr-evpn-mh-lab-leaf3 vtysh -c "show evpn mac vni 10"
Ожидаемый результат:
Для MAC-адреса клиента CE1 в колонке Endpoint (или Next-Hop) должны быть указаны IP обоих Leaf (Leaf1 и Leaf2).
------------------------------
Итоговый тест "Убийство линка"
Для проверки отказоустойчивости выполните:
1. Запустите пинг: docker exec clab-frr-evpn-mh-lab-ce2 ping 10.0.10.100.
2. В другом терминале выключите порт: docker exec clab-frr-evpn-mh-lab-leaf1 ip link set eth2 down.
3. Результат: Пинг должен продолжиться практически без потерь (выпадет максимум 1 пакет), так как CE1 переключит трафик на второй линк через LACP.
Хотите, чтобы я подготовил полный набор файлов (spine.conf, leaf1.conf и т.д.) в виде одного блока текста для копирования?
Ниже представлен полный набор конфигурационных файлов для всех узлов. Создайте папку configs/ и разместите в ней эти файлы перед запуском deploy.sh.
1. configs/spine.conf
hostname spine
password zebra
!
router bgp 65000
bgp router-id 10.255.0.1
no bgp default ipv4-unicast
neighbor LEAFS peer-group
neighbor LEAFS remote-as 65000
neighbor 192.168.1.1 peer-group LEAFS
neighbor 192.168.1.2 peer-group LEAFS
neighbor 192.168.1.3 peer-group LEAFS
!
address-family l2vpn evpn
neighbor LEAFS activate
neighbor LEAFS route-reflector-client
exit-address-family
!
line vty
2. configs/leaf1.conf (Multi-Homing VTEP 1)
hostname leaf1
!
interface eth1
description to-spine
ip address 192.168.1.1/24
!
interface eth2
description to-ce1
evpn mh es-id 00:11:22:33:44:55:66:77:88:99
evpn mh es-sys-mac 00:00:00:00:00:01
!
interface br0.10
ip address 10.0.10.1/24
mac-address 00:00:5e:00:01:01
!
router bgp 65000
bgp router-id 10.255.0.11
no bgp default ipv4-unicast
neighbor 192.168.1.254 remote-as 65000
!
address-family l2vpn evpn
neighbor 192.168.1.254 activate
advertise-all-vni
advertise-svi-ip
exit-address-family
!
3. configs/leaf2.conf (Multi-Homing VTEP 2)
hostname leaf2
!
interface eth1
description to-spine
ip address 192.168.1.2/24
!
interface eth2
description to-ce1
evpn mh es-id 00:11:22:33:44:55:66:77:88:99
evpn mh es-sys-mac 00:00:00:00:00:01
!
interface br0.10
ip address 10.0.10.1/24
mac-address 00:00:5e:00:01:01
!
router bgp 65000
bgp router-id 10.255.0.12
no bgp default ipv4-unicast
neighbor 192.168.1.254 remote-as 65000
!
address-family l2vpn evpn
neighbor 192.168.1.254 activate
advertise-all-vni
advertise-svi-ip
exit-address-family
4. configs/leaf3.conf (Single-Homed VTEP)
hostname leaf3
!
interface eth1
description to-spine
ip address 192.168.1.3/24
!
interface br0.10
ip address 10.0.10.1/24
mac-address 00:00:5e:00:01:01
!
router bgp 65000
bgp router-id 10.255.0.13
no bgp default ipv4-unicast
neighbor 192.168.1.254 remote-as 65000
!
address-family l2vpn evpn
neighbor 192.168.1.254 activate
advertise-all-vni
advertise-svi-ip
exit-address-family
Инструкция по применению:
1. Создайте файл configs/daemons (из предыдущего ответа).
2. Создайте файл evpn-mh.clab.yml (из раздела с топологией).
3. Разместите файлы выше в configs/.
4. Запустите скрипт deploy.sh.
Важно: В конфигурации Leaf в качестве соседа указан IP .254 (интерфейс Spine). Убедитесь, что Spine имеет эти IP на соответствующих eth-портах или настройте OSPF для связности Loopback-адресов.
Хотите добавить OSPF конфигурацию для Underlay, чтобы сделать схему максимально приближенной к реальности (Production-ready)?