NKT: Киллер фича № 7, скрипты: краткость — сестра таланта
Философия: почему 29, а не 290 Язык сценариев NKT — построчный декларативный язык развёртывания. Он не пытается быть полноценным языком программирования: в нём нет условий, циклов и функций. Это осознанный выбор.
Принцип: язык решает одну задачу — «Разверни сервис, проверь, что он работает, и перенеси, если нужно». Для этой задачи не нужны сотни абстракций. Нужны 29 глаголов.
Каждый глагол покрывает атомарное действие:
- Установить пакет
- Управлять службой
- Развернуть стек
- Создать ВМ
- Перенести контейнер
- Проверить доступность
Из 29 глаголов собираются сценарии любой сложности. Если нужна логика сложнее — есть описания сервисов и внешние плагины, которые расширяют язык без изменения его ядра.
Все 29 команд
set создаёт переменную для подстановки как ${ИМЯ}. Вариант ask спрашивает значение при запуске и не записывает его в текст и журнал — для паролей и токенов.
param создаёт параметр, значение которого спрашивается при запуске с подсказкой. Так один сценарий разворачивает разные стенды. Незаполненные параметры сверяются при запуске (Script.Unresolved).
Пример:
group создаёт группу хостов на хабе. С профилем — машины, создаваемые в ней, делаются по нему.
host добавляет хост на хаб по SSH — то же, что «Добавить хост» в интерфейсе. Варианты аутентификации: password ask, password "…", key hub.
install ставит nkt на перечисленные хосты и ждёт, пока каждый ответит.
wait имеет пять вариантов:
Последний вариант — проверка адреса снаружи: запрос с хаба по настоящему имени (DNS, шлюз, сертификат проверяются), хост указывать не нужно.
Пример:
Пакеты ставятся одной транзакцией. Файрвол работает через ufw или firewalld — в зависимости от того, что установлено на хосте.
Пример:
docker stack имеет четыре действия:
- up — поднять (скачав образы, если нужно)
- down — остановить и убрать
- start — запустить имеющееся без обращения к registry
- stop — остановить, оставив контейнеры
С блоком до end команда сначала записывает compose‑файл по указанному пути:
Стек, выложенный конвейером, запускают и останавливают командой deploy КОНВЕЙЕР start|stop — «Проверить» об этом напомнит.
vm create создаёт виртуальную машину из облачного образа. Опции: cpu, mem, disk, user, network, profile, install (поставить nkt внутрь).
cert issue работает через certbot --standalone: службы на 80/443 останавливаются на время проверки и запускаются снова.
git clone для приватных репозиториев: token ask (спросят при запуске) или key hub (deploy‑ключ хоста).
k8s create — самая «тяжёлая» команда языка. Создаёт кластер на виртуальных машинах: машины из облачного образа, control plane, присоединение узлов, ожидание Ready, проброс портов, скачивание kubeconfig на хаб.
Опции: flavor (k3s или kubeadm), nodes (размещение по хостам), image, cpu/mem/disk, network, cni, no-kube-proxy, version, expose, api/http/https порты.
pipeline сохраняет конвейер выкладки. Значения env: уходят в секреты конвейера. generate: создаёт значение (пароль, токен) на хабе.
deploy выкладывает конвейер и ждёт итога. С start или stop — запускает или останавливает уже выложенное на всех его хостах.
migrate переносит стек на другой хост: план с препятствиями до остановки стека, остановка, данные через хаб, запуск на новом. Упавший перенос откатывается сам. Опции: switch-fly, switch-pipeline, clean-leftovers.
k8s apply в сухом прогоне выполняет kubectl diff и показывает изменения без применения.
Виды маршрутов: https, http, tcp, udp, tcpudp. Цели: targets cluster КЛАСТЕР port N (все узлы кластера) или target ХОСТ container|vm|lxd ИМЯ ПОРТ (конкретная цель).
Новый маршрут записывается и применяется. У существующего цели меняются плавно: новые добавляются и проверяются, прежние выводятся. В сухом прогоне — проверка карты с маршрутом.
Реальный пример: полный цикл
Из репозитория, examples/scripts/forgejo-fly.nkt:
Что делает язык в этом сценарии:
- param — спрашивает хосты и домен при запуске
- pipeline — сохраняет конвейер с Docker Compose и генерацией паролей
- deploy — выкладывает и ждёт до 20 минут
- wait url — проверяет доступность через шлюз с проверкой сертификата
- migrate — переносит контейнер с переключением маршрутов и конвейера
- Финальная проверка доступности
47 строк. Вместо связки docker-compose.yml + deploy.sh + migrate.sh + healthcheck.sh.
Использование через веб‑интерфейс
Где найти
Профили → вкладка «Сценарии» → «Новый сценарий»
Редактор
- «Готовые сценарии ▾» — выпадающий список с примерами (Forgejo, Kubernetes). Пример вставляется целиком, с вопросом, если в тексте уже есть свои правки.
- «?» — значок в заголовке окна редактора и на карточке сценария открывает страницу «Команды сценариев» на сайте документации.
- Вкладка «Справка» — показывает ту же страницу с сайта. Переключатель «Сайт / Из nkt» — встроенная справка, если сайт недоступен. Выбор запоминается.
- Проверка — кнопка анализирует синтаксис и показывает ошибки. Имена хостов из параметров (on ${HOST}) не ругаются при проверке — они сверяются при запуске. Предупреждения не мешают сохранить и выполнить.
- История версий — таблица: №, время, автор, заметка, размер, метка «текущая». У каждой редакции: «Содержимое» (текст целиком), «Разница» с текущей или предыдущей, «Вернуть в редактор».
- Кнопка «ИИ ▾» — три действия:
1.Объяснить — разбор написанного кода
2.Написать по # ИИ: — генерация кода из комментариев
3.Написать по описанию — создание сценария из текстового описания задачи
Результат вставляется через дифф — пользователь проверяет и подтверждает. Сценариям от ИИ предупреждения показываются как ошибки на исправление.
Запуск
При нажатии «Запустить»:
- Диалог с полями для незаполненных param
- Чекбокс Сухой прогон — проверка без применения
- Журнал задания — пошаговый лог с таймстампами
Использование через API
Запуск сценария
Пределы — хосты и группы, к которым токен имеет доступ. Сценарии проверяются по разбору до запуска: хосты/группы вне предела — отказ (scriptScopeError).
Ограничения для токенов: создавать и править сценарии по токену нельзя. Только запускать сохранённые.
Интеграция с n8n
Готовые ноды для n8n:
Ответы на параметры передаются как JSON: {"param:FROM": "web1"}.
Описания сервисов
Помимо 29 встроенных команд, язык расширяется через описания сервисов — YAML‑файлы, которые добавляют поддержку новых сервисов без перекомпиляции.
Описания живут в /etc/netknownsthat/services.d/, в профиле хаба или встроены в nkt. Старшее описание перекрывает младшее. disabled: true выключает описание.
Встроенные описания: Traefik, RabbitMQ, Redis, PostgreSQL, Mosquitto, Envoy — с правилами безопасности.
Встроенные разборщики (nginx, HAProxy, Caddy, Docker, Podman, LXD, libvirt, Kubernetes, firewall, fail2ban) — тоже описания с engine:. Их можно выключить или настроить через описание на хосте или в профиле.
Внешние плагины
Плагины добавляют новые команды в скриптовый язык:
Плагины подключаются через конвейеры и предоставляют:
- Команды сценариев (plugin ИМЯ СЛОВО …)
- Инструменты MCP для ИИ‑агентов
- Разделы в веб‑интерфейсе
ИИ‑интеграция
Ассистент в редакторе
Кнопка «ИИ ▾» в редакторе сценариев:
- Объяснить — разбор написанного кода
- Написать по # ИИ: — генерация кода из комментариев
- Написать по описанию — создание сценария из текстового описания задачи
Результат вставляется через дифф — пользователь проверяет и подтверждает.
Ассистент хаба
Переписка с ассистентом: окно запуска, имена ссылками с меню, избранное. Имена объектов — ссылки с меню по типу: хост, контейнер и служба, конвейер, сценарий, кластер, маршрут, группа.
MCP‑сервер
Хаб предоставляет ~40 инструментов для ИИ‑агентов (Claude Code, Claude Desktop, Cursor):
- Хосты, находки, службы, контейнеры
- Конвейеры (создание, правка, сухой прогон)
- Задания, сценарии, переносы
- Traffic Fly, кластеры
Каждый инструмент — вызов того же API под тем же токеном, права и пределы — токена.
Честные ограничения языка
Чего нет
❌ Условий (if/else) — язык линейный
❌ Циклов (for) — для нескольких хостов используется перечисление ❌ Функций — повторное использование через готовые сценарии
❌ Состояния между запусками — каждый запуск изолирован
❌ Языка выражений — нет арифметики, конкатенации строк
Почему это осознанный выбор
Язык решает одну задачу: линейное развёртывание с проверками. Для сложной логики есть описания сервисов и внешние плагины.
Принцип: если в языке нет условия — значит, вам оно не нужно для этой задачи.
Заключение
29 команд. Одна страница документации. Пример к каждой. Готовые сценарии в редакторе. Сухой прогон перед применением. Журнал с таймстампами. История версий. ИИ‑ассистент. Описания сервисов. Плагины.
Это и есть «Краткость — сестра таланта» в инженерном исполнении: не добавлять абстракции, а убирать всё лишнее, пока не останутся только те 29 глаголов, которые реально нужны.
А когда нужна расширяемость — описания сервисов и плагины добавляют новые команды без изменения ядра языка.
Ссылки:
- 👉 GitHub: github.com/piqab/nkt
- 📚 Документация: github.io/nkt
- 📚 Справочник: github.io/nkt/guide/script‑commands