Перейти к содержанию

Кластерный API (MAIN ↔ LB)

Балансировщик нагрузки, используемый для прямого доступа к MariaDB и Redis в MAIN: его crons, демонам и конечные точки потоковой передачи хранили учетные данные панели управления в базе данных и записывали таблицы MAIN. То cluster API заменяет его одним подписанным зашифрованным HTTP-каналом, который узел открывает для MAIN. На этой странице представлен протокол и его взгляд на него оператора; проектная документация с каждым решение и его история - docs/adr/0004-cluster-api.md, и кодовые швы, через которые проходит каждый вызов, находятся в кластерных швах.

По умолчанию используется обычный HTTP

Для канала не требуется TLS. Каждый запрос подписывается, а его текст шифруется с помощью ключей производный от токена узла, поэтому панель без сертификата ничего не теряет, общаясь через http://. HTTPS является необязательным и предпочтительным при проверке сертификата — см. Транспортировка.

Какие путешествия

Узел всегда набирает номер MAIN; MAIN никогда не подключается к узлу (его инструкции ожидают, пока узел, чтобы запросить их). Каждый вызов равен POST /cluster/v1/<op> на HTTP-широковещательном порту MAIN, или на cluster_api_port, если он установлен.

Направление Переносится как Примеры
Узел → ГЛАВНЫЙ, требуется ответ операция на контрольной полосе hello, heartbeat, token_refresh, conn_admit, commands, ack
Узел → ГЛАВНЫЙ, отчет операция на линии захвата events, streams, conn_snapshot, queue_claim, queue_update, queue_enqueue, config, recording_complete, vod_analysis, artefact
ГЛАВНАЯ → узел подписанная команда, которую собирает следующий вызов узла commands node.rpc, node.root, node.cache, conn.kill_worker, conn.drop, conn.close, config.changed, artefact.fetch

Two ops the plan lists are deliberately never served: rpc_result (a command's result comes back inline with its ack, which takes 64 KiB) and stream_bundle (the replica's streams раздел содержит всю запись потока, и ошибка кэширования считывает ее с диска). Они остаются в список операций, потому что из него выводится полоса приема nginx, а API отказывает в операции. не служит.

Переулки

События помещаются в очередь по приоритету и удаляются агентом:

Переулок Что Темп
Р0 открытие или закрытие программы просмотра, состояние потока сразу
Р1 журналы, инвентаризация узла, его аудит дозированный
Р2 Прикосновения к здоровью пакетно, только пока MAIN принимает их

MAIN обслуживает операции управления в пуле cluster_ctl FPM и операции приема в cluster_ingest, размер которого равен cluster_ingest_concurrency; половина его разрешений зарезервирована для P0, чтобы поток журналов никогда не задерживал просмотр. Узел, который поступает во время запуска MAIN отклоняется с STARTING и отсрочкой, но никогда не с 500.

Идентификация

В файле нет общего секрета, а в проводнике нет учетных данных на предъявителя.

  1. Зачисление. MAIN присваивает узлу идентификатор (node_uuid, пара ключей Ed25519 для узла генерирует сам, закрепленный открытый ключ MAIN) по SSH при установке или с помощью одноразового код, который считывает оператор (cluster:enrol-code, согласован с cluster:enrol-approve).
  2. Жетон отчеканено внутри расширения xcvm_core из корневого секретного файла панели и лицензия, привязанная к uuid узла, поколению и эпохе. Она никогда не существует в PHP как открытый текст: узел получает его, запечатанный своим собственным ключом.
  3. Каждый запрос содержит временную метку, одноразовый номер и HMAC поверх канонического представление запроса с зашифрованным текстом (AES-256-GCM). MAIN отвечает на запрос таким же образом. Хранилище одноразовых данных отклоняет повторный запрос; запрос, время которого отключено отклонение более чем на допустимое отклонение отклоняется.
  4. Вращение. Время жизни токена равно lb_token_rotation_min (5-1440, по умолчанию 60). агент обновляется через половину срока службы; отклоненный токен повторно вводит ключ, а не останавливает узел. Отзыв лицензии вообще прекращает чеканку новых токенов, что и является причиной появления флота. огороженный забором.

