
Построение отказоустойчивой гибридной сети между локальной инфраструктурой и облаком — одна из ключевых задач при миграции. Стандартных решений здесь не существует: выбор архитектуры и технологий зависит от требований безопасности, производительности и желания избежать vendor lock-in.
Я хочу показать один из способов решения такой задачи на примере облака VK Cloud с учетом специфики его SDN-сети. Отдельно хочется добавить, что рассматриваемый в статье подход к построению сетевой связности может быть успешно применен не только в VK Cloud.
В основу статьи легли вопросы и задачи, с которыми клиенты часто обращаются к командам Presale архитекторов и Professional services VK Cloud, когда они хотят построить надежное гибридное решение для своего бизнеса.
Мне хотелось написать статью, которая будет не научно-популярным повествованием, а практическим руководством, систематизирующим имеющиеся знания по разным продуктам и сетевым технологиям.
Проблематика
Когда возникает задача перенести часть традиционной ИТ-инфраструктуры в облако, сразу появляется ряд вопросов:
какое архитектурное решение лучше использовать;
какой набор технологий поможет решить поставленную задачу;
как получить надежное отказоустойчивое решение;
как правильно заложить фундамент сетевой связности в облаке, который сможет бесшовно масштабироваться вместе с ростом бизнеса.
При этом ответить на них решением класса «всё в одном» нельзя по ряду причин:
SDN-технологии в облаках вносят свою специфику (накладывают требования и ограничения) в способы построения IP-связности.
Возникают различные требования со стороны компонентов ИТ-инфраструктуры, части которой переносятся в облако: количество пакетов в секунду, совокупная пропускная способность, защита передаваемых данных и другие.
Хочется использовать привычные средства для управления маршрутизацией и безопасностью (например, NGFW).
Хочется избежать ситуации, которую традиционно называют Vendor Lock, то есть привязки к одному поставщику.
Выбранный подход (архитектурное решение) не должен ограничивать рост инфраструктуры с точки зрения скоростей и объемов передаваемой по сети информации.
На этом список не заканчивается, но я постарался выделить довольно популярные тезисы, которые будут предопределять дальнейший путь в решении поставленной задачи.
Сценарий
Представьте себя в роли администратора локальной инфраструктуры, которая должна пройти по пути облачной гибридизации. Долгое время мы жили в привычном мире железа и проводов (межсетевые экраны, маршрутизаторы, коммутаторы, серверы, оптические и медные кабели), а теперь в нашу зону комфорта вторгаются облачные (виртуальные) технологии, до которых мы не можем дотянуться физическими проводами.
Облачная инфраструктура вполне может быть объединена с локальной при помощи физических каналов связи — для многих инженеров здесь привычно появится термин «темное волокно», или «темная оптика». Но такое включение следует рассматривать как отдельный проект, который потребует дополнительных инвестиций и времени — ведь задача по аренде и тем более по строительству новых оптических каналов связи может потребовать значительного времени.
На уровне бизнеса задача может звучать довольно просто: поддержать перенос ИТ-нагрузок в облако и обеспечить надежный доступ к облачной инфраструктуре. Располагая представлением о локальной ИТ-инфраструктуре, ее функционально-технических возможностях, можно собрать следующий набор требований, которые позволят решить поставленную бизнес-задачу:
Два оператора интернет-связи: основной и резервный.
Оба оператора связи подключены к одному или нескольким маршрутизаторам (бывают случаи, когда один из маршрутизаторов лежит предварительно настроенным в качестве ЗИП).
За маршрутизаторами находятся один или несколько приватных адресных префиксов (CIDR).
Особенности географического расположения локальной инфраструктуры не позволяют быстро и дешево организовать выделенные каналы связи до ЦОД или точек присутствия облака, и мы вынуждены строить IP-связность до облака через интернет.
Целевое решение должно автоматически отрабатывать отказ основного провайдера связи.
Целевое решение должно отрабатывать отказ одной из зон доступности облака.
Данные не должны передаваться через интернет в открытом виде.
Пример из реальной жизни
Чтобы случай не казался надуманным или синтетическим, достаточно посмотреть на производственное предприятие или транспортно-логистический центр, когда география местоположения не позволяет арендовать «темное волокно» и быстро организовать выделенное подключение в ЦОД или на точку присутствия инфраструктуры облака.
Точка присутствия — место, где размещается маршрутизирующее оборудование, которое позволяет оборудованию клиента подключиться к облачному провайдеру с помощью кроссировки.
В своей практике я неоднократно встречался с ситуациями, когда надо подвести надежный интернет-канал на подобный промышленный объект (речь идет про проводной доступ к интернету). Очень часто провайдеры предлагают подключить площадку с использованием «радиомоста». С точки зрения надежности такое решение не может похвастаться 100% Uptime, так что, если другого варианта на площадке не существует, мостов должно быть несколько. При этом я рекомендую периодически возвращаться к задаче по организации наземного канала связи. Сети крупных операторов находятся в постоянном развитии, что позволяет с оптимизмом смотреть на то, что в один день оптика или витая пара «придут в гости на объект».
Архитектурное решение
Для проектирования решения я буду использовать сервисы IaaS (сети и виртуализация). Данный подход позволит наглядно продемонстрировать, что решение можно масштабировать не только на облако VK Cloud.
Если отталкиваться от названных выше требований, визуальное представление объединенной (гибридной) ИТ-инфраструктуры будет выглядеть следующим образом.

