[Документация Yandex Cloud](../../index.md) > [Yandex Cloud Stackland](../index.md) > Концепции > Лицензирование

# Лицензирование

Stackland лицензируется по суммарному числу процессорных ядер (vCPU) в кластере. Данные о лимитах предоставляет компонент *License Server*. Кластер периодически отправляет в License Server данные о фактическом потреблении ресурсов и получает в ответ актуальные лимиты, по которым формирует статус лицензии.

License Server также используется другими on-premises-продуктами Yandex Cloud, например DataLens, AI Studio и SpeechSense. При развертывании License Server как отдельного сервиса (см. раздел [License Server как отдельный сервис](#standalone)) один и тот же экземпляр может обслуживать несколько продуктов одновременно.

## Архитектура {#architecture}

License Server — самостоятельный сервис, который:

* хранит подписанные Yandex Cloud лимиты лицензий;
* собирает и хранит данные о потреблении ресурсов;
* при наличии связности с Yandex Cloud синхронизируется с облачным API: получает обновленные лимиты и отправляет агрегированные данные о потреблении.

Кластер Stackland выступает клиентом License Server. Агент лицензирования регулярно синхронизирует фактическое потребление, получает лимиты и публикует результат в ресурсе `PlatformConfig` в виде:

* секции `status.licensing` — текущая лицензия, лимит, потребление текущего кластера, суммарное потребление по всем инсталляциям лицензии и время последней успешной синхронизации;
* condition `LicenseSynced` — обобщенный признак того, что статус лицензии актуален.

## Режимы связности с облаком {#connectivity-modes}

License Server поддерживает два режима работы.

### Онлайн {#online-mode}

License Server подключен к API Yandex Cloud:

* периодически забирает из облака актуальный набор подписанных лицензий и проверяет подпись;
* отправляет в облако агрегированные данные о потреблении для биллинга и аналитики.

Этот режим подходит для контуров, у которых есть исходящий доступ к API Yandex Cloud (как правило, через DMZ).

### Офлайн (air-gapped) {#offline-mode}

License Server работает без связи с облаком:

* лимиты доставляются как подписанный файл лицензий, который владелец инсталляции получает у поставщика и размещает на сервере;
* данные о потреблении не отправляются в облако автоматически. Их выгружают из административного API License Server в виде зашифрованного файла и регулярно передают в Yandex Cloud вручную. Подробнее см. в разделе [Выгрузка данных о потреблении в air-gapped-инсталляции](#export-usage).

Этот режим подходит для изолированных контуров без доступа в интернет. Со стороны кластера Stackland режим связности License Server прозрачен: агент лицензирования обращается к License Server одинаково в обоих случаях.

## Размещение License Server {#deployment}

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

### License Server как компонент Stackland {#in-cluster}

License Server разворачивается внутри кластера Stackland как компонент платформы. В качестве хранилища используется кластер Managed Service for PostgreSQL.

Подходит для инсталляций, где не требуется отдельная инфраструктура: License Server работает как компонент платформы и использует механизмы самовосстановления Kubernetes, поэтому по устойчивости не уступает варианту с отдельным сервисом.

Преимущества:

* не нужна отдельная инфраструктура для License Server;
* единый цикл установки, обновления и мониторинга вместе со Stackland;
* быстро разворачивается из стандартного дистрибутива.

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

* доступность License Server привязана к доступности кластера: при недоступности кластера недоступен и License Server;
* в текущей версии один экземпляр обслуживает только один кластер Stackland.

### License Server как отдельный сервис {#standalone}

License Server разворачивается как самостоятельный сервис в Docker-контейнере с внешним PostgreSQL, как правило, на отдельном хосте в DMZ.

Подходит для промышленных инсталляций и для случаев, когда один License Server должен обслуживать несколько кластеров Stackland, например `test` и `prod`.

Преимущества:

* не зависит от состояния конкретного кластера Stackland;
* подходит для развертывания в DMZ — можно изолировать продуктовый контур от облачного API;
* один экземпляр может обслуживать несколько продуктов и несколько инсталляций.

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

* нужно поддерживать выделенный хост и внешний PostgreSQL;
* установка и обновление выполняются отдельно от Stackland.

В обоих вариантах кластер Stackland обращается к License Server одинаково — отличается только эндпоинт в настройках подключения.

## Лимиты и потребление {#limits-and-usage}

Stackland лицензируется по метрике `stackland.vcpu.cores`. Под потреблением понимается сумма `capacity.cpu` всех узлов кластера в статусе Ready. В расчет входят все узлы Kubernetes API, независимо от роли (`control-plane`, `worker`, `combined`).

Агент лицензирования периодически пересчитывает локальное потребление, отправляет его в License Server и публикует полученный статус лицензии в `PlatformConfig.status.licensing`.

Лимит лицензии включает все развернутые кластеры, а не только текущий.

### Временное превышение лимита {#overuse}

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

Временное превышение — не штатный режим эксплуатации. Платформа фиксирует факт превышения, публикует его в статусе лицензии и при длительном или существенном превышении ограничивает дальнейшее масштабирование (см. раздел [Поведение при нарушении лицензии](#enforcement)). Чтобы вернуть кластер в штатный режим, нужно либо привести потребление в соответствие с лицензией, либо обновить лицензию у поставщика.

## Поведение при нарушении лицензии {#enforcement}

При нарушении условий лицензии Stackland ведет себя так:

* в `PlatformConfig.status.licensing` появляются `state=WARNING` или `state=CRITICAL` и список причин в `reasons` (например, превышение лимита, истекший срок действия лицензии, устаревший статус);
* condition `LicenseSynced` переходит в `False` с причиной, по которой статус лицензии нельзя считать актуальным;
* при существенном или длительном нарушении масштабирование кластера ограничивается: создание новых ресурсов `StacklandHostConfig` блокируется. Уже работающие узлы продолжают обслуживать рабочие нагрузки.

При этом продолжают работать:

* эвакуация и удаление узлов через ресурсы `StacklandHostConfig` или консоль управления, подробности см. в разделе [Масштабирование кластера](../operations/cluster/scale-cluster.md);
* штатные операции с пользовательскими нагрузками;
* доступ к консоли управления, API Kubernetes и компонентам платформы.

Чтобы снять ограничения, нужно либо вывести часть узлов и привести потребление в соответствие с лицензией, либо обновить лицензию у поставщика и дождаться очередной синхронизации с License Server.

## Устаревший статус лицензии {#stale-status}

Если License Server не может связаться с облаком, последние полученные лимиты остаются в силе на протяжении настроенного окна. По истечении этого окна статус лицензии помечается как устаревший: `state` переходит в `WARNING` или `CRITICAL`, condition `LicenseSynced` становится `False` с соответствующей причиной.

В офлайн-режиме источник истины — локальный подписанный файл лицензий, поэтому отсутствие связи с облаком не приводит к устареванию статуса. Устаревший статус в офлайн-режиме возможен, только если агент лицензирования длительное время не может обратиться к License Server (например, License Server остановлен или недоступен по сети).

## Действия администратора {#admin-actions}

### Посмотреть текущий статус лицензии {#check-status}

Чтобы посмотреть текущий статус лицензии в кластере, выполните команду:

```bash
kubectl get platformconfig default -o jsonpath='{.status.licensing}'
```

Чтобы получить только обобщенный признак актуальности статуса, выполните команду:

```bash
kubectl get platformconfig default \
  -o jsonpath='{.status.conditions[?(@.type=="LicenseSynced")]}'
```

Поле `state` показывает обобщенный статус лицензии:

* `OK` — лицензия действительна, потребление в пределах лимита.
* `WARNING` — потребление выше лимита либо статус начал устаревать. Кластер продолжает работать, но требуется внимание администратора.
* `CRITICAL` — лицензия просрочена, статус лицензии устарел или потребление достигло критического порога. Возможны ограничения на масштабирование.

Поле `reasons` содержит список причин, по которым статус отличается от `OK`.

### Выгрузка данных о потреблении в air-gapped-инсталляции {#export-usage}

Метод `ExportUsage` административного API License Server формирует зашифрованный файл с данными о потреблении и сохраняет его в каталоге экспорта на стороне сервера. Метод доступен в любом режиме связности, но в air-gapped-инсталляции это единственный способ доставить данные о потреблении в Yandex Cloud: в онлайн-режиме данные отправляются автоматически в рамках синхронизации с облаком.

Чтобы запустить выгрузку, выполните команду:

```bash
curl \
  -H "Authorization: Bearer <admin_token>" \
  'https://<адрес_license_server>:<порт>/api/v1/admin/usage/export'
```

Дополнительные query-параметры:

* `from` и `to` — границы временного интервала в формате RFC 3339. Передаются только парой: если задан один параметр, должен быть задан и второй. Если оба параметра не заданы, в выгрузку попадают все доступные записи.
* `filename` — имя файла без расширения. Если не задано, имя формируется автоматически: `usage_export_<export_id>.json.enc`.

В ответе возвращаются метаданные сформированного файла: `export_id`, `file_path`, `file_size`, `record_count`, контрольная сумма `checksum` (SHA-256) и подпись `signature` (ECDSA, base64). Сам файл нужно забрать с хоста License Server по пути из `file_path` и передать в Yandex Cloud по согласованному с поставщиком каналу.

Регулярная выгрузка нужна, чтобы корректно работали биллинг и аналитика на стороне Yandex Cloud.

#### См. также {#see-also}

* [Руководство по установке](../quickstart.md)
* [Масштабирование кластера](cluster-scaling.md)
* [Масштабирование кластера](../operations/cluster/scale-cluster.md)