Транспортировка и конечные точки

cluster_transport:

Ценность Значение
auto (по умолчанию) Сначала используется HTTPS, когда проверяется собственный сертификат MAIN, в противном случае используется обычный HTTP
http только обычный HTTP
https_preferred Сначала HTTPS, простой HTTP в качестве запасного варианта
https_required Только HTTPS; отказано, если сертификат MAIN не подтвердит, что и каждый активный узел уже подключился к MAIN по протоколу HTTPS (его агент сообщает об этой функции https).

URL-адреса, которые набирает узел, их порядок и способ передачи - это политика MAIN, версия которой cluster_policy_ver. Узел принимает политику, которая не старше той, которая у него есть, и запоминает простые HTTP-URL-адреса каждой политики, которую он видел: под https_required с сломанный сертификат, вызов подписи по обычному протоколу HTTP - это обратный путь.

При изменении адреса MAIN, его HTTPS-порта или cluster_api_port старая конечная точка продолжает обслуживаться for seven days so no node is lost; cluster:endpoint list shows what is kept and cron:cluster освобождает порт, как только каждый узел покидает его.

Политика также учитывает частоту сердечных сокращений флота (lb_telemetry_interval_sec, 1-3 секунды), так что его изменение распространяется на каждый узел со следующей политикой без перезапуска агента.

Потоки и режимы

То, что узел выполняет через API, переключается для каждого узла на странице "Узлы кластера". Поток переносит часть своей работы на агента и отменяет устаревший путь.

Немного Поток Движется
1 ТЕЛЕМЕТРИЯ статистика сервера: MAIN записывает строку servers из числа ударов сердца
2 команды операции удаления, задания кэширования и действия root поступают в виде подписанных команд
4 бревна записи о клиенте, потоке, ошибке, действии и по требованию становятся событиями log.*
8 потоки потоки узла поступают из его реплики, а его состояние выполнения - из его собственного хранилища
16 содержание записи, анализ VOD и очередь кодирования проходят через ОСНОВНЫЕ
32 конфигурация кэши узла создаются на основе реплики, а не базы данных MAIN
64 связи средства просмотра узла хранятся в реестре его агента
128 ПЛОСКОСТЬ ДАННЫХ ретрансляторы и файлы других серверов передаются через петлевой прокси-сервер агента с тикетами вместо секрета потока

mode - это независимость узла:

Режим Имя Значение
0 наследие считывает базу данных MAIN, как это было всегда
1 гибридный загружается с его копии, все еще может попасть в базу данных MAIN
2 интерфейс прикладного программирования каждое подключение к MariaDB или Redis от MAIN отклоняется в коде (LbDatabaseAccessException)

Перемещение узла вверх ограничено (ClusterAdmin::modeGate()): режим 1 требует настройки; режим 2 требует every flow, the data plane included, and the node's own connect audit clean — zero MySQL and нулевое повторное подключение выполняется в течение семи дней. Перемещение вниз всегда разрешено, потому что это способ back. A crontab row whose role is legacy (today cron:users) is not sent to a node in режим 2 вообще отсутствует.

Реплика узла

Пока включена настройка, кэши узла создаются на основе того, что сохранил агент, а не на основе запрос. MAIN обслуживает разделы; cluster:apply превращает их в кэши, которые хранятся в узле. читатели используют (теневое различие перед включением потока, чтобы оператор видел, что изменилось бы):

Раздел Носит
settings настройки, которые считывает узел, никогда не являются секретом
servers каждая строка сервера, без учета живучести или телеметрии
node собственная строка узла и настройки его узла
crontab включенные строки, роль которых соответствует режиму узла
cluster ОСНОВНЫЕ URL-адреса, транспорт, сердцебиение, клавиши панели, min_proto
secrets секретный токен просмотра и OPENSSL_EXTRA, каждый со значением, которое он заменил, и как долго это все еще принимается
bouquets, categories как cron:cache строит их
streams (R2) по одной записи на каждый поток, хранящийся на узле, которые сохраняются с помощью дельт и повторной синхронизации; при включенном DATAPLANE его ретрансляционные и файловые запросы также сохраняются