На стороне инфраструктуры клиента:
один маршрутизатор с подключением к двум операторам интернет-связи;
приватный адресный префикс (CIDR) в локальной сети за маршрутизатором;
несколько серверов.
Приватных адресных префиксов может быть несколько. Увеличение количества приватных адресных префиксов практически не отразится на настройке.
На стороне VK Cloud:
Две зоны доступности: MS1 и ME1.
Приватная сеть (L2) и приватная подсеть, «растянутая» между зонами доступности VK Cloud.
Два маршрутизатора (по одному в каждой зоне доступности).
Каждый из маршрутизаторов подключен одним интерфейсом к интернету, а другим интерфейсом к приватной виртуальной сети с приватным адресным префиксом (CIDR).
Несколько виртуальных серверов с распределением по зонам доступности. Они сделают топологию более наглядной, а также помогут с проверочными тестами на IP-связность.
Технологический стек
Виртуальные сети VK Cloud работают в режиме L2, что дает возможность использовать VRRP (или его реализацию при помощи Keepalived в ОС Linux).
Для решения поставленной задачи я буду использовать следующий набор технологий:
Ubuntu 24.04.3 LTS в качестве ОС общего назначения с использованием стандартного «облачного» образа (образа, который доступен любому клиенту для создания виртуальной машины).
Keepalived для того, чтобы объявить виртуальный IP-адрес в качестве шлюза в локальной сети облака.
Netplan для настройки сети и управления ей (основной инструмент для настройки сети Ubuntu начиная с версии 18 LTS).
IPtables для управления NAT-трансляцией, а также MSS-оптимизацией туннелируемых пакетов.
GRE для организации VPN-соединения «точка — точка».
StrongSwan в транспортном режиме для защиты GRE-трафика (IKEv2 + PSK-аутентификация).
FRR для управления BGP-маршрутизацией.
Отдельно обращаю внимание на технологии автоматизации, которые помогут «склеить» все вместе:
Terraform для создания облачного окружения.
Ansible для настройки программного обеспечения.
Выбор технологий определяется их доступностью, функциональностью, универсальностью, технологической зрелостью, наличием хорошей сопроводительной документации, а также проектным опытом.
Несколько полезных ссылок на документацию к выбранным технологиям:
Настройка
Вы можете собрать аналогичный проект самостоятельно, обратившись к конфигурационным файлам проекта, которые я опубликовал на GitHub.
Основное внимание в статье (практическом руководстве) будет направлено на настройку инфраструктуры в облаке. Технологический стек, который был выбран для решения, позволяет установить подключение к большому числу аппаратных и программных решений по управлению маршрутизацией, благодаря использованию открытого программного обеспечения, которое основано на стандартах, описанных в RFC.
Технологии виртуальных частных сетей (VPN), которые затрагиваются в данном материале, используются исключительно в целях организации защищенного обмена информацией между облаком и локальной инфраструктурой, а используемые в процессе настройки алгоритмы безопасности являются стандартными для большинства облаков.
Приступая к настройке облачной части проекта, я рекомендую придерживаться способа управления инфраструктурой через код IaC. Для кого-то это может показаться сложнее, чем настроить каждый из серверов в окружении привычным ручным способом, но на деле это дает гораздо больше контроля над инфраструктурой, а также повышает уровень прозрачности административных операций через контроль над изменениями.
Для настройки облачной части окружения я буду использовать привычные в мире IaC инструменты — Terraform и Ansible.
Спланируем IP-адресацию для будущего проекта
Для того чтобы сценарий был наглядным и понятным одновременно, я предлагаю следующую IP-адресацию, которая будет использована в процессе настройки. Если вам захочется воспользоваться моей автоматизацией, то сможете без труда адаптировать сценарий к своим значениям через несколько управляющих файлов.
Далее я предлагаю посмотреть на памятку (карточку) с IP-адресами, которые я буду использовать в настройке:

