Петля в EVPN-VXLAN.

Петля в EVPN-VXLAN.

Sergey Bocharnikov

Как и обещал, продолжение истории с петлей. Для тех кто не в курсе, первая часть вот тут - https://t.me/like_a_bus_channel/59.


Собственно, как вы уже поняли, петля всё-таки случилась.

Заранее предвещая вопросы. Влияния какого-то не было, т.к. это случилось не в продуктивной среде.


Но давайте пойдём сначала.

Итак, как мы поняли что у нас проблема? Всё очень просто. В какой-то момент логи на коробке прислали сообщение, что CPU приближается к 100%.

CPU  H-Ma  09-02-2024 09:10:10  98.19%(Cpu Core)   


Ок, но почему петля то сразу? Вдруг там какая-то другая проблема?


Заходим на лиф и смотрим остальные логи:

  1. Дропы от работы storm-control
HSL : NOTIF : [IF_STORM_DISCARDS_4]: Storm control discards started on interface xX total discards 14938165044
HSL : NOTIF : [IF_STORM_DISCARDS_4]: Storm control discards started on interface xY total discards 45256185512


2. Огромное количество разных сообщений по изменению состояния таблиц в BGP и сервисов NSM и HSL.

NSM - network service module, один из ключевых сервисов на уровне Control Plane, занимающийся взаимодействием с Data Plane
HSL - hardware service layer, аналог NSM, но на уровне Data Plane, занимающийся программированием ASICа
Более детально структура описана в отдельном посте - https://t.me/like_a_bus_channel/35
Все логи приводить не буду, иначе будет нечитабельно, но по ходу повествования добавлю ключевые


Аналогичная картина на соседнем лифе в паре.


То есть мы видим следующее: дискарды + флапы MAC адресов и как следствие, всех причастных процессов.


Как видите, уже в принципе понятно, что у нас петля. Но нужно ещё найти место где она возникает и разорвать её.


Ок, петля есть.

Давайте найдём, устраним и только потом будем выяснять причину.

Причем именно в таком порядке :)


Чтобы увидеть проблему наглядно, нужно обратиться к схеме подключения.


Как видите, она была совсем нетривиальная.

Есть у заказчика такое требование, чтобы к лифам подключались коммутаторы в разных конфигурациях. Это далеко не единственный вариант, в целом мы заранее прорабатываем несколько сценариев возможных подключений хостов и тестируем их. Естественно всё это собирается и проверяется сначала на стенде, только потом уже уезжая на площадку. Тут не исключение.


Не буду ходить вокруг да около. Петлю нашли практически сразу.

Посмотрели конфиги на SW-1/2 и обнаружили, что у нас не настроен MLAG между ними.

То есть получилась вот такая история:



Как видите, у нас была пара общих LAG между всеми коробками. Плюс линк между SW-1 и SW-2. MLAG при этом не был настроен и по факту, это и явилось причиной возникновения петли.

Т.е линк между SW-1 и SW-2, был просто настроен по умолчанию, и т.к. это Huawei, то в отличии от Cisco, у них дефолт - это L2 с включенным MSTP + VLAN 1.

Хорошо, разобрались где петля возникала. Достаточно было выключить линки между SW или собрать на них MLAG.

Ок. Шторм обнаружен и устранен.

Но это только часть задачи.

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

Про влажные мечты и разговоры в духе отказаться полностью от L2 и перейти целиком на L3, никогда не ошибаться в конфигурациях и коммутациях, любить маму и пить компот - в курсе, большое спасибо.
Увы (или наоборот к счастью), жизнь чуть сложнее и ставит свои условия.

Например, могу предложить вам решить задачу бесшовной миграции VM между хостами внутри vSphere без общего L2 и опираясь только на L3.
Ну да, забыл, что VMware ушла из РФ и задачи такой больше нет. Ага, ок.


В общем, предлагаю идти дальше в исследовании возникновения проблемы и выявить root cause, после чего попытаться защититься от возникновения подобного шторма.

Собственно тут и начинается самая интересная на мой взгляд часть.