Ссылка на настройки

Установка Границы Что это значит
cluster_api_enabled 0/1 весь API; требуется cluster:init и расширение
cluster_api_port 0 или 1024-65535 0 обслуживает API на HTTP-широковещательном порту MAIN
cluster_main_host имя хоста DNS-имя MAIN в наборе URL-адресов узлов
cluster_transport смотрите выше политика
lb_token_rotation_min 5–1440 (60) срок службы токена; благодать равна clamp(L/4, 5, 60)
lb_revocation_mode изящный |трудный как быстро автопарк останавливается после отзыва лицензии
lb_telemetry_interval_sec 1–3 (2) сердцебиение флота, поддерживаемое политикой
cluster_offline_after_sec 10–300 (30) тишина перед включением MAIN означает, что узел отключен
cluster_orphan_conn_ttl_sec 30–3600 (120) тишина перед тем, как MAIN удалит зрителей узла
lb_offline_admission местный |позволять |отрицать допуск зрителей, в то время как ГЛАВНАЯ страница недоступна
cluster_kill_on_line_disable 0/1 (1) отключенная, заблокированная или с истекшим сроком действия линия теряет свои сеансы
cluster_ingest_concurrency 1–64 (6) Разрешения MAIN на прием; половина зарезервирована для P0
lb_new_node_mode наследие |интерфейс прикладного программирования режим, в котором регистрируется недавно установленный LB
servers_stats_retention_days 1–365 (30) cron:cleanup чернослив servers_stats
cluster_audit_retention_days 1–365 (30) cron:cleanup чернослив cluster_audit
cluster_db_allowlist (+_extra) 0/1 брандмауэры 3306/6379 подключены к сети интернет
lb_scan_roots пути каталоги, которые может перечислять RPC-сервер сканирования узла
lb_partition_tolerance_h, lb_fence_drain_min 0–24 (12), 0–60 (10) окно аренды после истечения срока действия токена и слив после него
lb_lease_fence 0/1 (0) узел перестает обслуживаться, когда заканчивается срок его аренды

Управляя им

# MAIN, once: create the cluster root and record the panel keys
console.php cluster:init

# Enrol a load balancer over SSH (or at install time, automatically)
console.php server:enrol <serverID>

# Without SSH: a one-time code the operator reads out, then approves by its SAS
console.php cluster:enrol-code <serverID>
console.php cluster:enrol-approve <serverID> <SAS>

# The node's own side, run by its agent after every change
console.php cluster:apply            # --from-disk at boot
console.php cluster:exec             # one signed command

# MAIN's endpoint and pools
console.php cluster:nginx            # render and reload the API's nginx config
console.php cluster:pools            # start or resize the API's FPM pools
console.php cluster:endpoint list    # old ports and URLs still served
console.php cluster:maintain-stats   # servers_stats indexes, built online (cron:cleanup starts it)

# Before switching CONNECTIONS on: load the node's viewers into its agent
console.php cluster:seed-connections <serverID>

# Every node (MAIN too, any mode) keeps the agent, the fanout daemon and xcvm_core
# current from GitHub itself, hourly from cron:root_signals; by hand, as root:
console.php fanout_binary [fanout|agent] [force]
console.php xcvm_core [force]

# Firewall MariaDB and Redis to the fleet (check first)
console.php cluster:db-allowlist status | apply | undo

# Phase 9: a mode-2 node gives up MAIN's credentials (asks first; --wait=<s> waits for the revoke)
console.php cluster:strip-credentials <serverID> [--yes] [--wait=<seconds>]

# MAIN reads other servers' files and relays through its own agent (on | off | rekey | status)
console.php cluster:main-dataplane on