Подготовка рабочей станции администратора
Для запуска проекта нам потребуется проект в VK Cloud, а также дополнительное программное обеспечение:
доступ к управлению через API, активированный на уровне проекта в VK Cloud;
приватный SSH-ключ, добавленный в список ключей администратора проекта VK Cloud;
установленные и настроенные инструменты командной строки OpenStack CLI;
установленные и настроенные компоненты для работы с Terraform.
Порядок настройки
Настройка будет выполнена в два этапа:
Создание и настройка облачной инфраструктуры при помощи Terraform.
Настройка операционной системы маршрутизаторов при помощи Ansible.
Настройка маршрутизатора на удаленной площадке (для большей наглядности) при помощи CLI-команд (на примере MikroTik RouterOS 7.20).
Особенности Terraform-сценария
Первичная подготовка рабочей станции администратора для использования Terraform не рассматривается. Вы можете воспользоваться следующей инструкцией для настройки Terraform для вашей ОС.
Для сборки Terraform-манифеста я буду руководствоваться официальной опубликованной документацией к Terraform-провайдеру VK Cloud:
Получившийся манифест использует стандартные блоки из состава провайдера, а единственная кастомизация реализована через bash-скрипт, который запускается в качестве user_data аргумента при создании виртуальных машин, которые будут выступать в качестве маршрутизаторов.
Кто-то может сказать, что я «придумал костыль» на ровном месте с этим скриптом в user_data, что можно обойтись без него, но не все так просто.
Постараюсь подробно рассказать, почему без скрипта для настройки виртуальных машин с ролью «маршрутизатор» не обойтись.
Для того чтобы лучше понять мои аргументы в пользу скрипта, я предлагаю посмотреть на фрагмент диаграммы крупным планом:

