Нагрузочное тестирование EVPN-MPLS на маршрутизаторах MR-381 от B4COM. Методика, результаты и выводы

от автора

В конце 2023 года отечественный вендор B4com Tech анонсировал выпуск маршрутизаторов для провайдерского сегмента IP/MPLS. Среди новых моделей наше внимание привлекли те, которые поддерживают интерфейсы 100G, поскольку они стали стандартом подключения в современных центрах обработки данных (ЦОД).

В модельный ряд входят устройства MR-381 и MR-382, различающиеся интерфейсами, но построенные на одном чипе — Broadcom Qumran2C. Этот чип активно используется в таких маршрутизаторах, как Cisco NCS 5500/5700, Juniper ACX7000 и Edge-Core AGR400.

B4com MR-381

B4com MR-381

Программное обеспечение

На текущий момент используется B4comOS. Это операционная система, построенная изначально на OcNOS от IP Infusion, но с 2022 года полностью отделившаяся и развивающаяся самостоятельно.

Ниже — схема с описанием основных модулей, которые используются в ОС.

Схема архитектуры ПО

Схема архитектуры ПО

За время, пока я работаю с оборудованием этого вендора, не раз возникала потребность в подобной картинке. Например, периодически приходится обращаться к модулю HSL, который занимается программированием ASIC’а и, соответственно, может показывать информацию о FIB. Ещё интерес представляет модуль NSM, который отвечает за control-plane. Бывает так, что нужно и в него заглянуть. Поэтому хочется всё-таки не просто вводить какие-то команды и смотреть результаты вывода, а ещё и понимать, что происходит.

Первое наше знакомство с MR

С чипом мы уже знакомы и знаем его возможности. Но вопрос в том, как вендор смог адаптировать ASIC и насколько софт, скажем так, «сырой». В общем, в конце 2023 года мы взяли 2 коробки на тесты. Провели достаточно ограниченное тестирование на предмет использования этих маршрутизаторов в сети одного из наших заказчиков. Смотрели на базовый функционал: IS-IS, LDP, L3VPN (средствами MP-BGP VPNv4). Нагружали до 90 Gbps. Нашли мелкие нюансы, о которых знали заранее по работе с коммутаторами, и быстро их сами поправили. В целом, всё было нормально и без каких-либо подводных камней.

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

Речь идёт про EVPN-MPLS с Active-Active IRB и Anycast Gateway. Для тех, кто не знаком с этой темой, вот две полезные статьи: Статья 1 и Статья 2.

Тесты EVPN-MPLS

Топология

Наша тестовая среда включает два сегмента: EVPN-VXLAN и EVPN-MPLS.

Схема среды для тестирования

Схема среды для тестирования

Включения между сегментами выполнены для «проброса» двух сервисов: L3 и L2.

Для L3 используется стандартный Option-A, который с обоих сторон передаётся как type-5 EVPN, но на «стыке» разрывается и передаётся как чистый IPv4.

Пример конфигурации Option-A на PE и BL

Border-leaf

router bgp 300
!
address-family ipv4 vrf VRF-A
max-paths ebgp 2
neighbor 1.1.1.0 remote-as 500
neighbor 1.1.1.0 activate
no neighbor 1.1.1.0 send-community both
neighbor 1.1.1.2 remote-as 500
neighbor 1.1.1.2 activate
no neighbor 1.1.1.2 send-community both
neighbor 1.1.1.0 update-source 1.1.1.1
neighbor 1.1.1.2 update-source 1.1.1.3
exit-address-family
!
address-family ipv4 vrf VRF-B
max-paths ebgp 2
neighbor 2.2.2.0 remote-as 500
neighbor 2.2.2.0 activate
no neighbor 2.2.2.0 send-community both
neighbor 2.2.2.2 remote-as 500
neighbor 2.2.2.2 activate
no neighbor 2.2.2.2 send-community both
neighbor 2.2.2.0 update-source 2.2.2.1
neighbor 2.2.2.2 update-source 2.2.2.3
exit-address-family
!

