В конце 2023 года отечественный вендор B4com Tech анонсировал выпуск маршрутизаторов для провайдерского сегмента IP/MPLS. Среди новых моделей наше внимание привлекли те, которые поддерживают интерфейсы 100G, поскольку они стали стандартом подключения в современных центрах обработки данных (ЦОД).
В модельный ряд входят устройства MR-381 и MR-382, различающиеся интерфейсами, но построенные на одном чипе — Broadcom Qumran2C. Этот чип активно используется в таких маршрутизаторах, как Cisco NCS 5500/5700, Juniper ACX7000 и Edge-Core AGR400.
Программное обеспечение
На текущий момент используется 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 неверно классифицируется и попадает в другую очередь, где в дальнейшем отбрасывается.
При использовании TCP подобной проблемы не возникает, и весь трафик классифицируется корректно.
После общения с вендором и корректировки данного поведения для UDP потоков с помощью патча, мы повторили тесты и успешно достигли целевой нагрузки.
Также счетчики на очередях показывают корректные значения.
Выводы
Этот опыт показал важность комплексного тестирования. Без нагрузочных тестов мы могли бы перейти к следующей фазе и не обратить внимание на особенности реализации, что могло бы привести к проблемам на этапе ПНР или, что еще хуже, на ПСИ. В такой ситуации времени на разбор полетов уже не будет, и придется действовать быстро и решительно. Также мы проверили готовность вендора к быстрому реагированию на выявленные недостатки, что является важным фактором для дальнейшего взаимодействия.
Подписывайтесь на мой канал: https://t.me/like_a_bus_channel. Пишу о тестах, своем опыте и прочем, с чем сталкиваюсь на работе и не только!
ссылка на оригинал статьи https://habr.com/ru/articles/833526/
Добавить комментарий