Skip to content
Архитектура & Системы 7 мин чтения

Архитектура связки Cardinal Panel и Cardinal Wings: от браузерного терминала до cgroups v2

Глубокий технический разбор многоуровневой архитектуры: разделение веб-контроллера (Nuxt 4 + Drizzle) и нодового демона на Go, проксирование WebSocket, потоковые логи через SSE и детерминированная адресация srv-<uuid>.

#Cardinal #Go #Nuxt 4 #WebSockets #SSE #SFTP #cgroups v2
Ключевые выводы архитектуры
  • ▸Панель не имеет прямого доступа к сокету хоста: взаимодействие с узлами происходит строго по защищённому REST API Wings.
  • ▸Использование детерминированного префикса `srv-<uuid>` устраняет необходимость синхронизировать случайные хэши контейнеров при переустановках.
  • ▸Потоковый вывод ANSI-логов в браузер организован через Server-Sent Events (SSE), а интерактивный TTY-терминал — через защищённый WebSocket-мост.
  • ▸Встроенный SFTP-сервер в демоне Wings chroot-изолирует сессию в каталог тома конкретного сервера.

1. Топология и разделение ответственности

При проектировании панели управления серверами (PaaS / Game Server Hosting) критически важно не связывать веб-интерфейс напрямую с системными сокетами контейнерного рантайма на хосте. В Cardinal эта задача решена через строгое трёхуровневое разделение: пользовательский браузер взаимодействует только с Nuxt 4 веб-панелью, панель опрашивает агент Cardinal Wings на целевом сервере, а Wings локально управляет процессами через Cardinal.

Топология сетевых потоков Cardinal Ecosystem
txt
[ Browser (Client) ]
        │  HTTPS (:443) / WSS (WebSocket Terminal)
        ▼
[ Cardinal Panel (Nuxt 4 + Drizzle ORM) ]  :3000
        │  Bearer Auth · Multi-Node Routing
        ▼
[ Cardinal Wings Daemon (Go) ]  :8080 (REST + SSE) · :2022 (SFTP)
        │  Loopback IPC / HTTP
        ▼
[ Cardinal Runtime (serve) ]  ~5 MB Go Static Binary
        │  clone(2) · setns(2) · pivot_root · cgroups v2
        ▼
[ Isolated Linux Containers (Namespaces + OverlayFS) ]

2. Детерминированная адресация: паттерн `srv-<uuid>`

Традиционные панели часто сохраняют в базе данных сгенерированный рантаймом хэш контейнера (например, a1b2c3d4...). При переустановке сервера (reinstall), обновлении базового образа или аварийном падении хэш меняется, что приводит к рассинхронизации состояния. В связке Panel + Wings контейнер всегда адресуется стабильным именем вида `srv-<server-uuid>`. Демон Wings содержит внутренний резолвер (`resolve.go`), сопоставляющий UUID сервера с живым процессом Cardinal. Панели не требуется мигрировать базу данных при пересоздании контейнера.

cardinal-wings/internal/resolver/resolve.go snippet
go
// ResolveContainer converts panel server reference to Cardinal container ID
func (r *Resolver) Resolve(serverRef string) (*ContainerMeta, error) {
    if !strings.HasPrefix(serverRef, "srv-") {
        serverRef = "srv-" + serverRef
    }
    container, err := r.cardinalClient.Inspect(serverRef)
    if err != nil {
        return nil, fmt.Errorf("server %s not found on this node: %w", serverRef, err)
    }
    return container, nil
}

3. Потоковый вывод логов и интерактивный терминал

Передача консольного вывода делится на два сценария: чтение архивных и свежих логов, а также интерактивный ввод команд (exec TTY). Для логов Wings предоставляет HTTP эндпоинт с Server-Sent Events (SSE): браузер подписывается на поток, экономя системные ресурсы по сравнению с постоянным polling-опросом. Для интерактивной консоли панель поднимает WebSocket-соединение с Wings, проксируя сырой TTY-поток напрямую в библиотеку xterm.js с поддержкой цветных ANSI-последовательностей.

Важное преимущество: панель не раскрывает внутренний IP-адрес демона Wings конечному пользователю. Все WebSocket-сессии проксируются через защищённый внутренний маршрут панели.

4. Изолированный SFTP-сервер на порту :2022

Управление конфигурационными файлами серверов (например, server.properties для Minecraft или postgresql.conf) требует безопасного файлового доступа. Вместо запуска системного OpenSSH-сервера хоста, демон Cardinal Wings содержит встроенную реализацию SFTP-сервера на Go. При авторизации пользователя Wings валидирует права доступа к конкретному серверу и выполняет строгий chroot в директорию тома контейнера, предотвращая выход за пределы папки сервера.

Подключение к серверу через SFTP
bash
# Подключение через стандартный SFTP-клиент
sftp -P 2022 admin.srv-7f8a9b2c@node1.example.com

# Внутренняя структура директории контейнера в Cardinal:
/var/lib/cardinal/containers/srv-7f8a9b2c/
├── config.json          # OCI спецификация процесса и cgroups v2
├── rootfs/              # Смонтированный OverlayFS слой
└── data/                # Персистентный том сервера (SFTP chroot root)

5. Модель безопасности: Scoped Bearer Tokens и Loopback

Демон Wings по умолчанию слушает локальный интерфейс (loopback) либо защищается внешним mTLS/Nginx прокси. Доступ к API защищён ролевой моделью токенов (Read-Only, Operator, Node Admin). Это гарантирует, что даже в случае компрометации отдельного сервера злоумышленник не получит доступ к управляющему рантайму хоста.

Сайт animesao.work.gd · MIT

MIT LicensePermissive

Исходный код сайта animesao.work.gd (Nuxt 4, Vue 3, Tailwind CSS 4), архитектурные схемы и инженерные заметки полностью открыты под лицензией MIT. Разрешено коммерческое и частное использование, модификация и адаптация при сохранении уведомления об авторстве.

Разрешено
  • ✓Коммерческое использование
  • ✓Модификация кода и стилей
  • ✓Распространение
  • ✓Частное использование
Ограничения
  • ✕Ограничение ответственности
  • ✕Отсутствие гарантий
Условия
  • ℹСохранение уведомления об авторских правах (c) 2026 animesao
Официальный текст лицензииSPDX: MIT
MIT License

Copyright (c) 2026 animesao

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.