Перейти к основному содержимому

Библиотека образов ОС

Проблема и зачем​

Виртуальную машину поднимают из готового образа ОС за секунды, а с установочного носителя — за десятки минут. Но диск новой машины создаётся клоном ZFS, а клон живёт на том же пуле, что и его родитель. Значит, образ должен уже лежать на пуле, где создаётся машина. Тянуть гигабайты с внешнего сервера при каждом создании ВМ бессмысленно.

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

Отсюда деление модели на две половины. Снаружи кластера — источник библиотеки: обычный веб-сервер с файлом manifest.json, который перечисляет доступные образы. Внутри кластера — каталог образов: то, что уже импортировано, с картой раздачи по пулам и состоянием каждой копии. Синхронизация читает первую половину, импорт наполняет вторую.

Третья черта модели неочевидна. Ни у регистрации источника, ни у импорта образа нет параметра «в какой ВЦОД» (виртуальный центр обработки данных). Принадлежность выводится из прав вызывающего: роль Cluster master создаёт общий кластерный объект, администратор ВЦОД — объект своего ВЦОД. Указать чужой ВЦОД нельзя.

Экранов библиотеки образов в веб-интерфейсе vStack Center нет. И источники, и каталог образов живут в API кластера, поэтому работают с ними программно — вызовами API или системой автоматизации, которая их делает. Перечень операций — в конце страницы, состав запросов и ответов — в Справочнике API.

Эта страница объясняет модель. Как привезти образ — в инструкции «Как импортировать образ ОС в кластер»; как убрать его из кластера — в инструкции «Как удалить образ ОС».

Модель и сущности​

Источник библиотеки. Внешний сервер с образами. У источника есть имя, корневой адрес библиотеки и время последней синхронизации — пустое, если синхронизации ещё не было. Адрес обязан быть http- или https-ссылкой, по умолчанию требуется https; незащищённый http открывается только явным разрешением. Адрес уникален в кластере: один и тот же корневой адрес дважды не зарегистрировать.

Манифест. Файл manifest.json в корне источника — каталог того, что источник предлагает. Манифест пишет владелец библиотеки, и каждый его элемент несёт полный паспорт образа: обязательные name, version, format, url_path, size, sha256 и опциональные description, os_type, net_link_pattern, zero_based_link, default_shell, sector_size_logical, sector_size_physical, guest_customization, uefi, min_size, uuid. Признак пригодности к импорту кластер выводит сам: пригодны только образы формата zfs.

Поле uuid формально опциональное, но именно по нему импорт находит образ в манифесте: элемент без uuid импортировать нельзя. Идентификатор глобально уникален — двух элементов с одним uuid в манифесте быть не должно.

Образ в каталоге кластера. Импортированный образ адресуется суррогатным идентификатором (UUID). Имена образов неуникальны, поэтому операции ходят по идентификатору, а не по имени. У образа есть стадия жизненного цикла и карта фактической раздачи по пулам.

Копия на паре «узел → пул». Раздача идёт пулами, и у каждой пары «узел → пул» свой исход. Отсюда состояние «разложен не везде» и зависимость обратного порядка: диски ВМ на пуле — это ZFS-клоны копии образа именно на этом пуле.

СущностьЧем адресуетсяКому принадлежит
Источник библиотекицелочисленным идентификаторомкластеру (общий) либо одному ВЦОД
Образ в каталогеидентификатором UUIDВЦОД-владельцу либо кластеру
Копия образапара «узел → пул»пулу

Как работает​

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

Что нужноРежимПривилегия
Зарегистрировать или перенастроить источниксинхронныйManage Image Library
Посмотреть доступные источникисинхронныйView Image Library
Прочитать каталог источникасинхронныйSync Image Library
Привезти образ в кластерасинхронныйImport Golden Image
Посмотреть каталог образов кластерасинхронныйView Image Catalog
Снять карту зависимостей образасинхронныйView Image Dependencies
Удалить образ из кластерасинхронныйRemove OS Image

Все привилегии действуют в области своего ВЦОД; у роли Cluster master область глобальная. Право смотреть зависимости отделено от права удалять: просмотр можно выдать широко, удаление — нет.

Синхронизация читает манифест, а не образы​

Синхронизация скачивает только manifest.json и возвращает каталог образов источника. Байты самих образов при этом не двигаются, поэтому операция дешёвая и безопасная. Заодно она обновляет время последней синхронизации источника. Образ неподходящего формата из каталога не пропадает — он приходит с признаком «непригоден к импорту», и по этому признаку видно, почему импорт его не возьмёт.

Обращение к внешнему адресу защищено от подмены цели. Проверяются схема (только http или https) и результат разрешения имени. Кластер отклоняет loopback, link-local вместе со служебным адресом метаданных, приватные диапазоны RFC 1918, разделяемое адресное пространство операторов связи (CGNAT), «нулевую сеть» и широковещательный адрес. Замаскированные IPv4-mapped-формы IPv6 сводятся к IPv4 и проверяются по тому же списку; из собственных адресов IPv6 закрыты loopback, link-local и уникальные локальные (ULA). Тело манифеста ограничено 100 МБ.

Импорт раскладывает образ по пулам​