Обращаю ваше внимание, что каждый из маршрутизаторов имеет по два порта:
порт с прямым подключением к приватной сети;
порт с прямым подключением к интернету.
Во время предварительной подготовки приватных портов для LAN-интерфейсов маршрутизаторов используется отключение специального параметра Port Security, что позволяет SDN корректно работать с трафиком, проходящим через виртуальную машину.
Почему и для чего нужен скрипт?
Особенности SDN и Terraform провайдера не позволяют заранее создать порт с прямым подключением к интернету, присвоить ему имя, выбрать адрес, или назначить какие-то другие аргументы. Единственная возможность, которая есть у пользователя на руках — сообщить виртуальной машине, что она будет подключена к сети с доступом в интернет напрямую. Автоматика «под капотом SDN» выберет порт, относящийся к одному из нескольких публичных адресных префиксов, случайным образом и назначит его на интерфейс виртуальной машины. Именно в этом месте без использования скрипта сценарий сломается, так как заранее нам не будет известен ID объекта, к которому можно обратиться для тонкой настройки операционной системы через упрощенный аргумент user_data.
Другие операции, которые выполняются в процессе работы Terraform манифеста, — это:
Создание приватной сети.
Создание приватной подсети с заданными характеристиками.
Создание правил Firewall (создание групп безопасности и правил к ним).
Создание приватных портов в локальной подсети для использования в качестве LAN-интерфейс.
Создание нескольких виртуальных машин.
Сопоставление групп безопасности и прочих сущностей с виртуальными машинами.
Внутри bash-скрипта
Какой же тюнинг может потребоваться для операционной системы, чтобы все работало хорошо? Далее я подробно расскажу о том, что именно настраивается на шаге постпроцессинга при создании виртуальных машин с ролью «маршрутизатор».
Определить интерфейс (WAN), который подключен к интернету:
получить имя интерфейса;
получить MAC-адрес интерфейса;
получить IP-адрес и сетевую маску интерфейса;
получить адрес шлюза по умолчанию.
Определить интерфейс (LAN), который подключен к приватной сети:
получить имя интерфейса;
получить MAC-адрес интерфейса;
получить IP-адрес и сетевую маску интерфейса.
Отключить cloud-init для выполнения управления сетевыми настройками виртуальной машины.
Создать резервную копию файла netplan, которая была собрана с использованием cloud-init в момент создания виртуальной машины.
Создать новый статический файл конфигурации netplan для управления именами и IP-адресами виртуальных сетевых интерфейсов маршрутизатора с использованием ранее собранной (полученной) информации.
Применить новую настройку и выполнить проверку доступности шлюза (валидация настроек статического файла для управления сетью).
Выполнить перезапуск ВМ.
В процессе работы все события журналируются. Лог операций доступен в директории /var/log/network-config.log.
Пример лог-файла
`Starting network configuration...
Identified LAN interface: ens4 (MAC: fa:16:3e:04:c3:b1) with private IP: 10.200.10.254, Netmask: 255.255.255.0, CIDR: /24
Identified WAN interface: ens3 (MAC: fa:16:3e:40:56:c7) with public IP: 210.0.0.1, Netmask: 255.255.255.0, CIDR: /24, Gateway: 210.0.0.254
Final interface assignment:
LAN Interface: ens4 (MAC: fa:16:3e:04:c3:b1)
LAN IPv4: 10.200.10.254
LAN Netmask: 255.255.255.0
LAN CIDR: /24
WAN Interface: ens3 (MAC: fa:16:3e:40:56:c7)
WAN IPv4: 210.0.0.1
WAN Netmask: 255.255.255.0
WAN CIDR: /24
WAN Gateway: 210.0.0.254
Backed up existing netplan configuration
Disabling Cloud-Init for Networking...
Creating network config file
Network config file has been created
Netplan configuration generated successfully
Network configuration applied successfully! Gateway is reachable.
Network configuration applied. Rebooting in 10 seconds. Press Ctrl+C to cancel.`
Особенности Ansible сценария
Первичная подготовка рабочей станции администратора для использования Ansible не рассматривается. Вы можете воспользоваться следующей инструкцией для настройки Ansible.
Коллекция Ansible Playbook включает в себя главным образом набор ролей для настройки маршрутизаторов под ключ.
Для управления настройками из единого окна предлагается файл inventory.ini, который нужно будет заполнить требуемыми переменными, специфичными для On-Premise и облачного окружения, прежде чем Ansible-сценарий будет запущен.
Рассмотрим этот набор подробнее.
Роль base:
установка обновлений ОС;
установка диагностических утилит;
установка сетевых утилит;
активация ip_forward в параметрах sysctl (персистентная конфигурация);
активация модуля ядра, отвечающего за работу GRE (персистентная конфигурация);
установка iptables-persistent и настройка на автоматический запуск при старте ОС;
настройка NAT masquerade.
Роль disable_ipv6:
Здесь все очень просто: отключаем IPv6, так как он не используется в нашем сценарии.
Роль frr_router:
установка пакетов, необходимых для работы ПО FRR (FRRouting Project);
активация демонов, необходимых для запуска и управления BGP-функциональностью (персистентная конфигурация);
создание конфигурации по шаблону (с использованием переменных из файла inventory.ini);
активация созданной конфигурации.
Роль gre:
создание конфигурационных файлов netplan для управления GRE-туннелями (конфигурация собирается с использованием переменных из файла inventory.ini);
применение новых настроек (активация GRE-туннелей);
считывание обновленного списка сетевых интерфейсов (чтобы Ansible смог использовать сведения о новых интерфейсах GRE);
создание правил MSS-тюнинга для Path MTU оптимизации (таблица IP Tables Mangle нам в помощь), при этом создаваемые правила проверяются на уникальность, что исключает появление дубликатов.
Роль keepalived:
установка ПО Keepalived для настройки VRRP-протокола;
создание конфигурации по шаблону с использованием переменных из файла inventory.ini;
активация изменений (персистентная конфигурация).
Роль private_base (опциональная роль):
Эта роль предназначена для настройки ОС тестовых серверов в облачной сети VK Cloud. Для корректного запуска этой роли потребуется настроенная IP-связность между CIDR облачной сети и рабочей станцией администратора.
установка обновлений ОС;
установка диагностических утилит;
установка сетевых утилит.
Роль strongswan:
установка нескольких пакетов, необходимых для корректной работы ПО strongSwan и средств управления swanctl;
создание файла конфигурации по шаблону с использованием переменных из файла inventory.ini;
внесение правок в скрипты инициализации strongSwan для автоматизации загрузки созданной конфигурации;
перезапуск сервиса strongswan-starter для применения внесенных изменений.
Собираем все вместе
Запускаем Terraform
К настоящему моменту времени у нас должны быть готовы к запуску два сценария (terraform + ansible), и мы приступаем к настройке окружения, запуская сценарий Terraform.
На работу Terraform-сценария потребуется некоторое время, по окончании которого мы должны получить безошибочно собранное облачное окружение.
Как только сценарий отработал (без ошибок, разумеется), инициализируем CLI-инструменты для работы с облаком VK, если этого не было сделано ранее. Здесь вам придет на помощь документация по установке и настройке OpenStack CLI.
Готовимся к запуску Ansible
Отправляем запрос на получение списка ресурсов в облаке:
`> openstack server list -c Name -c Networks | grep router
| router1 | internet=210.0.0.1; router-lan-net=10.200.10.254 |
| router2 | internet=95.0.0.2; router-lan-net=10.200.10.253 |`
IP-адреса приводятся для наглядности в рассматриваемом сценарии, и в реальном окружении они будут отличаться.
На следующем шаге нам потребуется установить подключение — последовательно, к каждому из маршрутизаторов с использованием приватного SSH-ключа администратора и публичного IP-адреса маршрутизатора. На этом шаге нам нужно собрать сведения для настройки интерфейсов, обратившись к файлу журнала /var/log/network-config.log, который был создан скриптом bash (рассматривался ранее):
wan_ip
wan_cidr
wan_gw
lan_ip
Предлагаю посмотреть на диаграмму, которая наглядно демонстрирует особенности будущей настройки и то, почему нам потребуется так много переменных для описания целевой инфраструктуры в инвентарном файле.

