Прокидываем #cloud-config через Vendor Data в OpenStack

На кого ориентирована статья

Проект полезен для сервис-провайдеров или операторов небольших приватных облаков, которые до этого строили костыли с bash скриптами и массой не самых очевидных решений.

Идея

Какой самый живучий паразит?  Бактерия?  Вирус? Кишечный глист? Идея. Она живуча и крайне заразна. Стоит идее завладеть мозгом, избавиться от неё уже практически невозможно. Я имею в виду сформировавшуюся идею, полностью осознанную, поселившуюся в голове.

d9b420cfdd3531bd918bfa1ae36c7452.jpg

Началось всё с подколов от друга «где SSH ключи ?» в контексте облака. Казалось бы, обычная фича для провайдера, но подходящих реализаций, чтобы не затрагивать user-data с упором на элементарность внедрения на горизонте не было.

Взгляд упал на часть элемента OpenStack под названием Vendor Data (а если быть точнее, то Nova metadata service который покрывает ряд задач с точки зрения оператора облака), и, как окажется, не зря.

Vendor Data предоставляет простой способ предоставления дополнительной информации, специфичной для инстанса, например, это может быть информация для конфигурации пред-установленного ПО или информации о том, в каком датацентре и на базе чего развернут инстанс для применения каких-либо твиков.

Ближе к делу: наиболее удобным способом хранения конфигураций была выбрана база ключ-значение Consul KV.

Согласно документации, DynamicJSON провайдер ожидает что провайдер vendor data вернёт информацию в виде валидного JSON объекта, однако, после непродолжительного общения с разработчиками был выдвинут тезис, что экранированное кавычками содержимое, также является корректным JSON.

2d3012a0914e186f396dd73c2f0895ba.png

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

Оборачиваем всё в rest api провайдер

После получения рабочей версии было принято решение выкатить в опен-сорс базовую реализацию проекта с провайдером Vendor Data, так как у опен сорс проекта больше шансов на развитие силами комьюнити.

О провайдере:

  1. Основан на базе FastAPI с заделом для будущих фич;

  2. По пути /ocdv смонтировано Flask-based приложение, работающее непосредственно с Consul KV;

  3. Для Flask аппы подключен keystonemiddleware — это официальная мидлварь для WSGI-based приложений для авторизации входящих запросов (кратко: проверяется заголовок X-Auth-Token);

  4. По пути /ocdv/cloud-init приложение ожидает POST запрос с данными, среди которых, есть и ID инстанса.

  5. Проверяет наличие ключа в Consul KV по пути cloud/instances/${instance_id}/cloud-config . Если таковой ключ есть, то возвращается сериализованная строка с экранированными символами (фактически используется стандартный пакетjson), чтобы подходить под понимание валидного JSON (да-да, в одну строку) и возвращает ответ;

  6. DynamicJSON парсит ответ (под капотом тот же пакет json) и также возвращает ответ дальше по цепочке для сбора результатов от всех провайдеров.

Важно: чтобы в Vendor Data вернувшийся от провайдера #cloud-config был именно в ключе cloud-init, в котором cloud-init и ожидает увидеть конфигурацию, необходимо настроить nova-api следующим образом:

[api]
vendordata_providers=DynamicJSON
vendordata_dynamic_targets=cloud-init@10.10.10.10:8000/ocdv/cloud-init

Проверяем внутри инстанса

Статья предполагает, что у Вас уже имеется готовый к работе кластер Consul. Предположим UUID инстанса 00000000-1337-1337-1337-000000000000. По пути cloud/instances/00000000-1337-1337-1337-000000000000/cloud-config поместите следующий контент:

#cloud-config
hostname: ocdvworks

Смотрим Vendor Data:

curl http://169.254.169.254/openstack/latest/vendor_data2.json | jq
{
    "cloud-init": "#cloud-config\nhostname: ocdvworks"
}

Что с этим делать дальше?

Перед стартом инстанса необходимо сформировать #cloud-config и поместить по вышеуказанному пути в Consul KV. При старте инстанса cloud-init проверит наличие данных в vendor_data2.json и затем обработает конфигурацию. Важный момент: если пользователь указал user-data конфигурацию при создании инстанса, то пользовательская конфигурация имеет приоритет перед провайдерской.

Заключение

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

Проект полностью под MIT лицензией, свободный для любого использования.
https://github.com/ib-systems/openstack-consul-dynamic-vendordata

Я буду признателен идеям для улучшения и вкладу в исходный код, так как текущая реализация сформирована «на досуге» в свободное от всей рутины время и требует полировки.

Habrahabr.ru прочитано 5554 раза