Обзор агента
Агент — единственный процесс управления на ноде. Запускает Xray как дочерний процесс, держит стрим к backend (gRPC API) и приводит Xray к полученному NodeConfig. Собственных решений о конфигурации агент не принимает: он исполнитель desired state.
Reconciliation
Section titled “Reconciliation”flowchart TB
DS["DesiredState (revision N)"] --> DIFF["diff: NodeConfig ↔ фактическое состояние Xray"]
DIFF -->|применимо на лету| API["Xray API: add/remove inbound, user, outbound"]
DIFF -->|требует рестарта| GEN["полный конфиг → xray run -test → рестарт"]
API --> OK["ApplyResult(N)"]
GEN --> OK
- Агент строит фактическое состояние: список инбаундов, пользователей, аутбаундов из Xray API + собственный учёт того, что API не отдаёт (правила маршрутизации, сертификатные файлы).
- Считает diff с
NodeConfig. - Применяет: добавление/удаление пользователей, инбаундов, аутбаундов — горячо через Xray API; изменения, которые Xray не умеет на лету (правила маршрутизации, параметры существующего инбаунда), — генерацией полного конфига, валидацией
xray run -testи рестартом процесса. - Отправляет
ApplyResult. Ошибка любого шага —success: falseс текстом; состояние Xray при провале валидации не меняется.
Применение идемпотентно: повторный NodeConfig с той же ревизией даёт пустой diff. Промежуточных статусов нет — либо нода на ревизии N, либо нет.
Хот-патч против рестарта. Массовые ежедневные операции (клиенты появились/ушли/сменили ключ) всегда попадают в горячий путь — рестартов при обычной эксплуатации нет. Рестарт происходит при редких структурных изменениях (новый профиль, правила маршрутизации, цепочки) и стоит секунды даунтайма ноды; существующие соединения рвутся, клиенты переподключаются автоматически.
Локальное состояние
Section titled “Локальное состояние”/var/lib/astral-agent:
| Файл | Назначение |
|---|---|
identity/ |
Приватный ключ + клиентский сертификат + CA (Безопасность) |
last_config.json |
Последний применённый NodeConfig + ревизия |
usage.buffer |
Неподтверждённые дельты трафика (Трафик) |
certs/ |
PEM-файлы сертификатов для Xray |
При старте без связи с backend агент поднимает Xray из last_config.json — нода обслуживает клиентов при недоступной панели. Кэш не источник истины: после переподключения обычный reconciliation приводит ноду к актуальной ревизии.
Надзор за Xray
Section titled “Надзор за Xray”Агент — супервизор процесса Xray: падение → рестарт с экспоненциальным backoff + повторное применение последнего состояния; инцидент виден в StatusReport (xray_running, uptime). Команда restart_xray из панели — тот же механизм принудительно.
Агент держит кольцевые буферы последних строк своего лога и лога Xray. По команде get_logs отдаёт хвост, по start_log_stream — шлёт новые строки в стрим до stop_log_stream. На диск ноды логи Xray в объёме не пишутся (privacy: меньше следов трафика на ноде).