Overlay

Overlay - виртуальная сеть туннелей, натянутая поверх Underlay, она позволяет ВМ одного клиента общаться друг с другом, при этом обеспечивая изоляцию от других клиентов.
Данные клиента инкапсулируются в какие-либо туннелирующие заголовки для передачи через общую сеть.
https://fs.linkmeup.ru/images/adsm/1/overlay.png

Так ВМ одного клиента (одного сервиса) могут общаться друг с другом через Overlay, даже не подозревая какой на самом деле путь проходит пакет. Overlay может быть например таким, как уже я упоминал выше:

  • GRE-туннель
  • VXLAN
  • EVPN
  • L3VPN
  • GENEVE

Overlay’ная сеть обычно настраивается и поддерживается через центральный контроллер. С него конфигурация, Control Plane и Data Plane доставляются на устройства, которые занимаются маршрутизацией и инкапсуляцией клиентского трафика. Чуть ниже разберём это на примерах. Да, это SDN в чистом виде.

Существует два принципиально различающихся подхода к организации Overlay-сети:

  1. Overlay с ToR’a
  2. Overlay с хоста

Overlay с ToR’a

Overlay может начинаться на коммутаторе доступа (ToR), стоящем в стойке, как это происходит, например, в случае VXLAN-фабрики.
Это проверенный временем на сетях ISP механизм и все вендоры сетевого оборудования его поддерживают.
Однако в этом случае ToR-коммутатор должен уметь разделять различные сервисы, соответственно, а сетевой администратор должен в известной степени сотрудничать с администраторами виртуальных машин и вносить изменения (пусть и автоматически) в конфигурацию устройств.
https://fs.linkmeup.ru/images/adsm/1/vxlan-fabric.png
Тут я отошлю читателя к статье о VxLAN на хабре нашего старого друга bormoglotx.
В этой презентации с ENOG подробно описаны подходы к строительству сети ДЦ с EVPN VXLAN-фабрикой.
А для более полного погружения в реалии, можно почитать цискину книгу A Modern, Open, and Scalable Fabric: VXLAN EVPN.
Замечу, что VXLAN - это только метод инкапсуляции и терминация туннелей может происходить не на ToR’е, а на хосте, как это происходит в случае OpenStack’а, например.
Однако, VXLAN-фабрика, где overlay начинается на ToR’е является одним из устоявшихся дизайнов оверлейной сети.

Overlay с хоста

Другой подход - начинать и терминировать туннели на конечных хостах.
В этом случае сеть (Underlay) остаётся максимально простой и статичной.
А хост сам делает все необходимые инкапсуляции.
https://fs.linkmeup.ru/images/adsm/1/ip-fabric.png
Для этого потребуется, безусловно, запускать специальное приложение на хостах, но оно того стоит.
Во-первых, запустить клиент на linux-машине проще или, скажем так, - вообще возможно - в то время как на коммутаторе, скорее всего, придётся пока обращаться к проприетарным SDN-решениям, что убивает идею мультивендорности.
Во-вторых, ToR-коммутатор в этом случае можно оставить максимально простым, как с точки зрения Control Plane’а, так и Data Plane’а. Действительно - с SDN-контроллером ему тогда общаться не нужно, и хранить сети/ARP’ы всех подключенных клиентов - тоже - достаточно знать IP-адрес физической машины, что кратно облегчает таблицы коммутации/маршрутизации.

В серии АДСМ я выбираю подход оверлея с хоста - далее мы говорим только о нём и возвращаться к VXLAN-фабрике мы уже не будем.


Проще всего рассмотреть на примерах. И в качестве подопытного мы возьмём OpenSource’ную SDN платформу OpenContrail, ныне известную как Tungsten Fabric.

В конце статьи я приведу некоторые размышления на тему аналогии с OpenFlow и OpenvSwitch.

На примере Tungsten Fabric