# Rotate the panel's DB password (MAIN), and set it on a node MAIN cannot reach (node, root)
console.php cluster:rotate-db-password [--yes] [--password-stdin]
echo "$NEW_PASSWORD" | console.php cluster:set-db-password

# Disaster recovery of the cluster root
console.php cluster:export-keys   /path/bundle
console.php cluster:import-keys   /path/bundle

Страница "Узлы кластера" - это место, где узел утверждается, его потоки переключаются, его режим перемещается и его состояние указано (эпоха, истечение срока действия токена, окно ограждения, которое следует за ним — истечение срока действия токена плюс lb_partition_tolerance_h, затем lb_fence_drain_min — его команды в очереди, которые были просмотрены в последний раз, агент версия и архитектура, сбои в настройках, проверка подключения). Предупреждает о завершении действия лицензии. приостановлено (и, при включенном lb_lease_fence, не позднее, чем к моменту остановки автопарка) и когда Срок действия сертификата MAIN истекает в течение 14 дней, пока узлы могут подключаться к протоколу HTTPS. На рисунке показаны цифры ОСНОВНЫЕ записи: выполнение команд и задержка подтверждения (p50/p99 за последний час), глубина очереди, количество разрешения на использование для каждой полосы, очередь прослушивания пула cluster_ctl и недавний аудит. * Теперь поменяйте местами все токены * отправляет token.rotate_now каждому активному узлу, который принимает команды. Сохранение другого ключа активации на панели управления приводит к тому же результату, как только расширение принимает его. В меню "Строка" списка "Серверы" выполняются те же действия для каждого узла (переключение режимов вверх/вниз, поворот, регистрационный код, ссылка на потоки узла) и показывает команду cluster:reenrol для запуска для повторной регистрации по SSH. Каждое решение записывается в cluster_audit, что cron:cluster чернослив.

Сокращение, для того чтобы

  1. cluster:init на ГЛАВНОМ, cluster_api_enabled на, cluster:nginx, cluster:pools.
  2. Зарегистрируйте узел; подтвердите его, если он пришел по коду.
  3. Переключите ТЕЛЕМЕТРИЮ, затем КОМАНДЫ, затем ЖУРНАЛЫ — все это обратимо и отображается на странице.
  4. Переключайте ПОТОКИ и КОНТЕНТ; следите за сбоями в настройках узла и его аудитом.
  5. Измените конфигурацию, затем mode_up на 1: теперь узел загружается из своей реплики.
  6. cluster:seed-connections, затем СОЕДИНЕНИЯ.
  7. ПЛОСКОСТЬ ДАННЫХ, как только родительские узлы и серверы, файлы которых он считывает, являются основными или активные узлы, и его агент запускает ретрансляционный прокси-сервер (страница отказывается от переключения в противном случае): ретрансляция и чтение файлов проходят через его агент при следующем запуске каждого потока.
  8. Оставьте это на неделю. Когда проверка подключения узла покажет ноль MySQL и ноль Redis подключается в течение семи дней, с mode_up по 2.
  9. cluster:db-allowlist apply как только каждый узел перейдет в режим 2.
  10. Удалить учетные данные базы данных на узле (или cluster:strip-credentials): имя узла config.enc теряются учетные данные MAIN для DB и Redis, после чего MAIN отзывает свое разрешение. Есть отмена со страницы невозможна: для отката требуется конфигурация с учетными данными и новое разрешение.