Можно увидеть, что у нас должно быть сформировано четыре полноценных подключения «точка — точка», при этом все они будут работать одновременно, но трафик будет передаваться только по приоритетному пути, которым мы будем управлять через BGP MED и BGP Local Preference.
Каждое из подключений будет представлять собой «обертку», где IPsec будет защищать GRE, внутри которого будет открываться BGP-соседство.
Файл инвентаря inventory.ini
Далее я предлагаю посмотреть на 2-ю и 3-ю строки конфигурационного файла inventory.ini (для удобства и наглядности я представлю содержимое в виде списка):
router1
ansible_host=210.0.0.1
wan_ip=210.0.0.1
wan_cidr=24
wan_gw=210.0.0.254
lan_ip=10.200.10.254
remote_main_isp_ip=200.0.0.1
remote_backup_isp_ip=80.0.0.2
remote_ibgp_peer=10.200.10.253
gre_main_ip=172.17.1.1
gre_backup_ip=172.17.1.5
local_pref_main=400
bgp_med_main=100
local_pref_backup=300
bgp_med_backup=200
router2
ansible_host=95.0.0.2
wan_ip=95.0.0.2
wan_cidr=24
wan_gw=95.0.0.254
lan_ip=10.200.10.253
remote_main_isp_ip=200.0.0.1
remote_backup_isp_ip=80.0.0.2
remote_ibgp_peer=10.200.10.254
gre_main_ip=172.17.2.1
gre_backup_ip=172.17.2.5
local_pref_main=200
bgp_med_main=300
local_pref_backup=100
bgp_med_backup=400
Здесь:
wan_ip — IP-адрес, назначенный на интерфейс маршрутизатора с прямым подключением к Internet.
wan_cidr — размер сетевой маски на интерфейсе маршрутизатора с прямым подключением к Internet.
wan_gw — IP-адрес шлюза по умолчанию.
lan_ip — IP-адрес, назначенный на интерфейс маршрутизатора с подключением к локальной сети.
remote_main_isp_ip — IP-адрес основного оператора связи, подключенный к маршрутизатору в On-Premise (удаленной ИТ-инфраструктуре).
remote_backup_isp_ip — IP-адрес резервного оператора связи, подключенный к маршрутизатору в On-Premise (удаленной ИТ-инфраструктуре).
remote_ibgp_peer — локальный ID для настройки BGP-соседства.
gre_main_ip — локальный приватный пиринговый IP-адрес в Point-to-Point сети, который будет использован для создания GRE-туннеля через основного оператора связи на стороне (удаленной ИТ-инфраструктуры). Далее — основной GRE-туннель.
gre_backup_ip — локальный приватный пиринговый IP-адрес в Point-to-Point сети, который будет использован для создания GRE-туннеля через резервного оператора связи на стороне On-Premise (удаленной ИТ-инфраструктуры). Далее — резервный GRE-туннель.
local_pref_main — локальный приоритет (стоимость) BGP-маршрута для приоритизации адресных префиксов, взаимодействующих с основным GRE-туннелем.
bgp_med_main — анонсируемый приоритет (стоимость) BGP-маршрута для приоритизации адресных префиксов, взаимодействующих с основным GRE-туннелем.
local_pref_backup — локальный приоритет (стоимость) BGP маршрута для приоритизации адресных префиксов, взаимодействующих с резервным GRE-туннелем.
bgp_med_backup — анонсируемый приоритет (стоимость) BGP маршрута для приоритизации адресных префиксов, взаимодействующих с резервным GRE-туннелем.
Подробнее о том, как работают BGP Local Preference и BGP MED
Теперь мы можем углубиться по слоям в настройку IP-связности между облаком и On-Premise инфраструктурами, и это важно сделать для лучшего понимания происходящего, прежде чем будет запущена коллекция ролей Ansible.
Пара слов про strongSwan и роль IPsec в этом проекте
Как я уже отмечал ранее, технологии VPN, рассматриваемые в этом проекте или же практическом руководстве (называйте, как вам удобнее), включают в себя построение туннелей для организации IP-связности между облачной и локальной (On-Premise) ИТ-инфраструктурами.
Главным связующим звеном в этом случае выступает статическая конфигурация GRE-туннелей, которые строится по публичным IP-адресам через незащищенную среду передачи данных, имя которой Internet.
Для того чтобы защититься от перехвата чувствительной информации (здесь нам следует вспомнить, что GRE-туннель сам по себе не дает защиты передаваемых данных), в связи с чем нам следует использовать наложенное средство информационной безопасности, которым в рассматриваемом проекте выступает IPsec в транспортном режиме работы для избирательной защиты GRE-трафика.
GRE-туннели под микроскопом

