Привет, Хабр!
Меня зовут Евгений, и с недавних пор я являюсь членом команды развития инфраструктуры в Домклике. Больше всего опыта у меня в области сетевых технологий, в простонародье я «сетевик». На сегодняшний день наша команда, да и не только наша, активно прорабатывает возможность использования облачной инфраструктуры для создания резервного центра обработки данных (РЦОД). А раз я много лет занимаюсь сетями, то вполне логично, что мне стало интересно решить одну задачку, о которой я хочу вам поведать.
Лирическое отступление
Многие вопросы, такие как создание ресурсов типа VPC (Virtual Private Cloud), Network Subnet, ECS (Elastic Cloud Server), настройка сети в ОЦОД и так далее, выходят за рамки статьи. Также, по понятным причинам, все подсети изменены.
Задача
Есть у нас основная площадка в центре обработки данных (ОЦОД), и мы хотим наладить сетевое взаимодействие между ОЦОД и РЦОД. Одной из ключевых задач является проверка на отказоустойчивость и время недоступности при нештатных ситуациях. Мерилом тестирования будет длительность потери связи до вычислительных ресурсов в РЦОД. Мы выбрали облачного провайдера, на базе которого подняли dev-инфраструктуру, и пришла пора реализовывать сетевую связность.
Решение
Так как мы большой Enterprise, для нас очень важно добиться минимально допустимого простоя при нештатных ситуациях. Для решения этой задачи, в первую очередь, используя разные телекоммуникационные трассы, мы подключили две волоконно-оптические линии связи (ВОЛС) между ОЦОД и РЦОД. Такая коммутация даёт нам отказоустойчивость на уровне физических линий.
По ряду причин не было возможности объединить эти ВОЛС в агрегированный канал, потому линии независимы.
Потратив немного времени, я нарисовал схему взаимодействия, в которой для маршрутизации между площадками использован встроенный в облако протокол BGP:
Согласно схеме, между ОЦОД и РЦОД будет настроено две P2P (peer-to-peer) подсети 192.168.255.0/30 и 192.168.255.4/30, где адреса 192.168.255.2 и 192.168.255.6 будут на стороне облачной инфраструктуры, а 192.168.255.1 и 192.168.255.5 на стороне маршрутизаторов ОЦОД. Между членами P2P-подсетей будет настроена BGP-сессия, в которой каждая сторона будет анонсировать свои префиксы. Из инфраструктуры ОЦОД будем анонсировать префикс 192.168.0.0/17, а из инфраструктуры РЦОД — 10.50.0.0/16.
Приступаем к реализации
К сожалению, большую часть работы нельзя выполнить с помощью подхода IaC и решения Terraform, а потому я буду опираться только на web-интерфейс управления своей инфраструктурой в облаке.
Кстати, кусок выделенных вам вычислительных ресурсов в облачной платформе называется Tenant.
Первым этапом было создание в облаке Connections, иными словами наши ВОЛС. Это сделали специалисты облачного провайдера. Теперь необходимо создать Virtual Gateway, он выступает в роли инструмента разделения нашей инфраструктуры в облаке и налаживания взаимодействиями с внешними интеграциями. Ниже представлен пример настройки:
Краткое пояснение полей:
Name — понятное название.
VPC — привязка к существующему VPC.
Subnet CIDR Block — подсеть, описанная в п.2.
Description — указываем, что хотим.
VPC или Virtual Private Cloud — это «облако в облаке», изолированный сегмент всего облака, в котором вычислительные ресурсы выделены только вам.
Здесь есть два очень важных момента, о которых стоит упомянуть:
Subnet CIDR Block — это поле описывает подсети, о которых должны узнать и с которыми могут работать за пределами VPC. В нашем случае тут описывается анонсируемый нами в BGP-префикс. Без правильной настройки Virtual Gateway маршрутизации не будет.
VPC — можно выбрать только при создании и оно никак потом не редактируется. Также стоит учитывать, что у одного VPC может быть только один Virtual Gateway.
Теперь надо создать и настроить Virtual Interface. Пример:
Пройдемся по полям:
Region — выбирается регион, "ru-moscow".
Name — понятное название.
Connection — выбирается в Direct Connect.
Virtual Gateway — выбирается ранее созданный.
Local Gateway — указываем адрес облака в P2P-подсети.
Remote Gateway — адрес маршрутизатора в ОЦОД.
Remote Subnet — указываем подсеть, которую нам будет анонсировать маршрутизатор в ОЦОД.
Routing Mode — способ получения маршрута.
BGP ASN — указываем номер автономной системы маршрутизатора ОЦОД, иными словами "peer AS".
BGP MD5 Authentication Key — симметричный ключ шифрования BGP-сессии.
Description — указываем, что хотим.
Почти все параметры, кроме Name, Remote Subnet и Description в Virtual Interface можно задать только в момент создания, после их изменить будет нельзя.
Подробнее расскажу про особенности полей "Remote Subnet" и "BGP ASN". Начну с последнего:
В текущей реализации мы не можем выбирать номер локальной автономной системы или как-то его менять, система сама выбирает первый свободный из пула приватных номеров, с 64512 по 65534. Иными словами, если это первая BGP сессия в вашей инфраструктуре, то номер локальной AS будет 64512, следующая получит номер 64513 и т.д. Подробнее про приватный пул AS можно прочесть в RFC6996.
Remote Subnet — указанная подсеть автоматически прописывается в дефолтной (default) таблице маршрутизации, которая привязана к используемому нами VPC. Со стороны пользователя это выглядит как статичный маршрут, у которого next-hop созданный нами Virtual Gateway. Даже если BGP-сессия упала и мы не получаем анонс, маршрут остаётся на месте.
Последним этапом будет создание правила, которое разрешит прохождение трафика в РЦОД из ОЦОД. Для регулирования сетевого взаимодействия между вычислительными ресурсами есть гибкий механизм — Security Group.
Security Group — это группа с набором правил входящего/исходящего трафика для ресурсов, которые в неё входят.
В примере выше мы разрешаем весь входящий трафик по всем портам из подсети 192.168.0.0/17. Это правило добавляем в Inbound Rules. Исходящее правило у нас будет базовым, то есть 0.0.0.0/0. Тогда вычислительный ресурс в такой Security Group может обращаться на любой IP-адрес, а пакеты примет от источника в подсети 192.168.0.0/17 и от членов той же группы.
Настало время всё это проверить, приступим...
Тестирование решения
С точки зрения сети у нас всё готово, BGP-сессии подняты, пинги между нами и виртуальными машинами исправно бегают, так что пора перейти к тестам на отказоустойчивость. Для этого напишем маленький скрипт, который будет в цикле «курлить» наши Nginx в РЦОД:
#!/bin/bash
x=1
while [ true ]
do
echo "Запрос в SCA № $x ↓"
curl -I -s http://nginx.testdomain.ru | egrep HTTP\|date
sleep 1
x=$(( $x + 1 ))
Возможно, кому-то будет полезно маленькое разъяснение, как это работает:
while
— это тип цикла, который будет повторяться, пока условие в скобках истинно.true
в нашем случае означает вечный цикл.echo
— выводимая надпись, где$x
увеличивается на 1 при каждом проходе цикла благодаря условиюx=$(( $x + 1 ))
.curl
— сам запрос, мы получим код ответа и время сервера (egrep
выводит строчки с точным совпадением).sleep
— устанавливает таймер ожидания перед продолжением, 1 сек.
Методика испытаний была предельно простой:
Что делаем | Результат |
Запускаем скрипт в подсети ОЦОД. | Получаем код 200. |
Разрываем одно соединение между площадками. | Одна BGP-сессия упала. |
Включаем разорванное соединение. | Все BGP-сессии работают. |
Разрываем второе соединение между площадками. | Вторая BGP-сессия упала. |
Давайте кратко разберём каждый шаг:
Запустив скрипт, мы начинаем получать примерно такой вывод:
В ОЦОД мы разорвали одно соединение и пакеты стали теряться, а скрипт перестал получать какой-либо ответ, потому что с точки зрения облака их стало некуда отправлять. Но спустя примерно 27-28 секунд всё восстановилось, потому что стал активен маршрут, полученный через вторую BGP-сессию. Это время сходимости:
Восстановили работу первой BGP-сессии и не заметили какого-то влияния.
В ОЦОД мы разорвали второе соединение и получили примерно такую же картину, что и на шаге 2, с теми же 27-28 секундами потерь.
По итогам тестирования могу сказать, что 30 секунд простоя вполне приемлемый для нас результат. К сожалению, у облачного провайдера не реализован механизм балансировки ECMP, но и такой результат вполне удовлетворителен для наших задач.
Вывод
Схема рабочая и вполне жизнеспособная, но есть и существенные недостатки реализации BGP на базе облачной платформы, которые мне хотелось бы отметить:
Невозможно влиять на некоторые параметры настроек после их создания, а на некоторые — даже во время создания.
Невозможно посмотреть, какой локальный AS был выбран системой, эту информацию пришлось получать из дампа трафика на стороне ОЦОД.
Нехватает инструментов диагностики состояния BGP-сессии на стороне РЦОД.
Как и в любой большой системе, есть свои плюсы и минусы. Я верю, что со временем минусов станет меньше, появятся новые фишки и инструменты, ну а пока могу сказать, что этим решением вполне можно пользоваться и работает оно достаточно стабильно. Какие-то более чёткие выводы можно будет сделать лишь после увеличения нагрузки.
Спасибо за внимание!