ActiveScaleинженерная практика

Model API: mTLS, GET/PUT и задачи

Эксплуатация model-apimodeltaskslatencymongohowto

Коротко. Model API — REST-интерфейс к модели системы на порту 8443, только по mTLS: без клиентского сертификата сервер отвечает 400 сразу, и это норма. Чтение — GET /model/<сущность>/, изменение — PUT документа или его поля, после чего запускается задача configure. Латентность API — быстрый индикатор здоровья: миллисекунды в норме, десятки секунд означают, что модель ждёт mongod, а не «медленный GUI».


1. Что это и как устроено

Модель — база описания системы: машины, сети, диски, колонки, окружение, приложения, правила конфигурации. Продукт не хранит конфиги «руками»: он рендерит файлы служб из модели. Поэтому изменение через Model API — штатный путь, а правка файла на диске будет перезаписана при следующем применении конфигурации.

Схема запроса:

клиент → nginx :8443 (mTLS) → Model API → mongod (management_model)

Три модели данных живут в отдельных кластерах mongod: management_model (основная), environment_data (окружение) и federated_model (федерация). Порты 27017/27018/27019 соответствуют им; путать кластеры нельзя — это разные базы.


2. Доступ: mTLS и сертификаты

  • Порт — 8443, TLS обязателен, клиентский сертификат обязателен.
  • Сертификаты продукта лежат в каталоге mTLS-конфигурации: machine.cert и machine.key. Они root-only, поэтому запрос от обычного пользователя даёт HTTP 000 — TLS просто не поднимается. Все вызовы с узла — через sudo.
  • Каталог сертификатов версионируется (ssl.<hash>, рядом симлинк ssl): путь берётся через симлинк, хеш не хардкодится.
  • Без клиентского сертификата ответ 400 приходит мгновенно — это признак того, что служба жива и правильно настроена, а не ошибка.

Проверка живости (на узле, root):

sudo curl -sk https://127.0.0.1:8443/ -o /dev/null -w '%{http_code}\n'

Ожидается 400. Если 000 — TLS не поднялся (нет прав на сертификат) либо служба не слушает.

Рабочий вызов:

cd "$(ls -dt /opt/ampli/cfg/marvin/ssl* | head -1)"
sudo curl -sk --cert machine.cert --key machine.key \
  https://127.0.0.1:8443/model/machine/ | jq '.machine[] | {name, role, status}'

3. Адресация сущностей

Путь строится как /model/<сущность>/ или /model/<сущность>/<guid>/. Основные сущности:

Сущность Что содержит
machine узлы: роль, статус, hardwaretype, rackunit, приложения
column колонки хранения, статус, размеченная ёмкость (resources)
disk диски, привязка к полкам/слотам
location локации: стойка, площадка; серийный номер стойки
networkswitch коммутаторы, участвующие в топологии
environment окружение: выбранная политика, параметры модели
configrule правила, из которых рендерятся конфиги служб
task задачи: статус, прогресс, ошибки
taskschedule периодические задачи: enabled, last_run_at

Вложенные объекты адресуются через родителя: NIC — /model/machine/<MGUID>/nic/<NGUID>/, действия — /model/<сущность>/<guid>/action/<имя>/.

Ответ на коллекцию — JSON-объект с ключом, равным имени сущности ({"machine": [...]}), а не голый массив. GET без limit на больших коллекциях может быть тяжёлым (см. §6).


4. GET, PUT и типовые коды

Чтение. GET /model/<сущность>/ или /model/<сущность>/<guid>/. Ничего не меняет.

Запись. PUT документа целиком либо отдельного поля: PUT /model/machine/<guid>/ телом {"rackunit": 12}; для backend-машины — PUT /model/column/<cg>/action/proxy/machine/<mg>/.

Типовые ответы и их смысл:

Код Причина Что делать
200 принято проверить документ повторным GET
400 нет клиентского сертификата, либо нет Content-Type: application/json добавить сертификат и заголовок
423 LOCKED висит незавершённая задача на этом объекте снять задачу, см. §5
503 клиент не видит PRIMARY mongod («no replica set members match Primary()») повторить запрос или переждать транзиент
500 ошибка схемы/валидации значения сверить допустимые значения поля с живым документом