PE

router bgp 500
!
address-family ipv4 vrf VRF-A
max-paths ebgp 2
neighbor 1.1.1.1 remote-as 300
neighbor 1.1.1.1 activate
neighbor 1.1.1.5 remote-as 301
neighbor 1.1.1.5 activate
neighbor 1.1.1.1 update-source 1.1.1.0
neighbor 1.1.1.5 update-source 1.1.1.4
exit-address-family
!
address-family ipv4 vrf VRF-B
max-paths ebgp 2
neighbor 2.2.2.1 remote-as 300
neighbor 2.2.2.1 activate
neighbor 2.2.2.5 remote-as 301
neighbor 2.2.2.5 activate
neighbor 2.2.2.1 update-source 2.2.2.0
neighbor 2.2.2.5 update-source 2.2.2.4
exit-address-family
!
exit
!

L2 включает более сложные сценарии. Оба сегмента используют EVPN-MH (EVPN Multi-Homing), можно назвать back-to-back evpn-mh (аналогично back-to-back vpc). Объединение выполнено в один общий LAG на 4 физических интерфейсах с разными ESI на парах.

Пример конфигурации L2 на PE и BL

Border-leaf

interface ce2
channel-group 1 mode active
lldp-agent
set lldp port-id-tlv if-name
exit
!
interface po1
switchport
load-interval 30
mtu 9216
evpn multi-homed system-mac 0000.1111.bbbb
port-channel load-balance rtag7

PE

interface ce22 
channel‑group 1 mode active
lldp‑agent
set lldp port‑id‑tlv if‑name
exit
!
interface po1 
switchport
load‑interval 30 
mtu 9216 
evpn multi‑homed system‑mac 0000.1111.aaaa
!

В стенде у нас 2500 таких растянутых L2-сетей, соответственно, такое же количество IRB-интерфейсов на обоих PE, всё это в режиме Active-Active с Anycast Gateway.

Пример конфигурации сервиса на PE

указываем MAC для AGW

evpn irb-forwarding anycast-gateway-mac 0011.2233.4455

создаём 2500 L2 сервисов

mac vrf vni_1000
rd 20.0.0.1:1000
route-target both 500:1000
...
mac vrf vni_3499
rd 20.0.0.1:3499
route-target both 500:3499

создаём 2500 интерфейсов

interface irb1000
ip vrf forwarding VRF-A
evpn irb-if-forwarding anycast-gateway-mac
ip address 30.0.0.1/24
...
interface irb3499
ip vrf forwarding VRF-A
evpn irb-if-forwarding anycast-gateway-mac
ip address 30.9.195.1/24

создаём 2500 evpn-id

evpn mpls id 1000
host-reachability-protocol evpn-bgp vni_1000
evpn irb irb1000
...
evpn mpls id 3499
host-reachability-protocol evpn-bgp vni_3499
evpn irb irb3499

создаём 2500 l2-subinterface

interface po1.1000 switchport
encapsulation dot1q 1000
rewrite pop
mtu 9216
access-if-evpn
map vpn-id 1000
...
interface po1.3499 switchport
encapsulation dot1q 3499
rewrite pop
mtu 9216
access-if-evpn
map vpn-id 3499

На BL настройка чуть проще, так как не требуется использовать IRB и L2-subinterface, растягиваем чистый L2 по EVPN-VXLAN домену.

Пример конфигурации сервиса на BL

создаём 2500 L2 сервисов

nvo vxlan id 11000 ingress-replication inner-vid-disabled
vxlan host-reachability-protocol evpn-bgp vni_11000
vni-name vni_11000
...
nvo vxlan id 13499 ingress-replication inner-vid-disabled
vxlan host-reachability-protocol evpn-bgp vni_13499
vni-name vni_13499

привязываем 2500 сервисов к целевому порту