Let`s go deeper.

Как писал ранее, мы делали и storm-control и LAG, плюс есть стандартные механизмы описанные в RFC, которые тоже должны были помочь. Но не помогли. Ниже поясню что к чему.

C LAG всё понятно, нет MLAG, нет и полноценной агрегации. Максимум получим линки поднятые только до одного SW-1 или SW-2.

То есть, либо так:


Либо вот так:

По сути, определится это тем, чей System-ID будет выбран на стороне LF100-1 и LF100-2.

Но не тут-то было.

По факту получилась вот такая схема:

Как вы можете заметить, ВСЕ линки в сторону LF100-1 в UP. Даже от SW-2.

Интересно, да? Почему port-channel с LF100-1 всё-таки активен до обоих узлов?

Причина кроется тоже в конфигурации. Причем тут уже нет ошибок, так и планировалось.

Мы настраивает такую штуку как "lacp force-up", эта команда превентивно поднимает линки в LAG, не дожидаясь получения LACP BPDU.

Удобно для автоматической настройки линуксовых хостов. Детально можно почитать вот тут:
https://support.huawei.com/enterprise/en/doc/EDOC1100137933/54c5f31b/link-aggregation-commands#EN-US_CLIREF_0141121183

https://docs.ipinfusion.com/service-provider-6.5/index.html#page/OcNOS_SP/Layer2-Config/LACP_Aggregator_Forceup.html

При этом на LF100-2 мы такую настройку не делаем, ровно для того, чтобы избежать петли, т.к. LAG собирается только на одной стороне. Схема рабочая и отлично себя показывает для автоматической настройки линуксовых хостов.


Так-так-так. Отлично. Уже вроде становится чуть более понятно, но ещё далеко не всё. Сейчас вы поймёте почему.


В нашей инсталляции всего было 2 хоста:

Первый - жил на SW-1, второй - на SW-2. И оба в одном L2 домене.

Получается, петля возникла между этими двумя? Да, могла.

В дальнейшем, на всех схемах заблокированный линк между LF100-2 и SW-2 убрал, он только будет путать и мешаться.

Для наглядности научился делать гифки, но телеграф их страшно сжимает...

Стрелка - это ARP. По факту, тут показан трафик только со стороны SW-1 и то, как петля возникает с него, но у нас есть хост и на SW-2, который провоцирует ровно тоже самое, но в обратную сторону.

Можно заметить, что единственный, кто хоть как-то старается, это LF100-2, который обратно в сторону хостов BUM трафик не отправляет, т.к. DF - это LF100-1

Так, ну хорошо. Петлю с хостами зафиксировали.


Как мы видели выше в логах, storm-control работает. Лишний трафик действительно отбрасывается.

Есть некий best practice, который не мной был придуман, но уже давно зарекомендовал себя как хорошее значение - 0.1% от ёмкости интерфейса, то есть, если интерфейс 100 Gbps, то при превышении 100 Mbps, всё что больше будет отброшено, для 10G - порог соответственно, находится на 10 Mbps.


Что же насчет флапов MAC адресов? Они ведь тоже у нас бесконечно идут, и MAC выучивается то с одной стороны, то с другой.

В EVPN у нас есть такая штука как MAC Mobility, которая использует extended community с указанием в нём sequence, что и позволяет плавно переводить трафик с одного лифа на другой, для конкретного MAC адреса. То есть, если у вы делаете первый анонс внутрь фабрики, то ставите sequence равный 0, и все его получают. Если же, кто-то хочет сделать новый анонс для точно такого же маршрута, то он уже знает о существовании маршрута с sequence равным нулю и добавляет к своему анонсу +1. Таким образом все получают новый update, где sequence выше текущего и переводят трафик в сторону этого лифа.

Если что, это и есть ответ на задачу по бесшовной миграции для vSphere

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

Так. Выходит EVPN не учитывает такой сценарий?

Нет, учитывает.

Если коротко, то за определенный промежуток времени sequence вырастает до значения равного 6, это расценивается как mac flooding и дальше повышение выключается, плюс MAC фиксируется. Происходит так называется MAC freezing

Cобственно вот тут он описан - https://datatracker.ietf.org/doc/html/rfc7432#section-15.1


Идём смотреть логи.

LF100-1 : NSM : NOTIF : [EVPN_MAC_MOBILITY_4]: Max Host movement VPN-ID 123: MAC MAC_HOST_1 and IP IP_HOST_1 moved to conflict state, resolve manually.This MAC also moved to discard till 300 seconds
LF100-1 : NSM : NOTIF : [VXLAN_OPR_MAC_IP_MOVE_IGNORED_4]: Max host movement VPN-ID 123: MAC MAC_HOST_1 mobility ignored because of CONFLICT
Признаться, когда я нашёл этот лог, то был не просто рад, а пиздец как рад. (с)


Ну что, выходит всё?
Петля нашлась, storm-control работал. MAC Mobility тоже нас выручил и заблокировал флаппинг внутри BGP.
Откуда же CPU 100% на протяжении длительного времени? Ведь всё, что я описал выше - это секунды.

Тут мы подходим к финальной части повествования.


FINISH HIM !!

Есть такой механизм, называется он ARP-ND-REFRESH.
Удобная штука для silent хостов, которые молчат и только отвечают, если видят направленный ARP или ND.

Работает по следующему сценарию.

  1. Лиф отправляет ARP-REQUEST и ND в сторону хоста со своим anycast gateway MAC в качестве source.
  2. Хост получает ARP и выучивает адрес лифа, а в ответ отправляет ARP-REPLY.
  3. Лиф обновляет таблицу ARPов, плюс если это требуется, отдаёт новый TYPE-2 в сторону EVPN облака.
  4. Профит.

Но что будет, если у нас петля?

А будет то, что запетляется ещё и вот этот наш ARP, который ушёл с лифа.

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

Как видите, наш собственный ARP, попадает к нам изнутри. То есть со стороны хостов. И тут происходит ровно то, что приводит к загрузке CPU до 100%.

LF100-1 : HSL : INFO : [NVO_OPR_HW_INFO_5]: VPN-ID 123: MAC removed in mac hash MAC aaaa.bbbb.cccc
LF100-1 : NSM : NOTIF : [EVPN_MAC_MOBILITY_4]: VPN-ID 123: MAC aaaa.bbbb.cccc update Static Local to Dynamic Local on irb123 outer-vlan 0, inner-vlan 0 dynamically learnt on po1 outer-vlan 0, inner-vlan 0

Ключевое сообщение - Static Local to Dynamic Local.

Таких сообщений, в логах несколько тысяч. То есть т.к. MAC есть локально, но мы получаем его из вне, происходит бесконечный MAC learning, который и кладёт нам процессор.

В итоге, если выключить ARP-ND-REFRESH, то мы уберём отправку ARP-REQUEST с лифов и больше такого не произойдёт.


Всё. Вот теперь точно конец.

Report Page