Для демонстрационных целей я выбрал следующую IP-адресацию (диаграмма выше показывает IP-адреса, назначаемые на интерфейсы через запись вида .1.1, что следует читать как последние два октета IP-адреса):
192.168.1.0/24 — адресный префикс в локальной (On-Premise) ИТ-инфраструктуры;
172.17.1.0/30 и 172.17.1.4/30 — адресные префиксы для настройки GRE-туннелей между маршрутизатором On-Premise инфраструктуры и основным маршрутизатором в облаке;
172.17.2.0/30 и 172.17.2.4/30 — адресные префиксы для настройки GRE-туннелей между маршрутизатором On-Premise инфраструктуры и резервным маршрутизатором в облаке;
10.200.0.0./24 — адресный префикс для размещения нагрузок в облаке.
BGP-соседство под микроскопом
Мы разобрались с особенностями настройки GRE-туннелей, и теперь можно перейти к «вишенке на торте» — к настройке BGP-соседства, который превратит эту сложную конфигурацию с четырьмя одновременными подключениями в высокодоступное решение для настройки IP-связности между On-Premise и облаком.
Предлагаю вашему вниманию диаграмму, которая отображает распространение атрибутов BGP MED между соседями. Все эти анонсы нужны для того, чтобы защититься от асимметричной маршрутизации и реализовать следующую логику переключений между основным и резервным маршрутизаторами в облаке.