nvo vxlan access-if port-vlan po1 1000
map vni-name vni_11000
...
nvo vxlan access-if port-vlan po1 3499
map vni-name vni_13499

Методика тестирования

Для генерации трафика использовался TRex.

В тесте запускались 2500 потоков, каждый с уникальным source IP и dot1q тегом, но общим destination IP. Это обеспечивает достаточную энтропию для балансировки и тестирует все 2500 IRB-интерфейсов, через которые маршрутизируется трафик.

Пример скрипта для генерации трафика
from trex_stl_lib.api import * import argparse import os  class STLS1(object):     def __init__(self):         self.mac_counter = 0  # Initialize a counter for generating MAC addresses      def generate_mac(self):         base_mac = [0x10, 0x70, 0x00, 0x00, 0x00, 0x00]         mac_suffix = self.mac_counter * 4096  # Increment by 4096 for each new MAC         for i in range(5, 1, -1):             base_mac[i] = mac_suffix & 0xFF             mac_suffix >>= 8         self.mac_counter += 1         return ':'.join('{:02x}'.format(b) for b in base_mac)      def create_stream(self, vlan_id, src_ip, src_mac, pkt_size=1400):         # Calculate the payload size needed to reach the desired packet size         header_size = len(Ether() / Dot1Q() / IP() / UDP())         payload_size = pkt_size - header_size         payload = 'x' * payload_size          return STLStream(             packet=STLPktBuilder(pkt=Ether(src=src_mac, dst="00:11:22:33:44:55") /                                   Dot1Q(prio=1, vlan=vlan_id) /                                   IP(src=src_ip, dst="10.200.0.5") /                                   UDP(dport=12, sport=1025) / payload),             mode=STLTXCont(pps=10),             # mac_dst_override_mode=STLStreamDstMAC_PKT # another way to explicitly take it         )      def get_streams(self, direction, tunables, **kwargs):         parser = argparse.ArgumentParser(description='Argparser for {}'.format(os.path.basename(__file__)),                                          formatter_class=argparse.ArgumentDefaultsHelpFormatter)          args = parser.parse_args(tunables)         streams = []         # Loop to generate streams for varying VLAN IDs and source IP addresses         vlan_id = 1000         for i in range(0, 10):  # second octet range             for j in range(0, 256):  # third octet range                 src_ip = f"30.{i}.{j}.10"                 src_mac = self.generate_mac()                 streams.append(self.create_stream(vlan_id, src_ip, src_mac))                 vlan_id += 1  # Increment VLAN ID for each stream                 if vlan_id > 1010:                     break             if vlan_id > 1010:                 break         return streams  # dynamic load - used for trex console or simulator def register():     return STLS1()

Сервис L2 растянут до хоста, а на PE (Provider Edge) этот сервис терминируется через IRB-интерфейсы. Конфигурации этих интерфейсов были описаны ранее.

Как видно из вышеописанного, мы предполагаем нагрузочное тестирование и пускаем трафик через большой объем сервисов, в данном случае 2500 штук. Это позволяет заранее выявить узкие места и создать качественную архитектуру.

Что касается полосы пропускания, то мы используем сценарий постепенного набора с шагом в 1% от максимума на порту, то есть 1 Gbps. Вначале запускаем трафик на 1 Gbps, который приблизительно равномерно распределяется по всем созданным сервисам, и затем начинаем наращивать объем.

Мы отслеживаем состояние как control plane, так и data plane. С контрольной плоскостью все понятно: достаточно включить логи и наблюдать за активностью используемых протоколов. Они должны быть стабильными и не должны флапать или перестраиваться. В отношении data plane сначала анализируем счетчики на дашборде TRex, и если необходимо, смотрим аналогичную информацию на самих узлах.

Результат тестов

При базовой нагрузке (1 Gbps) проблем не возникает.

DF/Non-DF выбираются корректно. Принцип выбора соответствует RFC7432 и подробно разобран в статьях, которые я приложил выше.