Заголовок Content-Type: application/json обязателен: без него PUT отвечает 400, и это самая частая «ошибка модели», которой на самом деле нет.

Значения полей не угадываются. Например, category политики хранения — жёсткий список (balanced, lower_overhead, lowest_overhead, 2site_replicated, custom); своё имя вроде balanced-8 даёт 500 ValidationError. Своя политика создаётся в слоте custom, а схема полей читается из живого документа. Подробнее — Формула политики DSS.


5. Задачи: как изменение становится применённым

PUT в модель — это только новое описание. Чтобы оно дошло до служб, запускается задача configure:

sudo curl -sk --cert machine.cert --key machine.key \
  -X POST -H "Content-Type: application/json" \
  -d '{"targets": "<MGUID>"}' \
  https://127.0.0.1:8443/model/machine/<MGUID>/nic/<NGUID>/action/configure/

Ответ содержит объект task с полем guid. Дальше задача читается по guid: GET /model/task/<guid>/. Ожидаемые статусы — QUEUED, STARTED, SUCCESS; ошибочные — FAILURE, REVOKED. «Залипшая» задача в STARTED держит блокировку и приводит к 423 LOCKED на следующих изменениях; её снимают штатным действием terminate:

sudo curl -sk --cert machine.cert --key machine.key \
  -X POST https://127.0.0.1:8443/model/task/<guid>/action/terminate/

Периодические задачи (taskschedule) — отдельная история. Оборванный install-ng оставляет column_bucket_update, logs_pruner, reconcile_federateddata выключенными: он выключает их на старте и включает только в самом конце успешного прогона. Признак — пустая витрина durability и «не дозревающие» метрики. Точечное включение — тот же вызов, что делает продукт: PUT /model/taskschedule/<guid>/enabled/True.


6. Латентность модели: главный диагностический признак

Латентность GET — самый быстрый способ отличить «модель думает» от «UI врёт»:

Наблюдение Значение
Норма на здоровом кластере десятки миллисекунд
Точечное чтение задачи по guid 0.1–0.4 с
Модель ждёт mongod (например, после потери питания) порядка 30 с вместо ~20 мс
Полный GET /model/task/ без limit при раздутой истории порядка 27 с и десятки МБ

Два последних случая — разные. Первый означает, что модель не получила базу: пока mongod не поднялся, GUI выглядит как «не принимает пароль», а API отвечает медленно (разбор — GUI «не принимает пароль» и mongod не поднялся). Второй — просто раздутая история задач: продукт читает задачи по guid и с limit, полный список в горячий путь не входит, поэтому «распухшие» задачи сами по себе установку не ломают. Уборка — штатная: уменьшить retention_config в документе environment (число дней хранения) и дать пройти периодической задаче очистки.


7. Границы и правила

  1. Только штатные сущности. Правка mongod напрямую — не путь: модель кэширует и валидирует, прямой документ разойдётся со схемой.
  2. Файлы служб не править. Продукт рендерит их из configrule; ручная правка исчезнет при следующем configure. Сертификаты S3/GUI — тоже через модель, см. S3-домен и сертификат.
  3. Бэкап до изменения. Сохранить текущий документ (GET) и правило (configrule) вне каталогов продукта.
  4. Читать перед записью. Смотреть живой документ, а не предполагать формат: settings у правил бывает массивом по узлам, а не объектом.
  5. Не путать 400 с поломкой. Мгновенный 400 без серта — норма mTLS.

Читать модель без curl удобнее через консоль: cli.ha.get('/model/...') возвращает строку JSON, которую надо разобрать. См. CLI sherpa.


8. Источники

  • Quantum Software Documentation Center (7.3) (2026-11-07)
  • ActiveScale Z200 datasheet — REST API в перечне интерфейсов управления
  • Наша практика (обезличенно): mTLS-вызовы, PUT/POST и задачи проверены на кластере из трёх нод, ActiveScale 7.3.1.2; латентность ~30 с против ~20 мс наблюдалась после полной потери питания, пока mongod не поднялся; полный список задач — 27 с / ~40 МБ при раздутой истории.
  • Обновлено: 2026-11-07.

Нужен инженер? Разберу вашу ситуацию и скажу, что делать — по шагам, с проверками.

Обсудить задачу