Для основного маршрутизатора облака (в порядке убывания приоритета):
Маршрут в On-Premise через GRE1-туннель и интернет-канал основного оператора связи.
Маршрут в On-Premise через GRE2-туннель и интернет-канал резервного оператора связи.
В случае если основной маршрутизатор в облаке будет переведен в режим обслуживания или по иным причинам временно не будет работать, нагрузка будет передана на резервный маршрутизатор в облаке (в порядке убывания приоритета).
Маршрут в On-Premise через GRE3-туннель и интернет-канал основного оператора связи.
Маршрут в On-Premise через GRE4-туннель и интернет-канал резервного оператора связи.
Я постарался описать все особенности, и теперь мы готовы к запуску коллекции Ansible для настройки маршрутизаторов.
Запускаем Ansible
Я рекомендую руководствоваться правилом «семь раз отмерь» в контексте подготовки файла инвентаря, проконтролировать, что все значения на своих местах, после чего запустить Playbook.
ansible-playbook -i inventory.ini site.yml
Последовательность выполняемых операций выверена, сценарий несколько раз прошел отладку через серию «холодных стартов», что позволяет мне говорить о том, что он отработает без ошибок.
Отличная платформа на будущее
Одним из выдающихся преимуществ предложенной архитектуры IP-связности с использованием GRE-туннелей и BGP для управления динамической маршрутизацией является то, что ее легко адаптировать к росту инфраструктуры.
Несмотря на высокий уровень доступности и надежности предложенного решения, оно может стать узким местом, если между On-Premise и облаком придется передавать значительные объемы данных, требующих высоких скоростей и (или) большого количества пакетов (много PPS). Другими словами, нам будет довольно тяжело добиться скоростей, превосходящих 1 Gbps, при организации IP-связности через обычный интернет.
Решение есть!
Стоит вспомнить про технологию Cloud Direct Connect или ее аналог, которые могут быть использованы в другом облаке. За счет этой технологии мы получаем возможность объединить On-Premise и облако с использованием гарантированного выделенного канала связи (чаще всего оптического), который может обеспечить канальную скорость передачи данных на уровне 10 Gbps и более.
Представим, что у нас появился такой выделенный канал связи, а лучше два, которые проложены разными кабельными канализациями. Здесь стоит вспомнить множество историй про «злой экскаватор», ежегодную реновацию бордюрной или тротуарной плитки и не только.
Количество и конфигурация оборудования на стороне On-Premise с появлением выделенных каналов связи, скорее всего, трансформируется в пользу двух независимых маршрутизаторов, что логично и правильно. Но чтобы лучше встроиться в историю, которую я только что рассказал, я продолжу ориентироваться на одно устройство в On-Premise.
Выделенные каналы встраиваются в нашу инфраструктуру следующим образом:
к основному маршрутизатору (router1) подключается выделенные каналы связи;
маршрутизатор получает дополнительные виртуальные сетевые интерфейсы;
выполняется настройка новых интерфейсов через netplan;
в конфигурационных файлах FRR объявляется новые BGP-соседи с повышенными приоритетами через выделенные каналы связи.
Аналогичным образом выполняется адаптация резервного маршрутизатора (router2).
В результате изменений IP-связность будет обновлена с учетом приоритетов и дополнена следующим образом:
Для основного маршрутизатора облака (в порядке убывания приоритета)
Маршрут в On-Premise через выделенный канал связи (основной).
Маршрут в On-Premise через выделенный канал связи (резерв).
Маршрут в On-Premise через GRE-туннель и интернет-канал основного оператора связи.
Маршрут в On-Premise через GRE-туннель и интернет-канал резервного оператора связи.
Для резервного маршрутизатора облака (в порядке убывания приоритета)
Маршрут в On-Premise через выделенный канал связи (основной).
Маршрут в On-Premise через выделенный канал связи (резерв).
Маршрут в On-Premise через GRE-туннель и интернет-канал основного оператора связи.
Маршрут в On-Premise через GRE-туннель и интернет-канал резервного оператора связи.
Настройка On-Premise
Для отладки сценария на стороне On-Premise я использовал оборудование MikroTik с RouterOS версии 7.20. В процессе настройки использовался стандартный штатный функционал без использования скриптов.
/interface gre
add comment=GRE_to_VK_Main_via_MAIN dont-fragment=inherit !keepalive \
local-address=200.0.0.1 mtu=1360 name=vk_gre1 remote-address=\
210.0.0.1
add comment=GRE_to_VK_Main_via_BACKUP dont-fragment=inherit !keepalive \
local-address=80.0.0.2 mtu=1360 name=vk_gre2 remote-address=\
210.0.0.1
add comment=GRE_to_VK_Backup_via_MAIN dont-fragment=inherit !keepalive \
local-address=200.0.0.1 mtu=1360 name=vk_gre3 remote-address=\
95.0.0.2
add comment=GRE_to_VK_Backup_via_BACKUP dont-fragment=inherit !keepalive \
local-address=80.0.0.2 mtu=1360 name=vk_gre4 remote-address=\
95.0.0.2
# VK_Cloud_Part_GRE_IPv4_Addresses
/ip address
add address=172.17.1.2/30 comment=GRE_to_VK_Main_via_MAIN interface=\
vk_gre1
add address=172.17.1.6/30 comment=GRE_to_VK_Main_via_BACKUP interface=\
vk_gre2
add address=172.17.2.2/30 comment=GRE_to_VK_Backup_via_MAIN interface=\
vk_gre3
add address=172.17.2.6/30 comment=GRE_to_VK_Backup_via_BACKUP interface=\
vk_gre4
# VK_Cloud_Part_IPsec_Profile
/ip ipsec profile
add dh-group=modp2048 dpd-interval=30s dpd-maximum-failures=1 enc-algorithm=\
aes-256 hash-algorithm=sha256 lifetime=14400 name=vk_profile
# VK_Cloud_Part_IPsec_Proposal
/ip ipsec proposal
add auth-algorithms=sha256 enc-algorithms=aes-256-cbc lifetime=7200 name=\
vk_proposal pfs-group=modp2048
# VK_Cloud_Part_IPsec_Peer
/ip ipsec peer
add address=210.0.0.1/32 comment=vk_main_via_main exchange-mode=ike2 \
local-address=200.0.0.1 name=vk_main_via_main profile=\
vk_profile
add address=210.0.0.1/32 comment=vk_main_via_backup exchange-mode=ike2 \
local-address=80.0.0.2 name=vk_main_via_backup profile=\
vk_profile
add address=95.0.0.2/32 comment=vk_backup_via_main exchange-mode=ike2 \
local-address=200.0.0.1 name=vk_backup_via_main profile=\
vk_profile
add address=95.0.0.2/32 comment=vk_backup_via_backup exchange-mode=ike2 \
local-address=80.0.0.2 name=vk_backup_via_backup profile=\
vk_profile
# VK_Cloud_Part_IPsec_Identity
/ip ipsec identity
add peer=vk_main_via_main secret=YourSecurePreSharedKey123!
add peer=vk_main_via_backup secret=YourSecurePreSharedKey123!
add peer=vk_backup_via_main secret=YourSecurePreSharedKey123!
add peer=vk_backup_via_backup secret=YourSecurePreSharedKey123!
# VK_Cloud_Part_IPsec_Policy
/ip ipsec policy
add comment=GRE_VK_main_via_main dst-address=210.0.0.1/32 peer=vk_main_via_main \
proposal=vk_proposal protocol=gre src-address=200.0.0.1/32
add comment=GRE_VK_main_via_backup dst-address=210.0.0.1/32 peer=vk_main_via_backup \
proposal=vk_proposal protocol=gre src-address=80.0.0.2/32
add comment=GRE_VK_backup_via_main dst-address=95.0.0.2/32 peer=vk_backup_via_main \
proposal=vk_proposal protocol=gre src-address=200.0.0.1/32
add comment=GRE_VK_nackup_via_backup dst-address=95.0.0.2/32 peer=vk_backup_via_backup \
proposal=vk_proposal protocol=gre src-address=80.0.0.2/32
# VK_Cloud_Part_BGP_Local_Prefixes_OUT
/ip firewall address-list
add address=192.168.1.0/24 list=bgp_out_net_peer
# VK_Cloud_Part_BGP_Routing_Filter
/routing filter rule
add chain=vk_med_main_via_main disabled=no rule="set bgp-out-med 400; accept"
add chain=vk_med_main_via_backup disabled=no rule="set bgp-out-med 300; accept"
add chain=vk_med_backup_via_main disabled=no rule="set bgp-out-med 200; accept"
add chain=vk_med_backup_via_backup disabled=no rule="set bgp-out-med 100; accept"
# VK_Cloud_Part_BGP_Connection
/routing bgp connection
add address-families=ip as=65011 disabled=no hold-time=30s keepalive-time=10s \
local.role=ebgp name=vk_peer_main_via_main output.filter-chain=vk_med_main_via_main \
.network=bgp_out_net_peer remote.address=172.17.1.2/32 .as=65021 \
routing-table=main use-bfd=no
add address-families=ip as=65011 disabled=no hold-time=30s keepalive-time=10s \
local.role=ebgp name=vk_peer_main_via_backup output.filter-chain=vk_med_main_via_backup \
.network=bgp_out_net_peer remote.address=172.17.1.6/32 .as=65021 \
routing-table=main use-bfd=no
add address-families=ip as=65011 disabled=no hold-time=30s keepalive-time=10s \
local.role=ebgp name=vk_peer_backup_via_main output.filter-chain=vk_med_backup_via_main \
.network=bgp_out_net_peer remote.address=172.17.2.2/32 .as=65021 \
routing-table=main use-bfd=no
add address-families=ip as=65011 disabled=no hold-time=30s keepalive-time=10s \
local.role=ebgp name=vk_peer_backup_via_backup output.filter-chain=vk_med_backup_via_backup \
.network=bgp_out_net_peer remote.address=172.17.2.6/32 .as=65021 \
routing-table=main use-bfd=no```
## Заключение
Разработанная архитектура доказала свою эффективность, предоставляя отказоустойчивое, безопасное и масштабируемое гибридное соединение. Ключевая особенность этого подхода — его гибкость. Использование открытых стандартов и технологий (GRE, IPsec, BGP) позволяет адаптировать решение не только для VK Cloud, но и для других платформ.
Этот фундамент отлично подходит для будущего роста. При появлении требований к большей пропускной способности и стабильности «костяк» из BGP-маршрутизации бесшовно интегрируется с выделенными каналами связи, такими как Cloud Direct Connect, создавая промышленное гибридное решение.