На каждой физической машине есть vRouter - виртуальный маршрутизатор, который знает о подключенных к нему сетях и каким клиентам они принадлежат - по сути - PE-маршрутизатор. Для каждого клиента он поддерживает изолированную таблицу маршрутизации (читай VRF). И собственно vRouter делает Overlay’ное туннелирование.
Чуть подробнее про vRouter - в конце статьи.
Каждая ВМ, расположенная на гипервизоре, соединяется с vRouter’ом этой машины через TAP-интерфейс.

TAP - Terminal Access Point - виртуальный интерфейс в ядре linux, которые позволяет осуществлять сетевое взаимодействие.

https://fs.linkmeup.ru/images/adsm/1/tf-host.png
Если за vRouter’ом находится несколько сетей, то для каждой из них создаётся виртуальный интерфейс, на который назначается IP-адрес - он будет адресом шлюза по умолчанию.
Все сети одного клиента помещаются в один VRF (одну таблицу), разных - в разные.

Сделаю тут оговорку, что не всё так просто, и отправлю любознательного читателя в конец статьи.

Чтобы vRouter’ы могли общаться друг с другом, а соответственно и ВМ, находящиеся за ними, они обмениваются маршрутной информацией через SDN-контроллер.

https://fs.linkmeup.ru/images/adsm/1/sdn-controller.png

Чтобы выбраться во внешний мир, существует точка выхода из матрицы - шлюз виртуальной сети VNGW - Virtual Network GateWay (термин мой).

https://fs.linkmeup.ru/images/adsm/1/vngw.png

Теперь рассмотрим примеры коммуникаций - и будет ясность.

Коммуникация внутри одной физической машины

VM0 хочет отправить пакет на VM2. Предположим пока, что это ВМ одного клиента.

Data Plane

  1. У VM-0 есть маршрут по умолчанию в его интерфейс eth0. Пакет отправляется туда. Этот интерфейс eth0 на самом деле виртуально соединён с виртуальным маршрутизатором vRouter через TAP-интерфейс tap0.

  2. vRouter анализирует на какой интерфейс пришёл пакет, то есть к какому клиенту (VRF) он относится, сверяет адрес получателя с таблицей маршрутизации этого клиента.

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

    https://fs.linkmeup.ru/images/adsm/1/intra-hv-dp.png

Пакет в этом случае не попадает в физическую сеть - он смаршрутизировался внутри vRouter’а.

Control Plane

Гипервизор при запуске виртуальной машины сообщает ей:

  • Её собственный IP-адрес.
  • Маршрут по умолчанию - через IP-адрес vRouter’а в этой сети.

vRouter’у через специальный API гипервизор сообщает:

  • Что нужно создать виртуальный интерфейс.

  • Какой ей (ВМ) нужно создать Virtual Network.

  • К какому VRF его (VN) привязать.

  • Статическую ARP-запись для этой VM - за каким интерфейсом находится её IP-адрес и к какому MAC-адресу он привязан.

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

    https://fs.linkmeup.ru/images/adsm/1/intra-hv-cp.png

Таким образом все ВМ одного клиента на данной машине vRouter видит как непосредственно подключенные сети и может сам между ними маршрутизировать.


А вот VM0 и VM1 принадлежат разным клиентам, соответственно, находятся в разных таблицах vRouter’а.
Смогут ли они друг с другом общаться напрямую, зависит от настроек vRouter и дизайна сети.
Например, если ВМ обоих клиентов используют публичные адреса, или NAT происходит на самом vRouter’е, то можно сделать и прямую маршрутизацию на vRouter.

В противной же ситуации возможно пересечение адресных пространств - нужно ходить через NAT-сервер, чтобы получить публичный адрес - это похоже на выход во внешние сети, о которых ниже.


Коммуникация между ВМ, расположенными на разных физических машинах