Пределы

  • Уровень данных (фаза 8) охватывает то, что узел извлекает с другого сервера, и только пока его поток данных включен. Дочерний элемент, передающий поток, выборку VOD или субтитров и элементы созданного канала проходят через закольцованный прокси-сервер агента (127.0.0.1:31290), который подписывает каждое восходящее соединение с помощью подписанного панелью тикета из раздела потоков R2 (ретранслятор билет действителен 24 часа, файловый билет - 6 часов, оба чеканятся заново каждые 3 часа и никогда не перемещаются ETag или версию записи) и проверяет каждый фрагмент файла размером 4 МБ на соответствие его владельцу. подписанный дайджест. О чем он не распространяется:
  • Родитель или владелец, который не может проверить билет (устаревший сервер, не зарегистрирован или нет активен) по-прежнему доступен с помощью устаревшего URL-адреса и пароля к нему, даже при включенном потоке.
  • Потоки, запущенные до переключения потока, сохраняют свой URL-адрес до тех пор, пока не будут перезапущены.
  • Ретрансляционные байты аутентифицируются только при подключении, а не в рамке: по обычному протоколу HTTP они не имеют целостность (plan, D11). Файлы работают.
  • Секрет по-прежнему отображается в собственном цикле обратной связи узла: локальный вывод RTMP (rtmp://127.0.0.1/live/<id>?password=) и подключение самописца к своему собственному /admin/live и /admin/timeshift.
  • MAIN проходит через это только после того, как оператор запускает cluster:main-dataplane on: MAIN, затем получает собственный ключ уровня данных и запись в списке подписанных узлов, а также его источник зонд, журнал certbot узла, а также ретрансляторы и файлы потоков, которые он запускает, проходят через xc_agent run -role main. Выключено (по умолчанию), MAIN сохраняет устаревшие URL-адреса. Ключ MAIN находится в в config/cluster/main_agent.json (0600), вне xcvm_core, как это делает узел; cluster:main-dataplane rekey заменяет его и поднимает его поколение.
  • В файловом билете ключ от ячейки владельца указан таким, каким он был при чеканке: владелец повторно зарегистрировался так как не могу открыть его до получения билета следующей эпохи (самое большее через 3 часа).
  • Собственное наследие узла /api продолжает обслуживаться при включенном потоке. api_legacy.conf (Фаза второе приращение 8) удаляет его только после того, как ничто не считывает файлы узла с помощью устаревший URL-адрес getFile больше не используется: его собственный поток, и каждый сервер кластера является основным включен активный узел с включенной плоскостью данных. Значение MAIN засчитывается один раз установлен параметр cluster:main-dataplane on. Прокси-сервер никогда не является узлом, поэтому кластер с прокси-сервером сохраняет значение /api для каждого узла.
  • Поток может быть включен только для узла, агент которого запускает прокси-сервер обратной связи (при приветствии появляется сообщение relay): сначала обновите xc_agent. Агент публикует обратную связь ключ (relay.key) только в том случае, если он содержит 127.0.0.1:31290, а PHP узла проверяет что прослушиватель принадлежит владельцу ключа. В то время как порт не принадлежит агенту (удерживается другим пользователем или агент остановлен), сбой ретрансляции узла и чтения файлов и повторяются: они никогда не возвращаются к секрету потока. Агент, который не может связать порт сообщает MAIN при каждом нажатии кнопки: на странице узлов кластера отображается отключенный порт ретрансляции с указывает на ошибку и указывает на нее как на server:diagnose. Порт для нее не освобожден: оператор находит держатель на узле.
  • /xfile имеет свой собственный лимит скорости (50 запросов в секунду на сервер, пакет 100, на который отвечает 429 повторных попыток агента), не считая 20 запросов зрителей в секунду.
  • cluster:rotate-stream-secret не существует: отмена пароля относится к этапу 9.
  • Лицензионный договор выдается, проверяется и исполняется только после переключения (фаза 9). Каждый токен MAIN передает узлу (регистрация по SSH или с помощью кода, token_refresh, token_rekey) содержит договор аренды, подписанный xcvm_core, с ограничением в min(token_exp + lb_partition_tolerance_h, iat + 26 часов); когда расширение отказывает в выдаче лицензии (нет лицензии, ее clock gate, отмененная генерация) токен выходит без него, и происходит отказ для отправка лицензии ClusterLicenceLapsedEvent. xc_agent проверяет каждый полученный договор аренды (подпись панели, ее узел, сервер и генерация, окно для оценки производительности MAIN time), сохраняет самое свежее значение в своем файле состояния и выводит его с xc_agent lease. Ограждение, которое воздействует на него, встроено в PHP узла (Core\Cluster\NodeLease) за lb_lease_fence, что равно по умолчанию выключен: если он включен, то после истечения срока аренды exp новых просмотр начинается с узла (stream/auth.php), а после lb_fence_drain_min далее продолжающиеся сеансы останавливаются (segment.php, key.php, live.php), и агент удаляется каждый зритель, которого обслуживает fanout, сам оценивает ту же аренду, часы и настройки. Он оценивает состояние аренды следующим образом: агент записывает данные в config/cluster/lease_state.json с каждым интервалом времени, независимо от того, not MAIN answers: the lease's exp, and MAIN's clock carried forward on the node's монотонные часы из последнего аутентифицированного оператора MAIN, поэтому перемещение настенных часов узла не перемещает время MAIN, как считает fence, и перезапуск агента возобновляет его. Каждый причины неопределенности: отключение, устаревший узел, отсутствие файла или файл, который был остановлен агентом обновление, нет аренды, нет привязки к часам MAIN. Переключатель должен быть включен перед получением лицензии сбои — он достигает узла в секции реплики settings, в которой панель без лицензия не может быть подписана. Если номер узла xcvm_core предлагает ее (cluster_lease_state), то продление срока аренды определяется само по себе — по собственному штифту на панели управления и по якорю на Часы MAIN, которые работают в монотонном режиме и никогда не возвращаются назад, и файл агента это запасной вариант. Тот же вердикт делает license_valid() истинным для узла, так что LicenseGate позволяет использовать разветвление. Вердикт расширения должен соответствовать вердикту узла core.pin: установка по SSH закрепляет его за свой собственный сеанс и за любой другой узел, который получает root команды закрепляются символом cron:cluster со знаком node.root pin_core (значок core на странице Узлов кластера или Закрепите ядро, чтобы отправить его сейчас).
  • Частично построена система блокировки учетных данных (фаза 9). Узел в режиме 2 отказывается от основного учетные данные с подписью node.root strip_db_credentials (или без учетных данных node.root install_config), запускаемый xcvm_core от имени пользователя root; когда его ack сообщает о конфигурации без учетных данных MAIN аннулирует разрешение узла (XC_VM::db_revoke) и записывает cluster_nodes.db_revoked_at (Domain\Cluster\DbCredentials). Только оператор отправляет блокировка (Удалить учетные данные базы данных, cluster:strip-credentials) и lb_new_node_mode=api по-прежнему отклонено (api_mode_allowed равно false): переход остается решение оператора. Главный узел уже не содержит учетных данных (режим 2 или отозванный грант) остается таким: при переустановке по SSH он получает конфигурацию без учетных данных, повторно регистрируется в режим 2 и не предоставляет ему ничего, и путь к нему не указан (Повторная авторизация MySQL, tools mysql) достигает своего хоста. cluster:rotate-db-password изменяет пароль панели управления базой данных через XC_VM::db_set_password и отправляет каждый узел ниже режима 2, который получает root отправляет команду с подписью node.root rotate_db и новым паролем, прикрепленным к ее ячейковому ключу, который открывается его корневой стороной и переходит в XC_VM::config_set_db (меняется только db.pass). Любой другой балансировщик нагрузки, который все еще использует свой грант, сохраняет старый пароль до тех пор, пока оператор запускает на нем cluster:set-db-password. Пароль никогда не используется в качестве команды в понятно. cluster:rotate-credentials таким же образом изменяет пароль Redis, и также существует руководство cluster:lockdown (ADR 0004, пятый и седьмой этапы фазы 9).
  • Секретный токен просмотра может быть * заменен* корректно (значение, которое он заменяет, остается читаемым в течение десяти минут по всему флоту), но полный оборот — повторное шифрование того, что хранится под ним — это фаза 9.
  • Имя узла whitelist_ips принадлежит администратору: узел больше не публикует свои собственные адреса, потому что этот столбец предоставляет устаревший список разрешений /api.