PE1-MR381#sh evpn mpls  EVPN-MPLS Information  =================     Codes: NW - Network Port            AC - Access Port           (u) - Untagged   VPN-ID   EVI-Name     EVI-Type Type Interface ESI                           VLAN      DF-Status Src-Addr         Dst-Addr         _______________________________________________________________________________________________________________________________ 1000     ----         L2       NW   ----      ----                          ----      ----      20.0.0.1         20.0.0.3         1000     ----         --       AC   po1.1000  00:00:00:11:11:aa:aa:00:00:00 ----      DF        ----             ----             1001     ----         L2       NW   ----      ----                          ----      ----      20.0.0.1         20.0.0.3         1001     ----         --       AC   po1.1001  00:00:00:11:11:aa:aa:00:00:00 ----      NON-DF    ----             ----             1002     ----         L2       NW   ----      ----                          ----      ----      20.0.0.1         20.0.0.3         1002     ----         --       AC   po1.1002  00:00:00:11:11:aa:aa:00:00:00 ----      DF        ----             ----              .....  3497     ----         L2       NW   ----      ----                          ----      ----      20.0.0.1         20.0.0.3         3497     ----         --       AC   po1.3497  00:00:00:11:11:aa:aa:00:00:00 ----      NON-DF    ----             ----             3498     ----         L2       NW   ----      ----                          ----      ----      20.0.0.1         20.0.0.3         3498     ----         --       AC   po1.3498  00:00:00:11:11:aa:aa:00:00:00 ----      DF        ----             ----             3499     ----         L2       NW   ----      ----                          ----      ----      20.0.0.1         20.0.0.3         3499     ----         --       AC   po1.3499  00:00:00:11:11:aa:aa:00:00:00 ----      NON-DF    ----             ----     

Аналогичная история с Aliasing и ESI label.

PE1-MR381#sh evpn mpls label alias  S - Self R - Remote ESI                            PE-IP-ADDRESS        TENANT               ALIAS-LABEL          ============================================================================================= 00:00:00:11:11:aa:aa:00:00:00  20.0.0.1(S)          1000                   30 00:00:00:11:11:aa:aa:00:00:00  20.0.0.1(S)          1001                   29 00:00:00:11:11:aa:aa:00:00:00  20.0.0.1(S)          1002                   28  ....  00:00:00:11:11:aa:aa:00:00:00  20.0.0.3(R)          3497                31959 00:00:00:11:11:aa:aa:00:00:00  20.0.0.3(R)          3498                31958 00:00:00:11:11:aa:aa:00:00:00  20.0.0.3(R)          3499                31961
PE1-MR381#sh evpn mpls label esi  S - Self R - Remote ESI                            PE-IP-ADDRESS        ESI-LABEL            ================================================================ 00:00:00:11:11:aa:aa:00:00:00  20.0.0.1(S)            18 00:00:00:11:11:aa:aa:00:00:00  20.0.0.3(R)            18

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

Вывод с MR

Вывод с MR

При использовании TCP подобной проблемы не возникает, и весь трафик классифицируется корректно.

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

Вывод с TRex

Вывод с TRex

Также счетчики на очередях показывают корректные значения.

Вывод с MR

Вывод с MR

Выводы

Этот опыт показал важность комплексного тестирования. Без нагрузочных тестов мы могли бы перейти к следующей фазе и не обратить внимание на особенности реализации, что могло бы привести к проблемам на этапе ПНР или, что еще хуже, на ПСИ. В такой ситуации времени на разбор полетов уже не будет, и придется действовать быстро и решительно. Также мы проверили готовность вендора к быстрому реагированию на выявленные недостатки, что является важным фактором для дальнейшего взаимодействия.

Подписывайтесь на мой канал: https://t.me/like_a_bus_channel. Пишу о тестах, своем опыте и прочем, с чем сталкиваюсь на работе и не только!


ссылка на оригинал статьи https://habr.com/ru/articles/833526/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *