
Привет, Хабр! На связи Кирилл Савин, я — архитектор SDN в Рег.облаке. Мы уже подробно разбирали, как устроен OVN в связке с OpenStack, — в статье «OVN под капотом: как построить сеть в OpenStack». А затем показали, как трассировать пакеты в OVN и анализировать поведение трафика.
В этом материале продолжаем тему интеграции OVN с OpenStack и разбираем более узкий, но важный сценарий — работу Metadata API при использовании OVN в качестве backend для Neutron. Это перевод оригинального design-документа, в котором мы сохранили структуру и инженерную логику автора. Речь пойдет уже не столько о маршрутизации пакетов, сколько о служебной логике поверх сетевой плоскости и особенностях ее реализации в модели OVN.
Навигация по тексту:
Введение
OpenStack Nova — сервис, отвечающий за управление жизненным циклом виртуальных машин, — предоставляет инстансам доступ к Metadata API. Это механизм, через который VM получает служебные данные о себе: идентификатор, параметры конфигурации, ключи SSH и user-data. По своей идее он аналогичен тому, как это реализовано в Amazon EC2.
В обработке запросов участвует OpenStack Neutron — сетевой сервис платформы. Одного IP-адреса источника недостаточно, чтобы однозначно определить, откуда пришел запрос к Metadata API: в разных сетях могут использоваться пересекающиеся диапазоны адресов. Поэтому Neutron перехватывает такие запросы и добавляет HTTP-заголовки, позволяющие уникально идентифицировать источник, после чего пересылает их на сервер Metadata API.
Цель этого материала — описать архитектурный подход к реализации этой функциональности при использовании OVN (Open Virtual Network) в качестве backend для OpenStack Neutron.
Neutron и Metadata: текущая реализация
В этом блоге можно подробнее узнать, как виртуальные машины сегодня получают доступ к Metadata API через Neutron. А ниже — краткое описание процесс��.
Metadata proxy запускается либо в namespace маршрутизатора (router namespace), либо в namespace DHCP. Namespace DHCP используется, если к сети не подключен маршрутизатор. Ограничение такого подхода в том, что через DHCP в виртуальную машину необходимо передать статический маршрут, чтобы она знала, что запросы к metadata нужно направлять на IP-адрес DHCP-сервера.
Процесс выглядит так:
Инстанс отправляет HTTP-запрос к Metadata API по адресу 169.254.169.254.
В зависимости от маршрута запрос попадает либо в router namespace, либо в DHCP namespace.
Сервис metadata proxy в namespace добавляет в запрос:
IP-адрес инстанса (заголовок
X-Forwarded-For);ID маршрутизатора или сети (
X-Neutron-Network-Id илиX-Neutron-Router-Id).Metadata proxy отправляет запрос агенту metadata (за пределами namespace) через UNIX domain socket.
Сервис
neutron-metadata-agentдобавляет новые заголовки (Instance ID и Tenant ID) и пересылает запрос в Nova Metadata API [0].
Для корректной работы Neutron и Nova должны быть настроены на взаимодействие с использованием общего секрета. Neutron подписывает заголовок Instance-ID этим секретом, чтобы предотвратить подмену. Параметр
metadata_proxy_shared_secretдолжен быть указан в конфигурационных файлах nova и neutron (опционально).
Neutron и Metadata при использовании OVN
Текущий подход к Metadata API нельзя напрямую перенести на OVN. При использовании OVN Neutron-агенты не применяются. Кроме того, OVN не использует собственные network namespaces так же, как это сделано в исходной реализации (router и dhcp namespaces).
Необходимо использо��ать модифицированный подход, соответствующий модели OVN. Ниже вы найдете предлагаемый вариант.
Обзор предлагаемого решения
Предлагаемый подход близок к сценарию изолированной сети в текущей реализации ML2+OVS. Предполагается запуск экземпляра metadata proxy (haproxy) на каждом гипервизоре — для каждой сети, к которой подключена VM на данном хосте.
Из минусов — число metadata proxy увеличится (по сравнению со сценарием с маршрутизируемыми сетями, где используется один proxy на виртуальный маршрутизатор). Однако haproxy — легкий сервис, и большую часть времени он будет простаивать. Существенное преимущество — отсутствие необходимости реализовывать логику распределения proxy по узлам и механизмы высокой доступности. При необходимости архитектуру можно развить. Как это сделать — ниже.
Подход опирается на новую функциональность в OVN: логический порт типа localport, который должен присутствовать на каждом chassis (по аналогии с localnet-портами). Для таких портов пакеты не передаются через туннели — они доставляются только локальному экземпляру.
Шаг 1. Создание порта для metadata proxy
Сейчас при использовании DHCP-агента Neutron автоматически создаёт порт для DHCP. Аналогичный механизм можно применить для metadata proxy (haproxy). Будет создан OVN localport, присутствующий на каждом chassis, с одинаковыми MAC- и IP-адресами на всех хостах. В перспективе можно использовать один и тот же neutron-порт для DHCP и metadata.
Шаг 2. Маршрутизация запросов к Metadata API
OVN настраивается так, чтобы через DHCP возвращался статический маршрут, направляющий запросы к Metadata API на localport, где размещён metadata proxy. Если DHCP отключен или клиент игнорирует маршрут, статический маршрут настраивается в логическом маршрутизаторе OVN. Если DHCP-маршрут не срабатывает в изолированной сети, VM не получит metadata — это соответствует текущему поведению и не является регрессией.
Шаг 3. Управление namespace и экземплярами haproxy
Предлагается новый агент — neutron-ovn-metadata-agent. Он запускается на каждом гипервизоре и отвечает за:
создание и удаление haproxy;
управление OVS-интерфейсами;
управление network namespaces;
проксирование запросов к Metadata API.
Шаг 4. Обработка запросов Metadata API
Как и существующий metadata agent, neutron-ovn-metadata-agent выступает посредником между haproxy и Nova Metadata API.
haproxy работает в отдельном network namespace и не имеет доступа к сетям хоста, где размещён Nova Metadata API. Он добавляет необходимые заголовки и передает запрос агенту через UNIX domain socket — аналогично текущей реализации.
Логика управления metadata proxy
В neutron-ovn-metadata-agent. При запуске
Выполнить полную синхронизацию.
Проверить, что запущены все необходимые metadata proxy.
Для этого агент отслеживает таблицу
Port_Bindingв OVN Southbound DB и выбирает строки, где полеchassisсоответствует текущему хосту.Для каждого datapath (сети), к которой подключены эти порты, должен быть запущен metadata proxy.
Ненужные proxy — удалить.
Агент поддерживает соединение с OVN Northbound DB (через ovsdbapp). При первом подключении и при переподключении выполняется полная синхронизация. Регистрируется callback на операции create/update/delete строк Logical_Switch_Port. Когда порт привязывается к chassis, агент проверяет наличие metadata proxy для соответствующей сети.
Создание сети
При создании сети:
создается OVN localport для metadata proxy;
порт принадлежит
network:dhcp, поэтому удаляется автоматически вместе с сетью;порт создается независимо от настроек DHCP в подсетях, если включён metadata service.
Удаление сети
При удалении сети:
metadata proxy (если есть) останавливается;
OVN localport удаляется автоматически.
Запуск metadata proxy включает:
Создание network namespace
sudo ip netns add <ns-name>
Создание VETH-пары
sudo ip link add <iface-name>0 type veth peer name <iface-name>1
Добавление OVS-интерфейса и перенос одного конца в namespace
sudo ovs-vsctl add-port br-int <iface-name>0 sudo ip link set <iface-name>1 netns <ns-name>
Настройка MAC и IP
sudo ip netns exec <ns-name> ip link set <iface-name>1 address <neutron-port-mac> sudo ip netns exec <ns-name> ip addr add <neutron-port-ip>/<netmask> dev <iface-name>1
Подъем интерфейсов
sudo ip netns exec <ns-name> ip link set <iface-name>1 up sudo ip link set <iface-name>0 up
Установка external-id
sudo ovs-vsctl set Interface <iface-name>0 external_ids:iface-id=<neutron-port-uuid>
И запуск haproxy в namespace.
Остановка metadata proxy включает:
удаление UUID сети с chassis;
остановку haproxy;
удаление OVS-интерфейса;
удаление namespace.
Дополнительные соображения
Функциональность включается по умолчанию при использовании ovn driver. Должна быть возможность отключить ее, если metadata не требуется. Существует потенциальная гонка при запуске первой VM в сети на гипервизоре, если metadata proxy ещё не создан. Повторные попытки cloud-init должны в итоге получить metadata.
Альтернативы
Альтернатива 1
Реализация metadata внутри ovn-controller
Подход отклонен, поскольку:
Metadata API — OpenStack-специфичная функция;
потребовалось бы встроить HTTP и TCP стек в ovn-controller;
это усложняет архитектуру.
Альтернатива 2
Распределенный metadata и High Availability
Предлагается запуск proxy на виртуальный маршрутизатор или на сеть. Для этого требуется:
планирование (scheduling);
поддержка HA;
логика перепланирования при падении хоста;
интеграция с L3 HA.
В neutron-server (ovn mechanism driver) предлагается опция:
[ovn]
isolated_metadata = True # или False
Описана логика планирования и перепланирования proxy через таблицы Chassis и Logical_Switch_Port с использованием external_ids.
Подход признан слишком сложным на текущем этапе, хотя архитектурно возможен и может быть реализован в будущем.
Планирование metadata proxy
В варианте с распределенным размещением metadata proxy требуется явная логика планирования и перепланирования.
Выбор хостов для размещения
neutron-ovn-metadata-agent может запускаться на тех узлах, которые способны обслуживать metadata proxy. Такие узлы должны одновременно запускать ovn-controller.
Каждый такой хост имеет запись Chassis в OVN Southbound database. В таблице Chassis используется поле external_ids, куда агент может записывать дополнительную информацию.
Для обозначения хостов, способных размещать metadata proxy, в external_ids соответствующей записи Chassis устанавливается флаг:
external_ids:neutron-metadata-proxy-host=true
Логика выбора chassis
При создании metadata proxy механизм драйвера OVN (в neutron-server) должен:
Получить список
Chassisиз OVN Southbound database.Отфильтровать узлы, у которых установлен
neutron-metadata-proxy-host=true.Выбрать наименее загруженный узел (например, с минимальным числом уже размещенных metadata proxy).
Назначить выбранный хост, записав в
Logical_Switch_Port(в OVN Northbound database) соответствующийexternal_id:
external_ids:neutron-metadata-proxy-chassis=CHASSIS_HOSTNAME
CHASSIS_HOSTNAME соответствует значению hostname в записи Chassis Southbound database.
Реакция агента на планирование
neutron-ovn-metadata-agent, запущенный на каждом хосте, отслеживает изменения в Logical_Switch_Port. Когда агент обнаруживает, что metadata proxy назначен его chassis, он:
создает namespace;
поднимает VETH-пару;
подключает интерфейс к OVS;
запускает haproxy;
регистрирует интерфейс через external_ids.
Перепланирование и отказоустойчивость
Также необходимо учитывать сценарий отказа хоста. При недоступности chassis:
metadata proxy, назначенные этому узлу, должны быть перепланированы;
требуется механизм обнаружения отказа (аналогично L3 HA);
после обнаружения отказа выполняется повторный запуск процедуры планирования;
соответствующие записи
external_idsобновляются на новыйCHASSIS_HOSTNAME.
По своей природе этот механизм близок к перепланированию L3 gateway при отказе узла, поэтому желательно использовать схожую модель обработки событий.
Такой подход обеспечивает распределенное размещение metadata proxy и возможность масштабирования, но добавляет дополнительную сложность в виде логики scheduling и HA. По этой причине на текущем этапе он признан избыточным по сравнению с базовой моделью localport, хотя архитектурно остается возможным направлением развития.