Data Plane

  1. Начало точно такое же: VM-0 посылает пакет с адресатом VM-7 (172.17.3.2) по своему дефолту.

  2. vRouter его получает и на этот раз видит, что адресат находится на другой машине и доступен через туннель Tunnel0.

  3. Сначала он вешает метку MPLS, идентифицирующую удалённый интерфейс, чтобы на обратной стороне vRouter мог определить куда этот пакет поместить причём без дополнительных лукапов.

    https://fs.linkmeup.ru/images/adsm/1/inter-hv-dp.png
  4. У Tunnel0 источник 10.0.0.2, получатель: 10.0.1.2.
    vRouter добавляет заголовки GRE (или UDP) и новый IP к исходному пакету.
  5. В таблице маршрутизации vRouter есть маршрут по умолчанию через адрес ToR1 10.0.0.1. Туда и отправляет.

    https://fs.linkmeup.ru/images/adsm/1/headers.png
  6. ToR1 как участник Underlay сети знает (например, по OSPF), как добраться до 10.0.1.2, и отправляет пакет по маршруту. Обратите внимание, что здесь включается ECMP. На иллюстрации два некстхопа, и разные потоки будут раскладываться в них по хэшу. В случае настоящей фабрики тут будет скорее 4 некстхопа.
    При этом знать, что находится под внешним заголовком IP ему не нужно. То есть фактически под IP может быть бутерброд из IPv6 over MPLS over Ethernet over MPLS over GRE over over over GREка.
  7. Соответственно на принимающей стороне vRouter снимает GRE и по MPLS-метке понимает, в какой интерфейс этот пакет надо передать, раздевает его и отправляет в первоначальном виде получателю.

Control Plane

При запуске машины происходит всё то же, что было описано выше. И плюс ещё следующее:

  • Для каждого клиента vRouter выделяет MPLS-метку. Это сервисная метка L3VPN, по которой клиенты будут разделяться в пределах одной физической машины.
    На самом деле MPLS-метка выделяется vRouter’ом безусловно всегда - ведь неизвестно заранее, что машина будет взаимодействовать только с другими машинам за тем же vRouter’ом и это скорее всего даже не так.
  • vRouter устанавливает соединение с SDN-контроллером по протоколу BGP (или похожему на него - в случае TF -это XMPP 0_o).

  • Через эту сессию vRouter сообщает SDN-контроллеру маршруты до подключенных сетей:

    • Адрес сети
    • Метод инкапсуляции (MPLSoGRE, MPLSoUDP, VXLAN)
    • MPLS-метку клиента
    • Свой IP-адрес в качестве nexthop
  • SDN-контроллер получает такие маршруты ото всех подключенных vRouter’ов, и отражает их другим. То есть он выступает Route Reflector’ом.

То же самое происходит и в обратную сторону.

https://fs.linkmeup.ru/images/adsm/1/inter-hv-cp.png
Overlay может меняться хоть каждую минуту. Примерно так это и происходит в публичных облаках, когда клиенты регулярно запускают и выключают свои виртуальные машины.
Центральный контроллер берёт на себя все сложности с поддержанием конфигурации и контролем таблиц коммутации/маршрутизации на vRouter.
Если говорить грубо, то контроллер запиривается со всеми vRouter’ами по BGP (или похожему на него протоколу) и просто передаёт маршрутную информацию. BGP, например, уже имеет Address-Family для передачи метода инкапсуляции MPLS-in-GRE или MPLS-in-UDP.

При этом не меняется никоим образом конфигурация Underlay-сети, которую кстати, автоматизировать на порядок сложнее, а сломать неловким движением проще.


Выход во внешний мир

Где-то симуляция должна закончиться, и из виртуального мира нужно выйти в реальный. И нужен таксофон^W шлюз.

Практикуют два подхода:

  1. Ставится аппаратный маршрутизатор.

  2. Запускается какой-либо appliance, реализующий функции маршрутизатора (да-да, вслед за SDN мы и с VNF столкнулись). Назовём его виртуальный шлюз.

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

Одной своей ногой шлюз смотрит в виртуальную сеть Overlay, как обычная Виртуальная Машина, и может взаимодействовать со всеми другими ВМ. При этом она может терминировать на себе сети всех клиентов и, соответственно, осуществлять и маршрутизацию между ними.

Другой ногой шлюз смотрит уже в магистральную сеть и знает о том, как выбраться в Интернет.

https://fs.linkmeup.ru/images/adsm/1/two_legs.png