Импорт отвечает немедленно — подтверждением приёма задания, а не готовности образа: работа продолжается в фоне. Байты двигает выделенный сервис раздачи vstack-center-image-distributor по двухфазному протоколу, диспетчер кластера только оркестрирует. Каталог образов пишет один компонент, поэтому конкурирующих записей о состоянии образа не бывает.

Прогресс и исход видны в каталоге образов кластера: у образа есть стадия и карта раздачи с записью на каждый пул.

СтадияЧто означаетЧто делать
importingобраз скачивается и раздаётсяждать
activeобраз разложен на все выбранные пулыможно создавать ВМ
partial_activeчасть пулов не получила копиюдораздать повторным импортом той же версии
failedпопытка провалилась целикомразобрать причину и запустить импорт заново

Автоповторов нет — принципиально. Любой сбой (скачивание, контрольная сумма, раздача, потеря задания сервисом) переводит образ в failed и оставляет запись в журнале. Повтор запускает администратор, повторным импортом. Такая же логика после перезапуска диспетчера: незавершённые импорты закрываются как неуспешные, а не переигрываются молча.

Частичный успех не откатывается. Пулы, которые копию получили, её сохраняют; повторный импорт той же версии довозит остальные.

Создание ВМ ждёт готовый пул​

Пока у образа есть карта раздачи, копия образа на пуле, выбранном при создании машины, обязана быть активна. Иначе создание ВМ отклоняется с кодом -259 — до того, как что-либо создано. Порядок действий поэтому обратный привычному: сначала образ на пуле, потом машина на этом пуле. Подробности создания — в инструкции «Как создать, удалить и перенести виртуальную машину».

Кто что видит и кто чем владеет​

Область видимости у образов и источников одна и та же. Cluster master видит всё. Администратор ВЦОД видит общие кластерные объекты плюс привязанные к своим ВЦОД. Субъект без ВЦОД — только общие. Адрес источника показывается лишь его владельцу, остальным он не виден.

Видимость и владение — разные права. Образ, «показанный» ВЦОД через грант видимости, администратор этого ВЦОД удалить не может: удаление требует владения. Импорт новой версии существующего образа тоже открыт только владельцу либо роли Cluster master. Несуществующий и невидимый образ отвечают одинаково — «не найден», поэтому по ответу нельзя узнать, что чужой закрытый образ существует.

Каждое изменение сначала попадает в журнал​

Регистрация источника, синхронизация, импорт и удаление пишут в журнал безопасности запись о намерении до самого действия. Запись ограничена по времени, по умолчанию двумя секундами. Если журнал не принял событие, операция не начинается и отвечает кодом -503. Ничего при этом не меняется — ни в каталоге, ни на узлах.

Успешные чтения — список источников и каталог образов — в журнал не попадают, а вот отказ доступа к любой операции с образами оставляет след auth.image_library_access_denied. Просмотр зависимостей фиксируется событием config.image_dependencies_viewed. Стадии удаления получают собственные записи: config.image_remove_initiated, config.image_removed, config.image_remove_partial, config.image_remove_failed, config.image_remove_blocked_dependencies. В каждой записи есть привязка к ВЦОД либо признак общего кластерного объекта, область доступа вызывающего и его идентификатор. Путей хранения и топологии пулов в журнале нет — только идентификаторы узлов и сводные числа.

Ограничения​

Импортируется только формат zfs. Копия образа на пуле — это ZFS-датасет, из которого клонируются диски машин, поэтому другой формат раскладывать некуда. Образ иного формата виден в каталоге источника как непригодный к импорту, а сам импорт отвечает кодом -48005. Обход: держать в манифесте zfs-вариант образа.

Незащищённый http закрыт по умолчанию. Библиотека отдаёт данные, из которых собираются все машины кластера, поэтому канал должен быть проверяемым. Без явного разрешения адрес на http отклоняется кодом -46011. Обход: опубликовать источник по https; разрешение оставить для изолированного стенда.

Внутренние адреса запрещены. Хост источника, который разрешается в loopback, link-local, служебный адрес метаданных, приватный диапазон RFC 1918, CGNAT, «нулевую сеть» или широковещательный адрес, отклоняется кодом -46012. Ограничение снять нельзя: оно закрывает обращение кластера к самому себе по чужой указке. Библиотека внутренней сети под это ограничение попадает целиком. Обход: вынести библиотеку на адрес вне перечисленных диапазонов.

Источник нельзя удалить. В кластере есть регистрация, чтение и синхронизация источника, удаления нет. Обход: регистрация работает как перезапись — укажите идентификатор существующего источника и перенастройте его имя и адрес вместо создания нового.

Импорт требует сервиса раздачи. Без развёрнутого vstack-center-image-distributor (и его обязательного vhost imgdistr_vhost) байты двигать некому. Обход только один — развернуть сервис; синхронизация сервиса раздачи не касается, она читает лишь манифест.

Проверка зависимостей бывает неполной. Карту клонов собирают опросом всех узлов, и узел не на связи в ответ не попадает — он отмечается как пропущенный. Обход: дождаться, пока узел вернётся, и снять карту заново; удаление в такой ситуации всё равно закончится частичным исходом.

Что читать дальше​

Методы API​

Операции этой страницы в API: os-library-set, os-library-list, os-library-sync, os-image-import, golden-images-list, golden-image-clones, golden-image-remove — см. Справочник API.