Data Plane

То есть процесс выглядит так:

  1. VM-0, имея дефолт всё в тот же vRouter, отправляет пакет с адресатом во внешнем мире (185.147.83.177) в интерфейс eth0.

  2. vRouter получает этот пакет и делает лукап адреса назначения в таблице маршрутизации - находит маршрут по умолчанию через шлюз VNGW1 через Tunnel 1.
    Также он видит, что это туннель GRE с SIP 10.0.0.2 и DIP 10.0.255.2, а ещё нужно сначала повесить MPLS-метку данного клиента, которую ожидает VNGW1.
  3. vRouter упаковывает первоначальный пакет в заголовки MPLS, GRE и новый IP и отправляет на адрес ToR1 10.0.0.1 по дефолту.

  4. Андерлейная сеть доставляет пакет до шлюза VNGW1.

  5. Шлюз VNGW1 снимает туннелирующие заголовки GRE и MPLS, видит адрес назначения, консультируется со своей таблицей маршрутизации и понимает, что он направлен в Интернет - значит через Full View или Default. При необходимости производит NAT-трансляцию.

  6. От VNGW до бордера может быть обычная IP-сеть, что вряд ли.
    Может быть классическая MPLS сеть (IGP+LDP/RSVP TE), может быть обратно фабрика с BGP LU или GRE-туннель от VNGW до бордера через IP-сеть.
    Как бы то ни было VNGW1 совершает необходимые инкапсуляции и отправляет первоначальный пакет в сторону бордера.
    https://fs.linkmeup.ru/images/adsm/1/outside-dp.png
    Трафик в обратную сторону проходит те же шаги в противоположном порядке.
  7. Бордер добрасывает пакет до VNGW1

  8. Тот его раздевает, смотрит на адрес получателя и видит, что тот доступен через туннель Tunnel1 (MPLSoGRE или MPLSoUDP).

  9. Соответственно, вешает метку MPLS, заголовок GRE/UDP и новый IP и отправляет на свой ToR3 10.0.255.1.
    Адрес назначения туннеля - IP-адрес vRouter’а, за которым стоит целевая ВМ - 10.0.0.2.
  10. Андерлейная сеть доставляет пакет до нужного vRouter’а.

  11. Целевой vRouter снимает GRE/UDP, по MPLS-метке определяет интерфейс и шлёт голый IP-пакет в свой TAP-интерфейс, связанный с eth0 ВМ.

    https://fs.linkmeup.ru/images/adsm/1/outside-dp-reverse.png

Control Plane

VNGW1 устанавливает BGP-соседство с SDN-контроллером, от которого он получает всю маршрутную информацию о клиентах: за каким IP-адресом (vRouter’ом) находится какой клиент, и какой MPLS-меткой он идентифицируется. Аналогично он сам SDN-контроллеру сообщает дефолтный маршрут с меткой этого клиента, указывая себя в качестве nexthop’а. А дальше этот дефолт приезжает на vRouter’ы.

На VNGW обычно происходит агрегация маршрутов или NAT-трансляция.
И в другую сторону в сессию с бордерами или Route Reflector’ами он отдаёт именно этот агрегированный маршрут. А от них получает маршрут по умолчанию или Full-View, или что-то ещё.
В плане инкапсуляции и обмена трафиком VNGW ничем не отличается от vRouter.
Если немного расширить область, то к VNGW и vRouter’ам можно добавить другие сетевые устройства, такие как файрволы, фермы очистки или обогащения трафика, IPS итд.
И с помощью последовательного создания VRF и правильного анонса маршрутов, можно заставлять трафик петлять так, как вам хочется, что и называется Service Chaining’ом.
То есть и тут SDN-контроллер выступает в роли Route-Reflector’а между VNGW, vRouter’ами и другими сетевыми устройствами.
Но фактически контроллер спускает ещё информацию об ACL и PBR (Policy Based Routing), заставляя отдельные потоки трафика ходить не так, как им велит маршрут.
https://fs.linkmeup.ru/images/adsm/1/outside-cp.png