Files
ermnvldmr.com/services/docs/content/ru/apex/concepts/tiered-storage.md
T

9.1 KiB
Raw Blame History

title, description, weight
title description weight
Многоуровневое хранилище и изоляция привилегий Структура ссылок @tier, общее хранилище и понодовые noroot-пользователи. 16

Данные сервисов никогда не живут внутри репозитория узла. Они живут в трёх уровнях хранилища — раздельных расположениях, выбираемых для каждого хоста, — и достигают композиций через стандартизированную структуру символьных ссылок. Владение этими данными делегируется системным пользователям для каждого проекта, поэтому ни один сервисный контейнер не пишет от имени root.

apex tiers/link <tier1> <tier2> <tier3> строит два слоя ссылок:

  • На уровне узла: compositions/@tierN → корень хранилища уровня. Именно их движок выставляет как APEX_TIER_ROOT1..3.
  • Для каждого проекта: для каждого compositions/<project>/ действие создаёт <tier-root>/<project>/ и связывает compositions/<project>/@tierN → <tier-root>/<project>. Внутри каждого уровня оно также поддерживает shared/ с подкаталогом для каждого проекта и относительной ссылкой shared внутри каталога уровня каждого проекта, указывающей обратно на него.

Каждый проект дополнительно получает compositions/<project>/.env → <tier1-root>/<project>/.env (создаётся пустым, если отсутствует) — файл незакоммиченных секретов, описанный в Концепция: Композиции. Ссылки @tierN и файлы .env игнорируются git; репозиторий остаётся чистым источником.

Если путь, который должен быть символьной ссылкой, существует как настоящий файл или каталог, действие предупреждает и запрашивает подтверждение перед его удалением; отказ (включая неинтерактивный EOF) пропускает эту ссылку и продолжает.

Пользователи и группы

apex tiers/useradd провизионирует по одному заблокированному системному пользователю на проект — noroot-<project> (имя санитизируется, собственная первичная группа) — плюс общефлотовую группу noroot-shared, к которой присоединяется каждый пользователь проекта. Затем оно внедряет разрешённые ID в .env проекта между комментариями-маркерами, заменяя любой предыдущий блок при повторных запусках:

# START AUTO GENERATED APEX-NOROOT-USERS
APEX_UID=998
APEX_GID=998
APEX_SHARED_GID=997
# END AUTO GENERATED APEX-NOROOT-USERS

Композиции потребляют их как user: "${APEX_UID?error}:${APEX_GID?error}" и group_add: ["${APEX_SHARED_GID?error}"].

Матрица владения

apex tiers/chown обеспечивает владение по всем трём уровням. Без аргументов оно работает с корнями уровней (APEX_TIER_ROOT1..3); явные пути уровней могут переопределить это.

Путь Владение Примечания
<tier-root> root:root Только inode каталога.
<tier-root>/shared root:root Только inode каталога — никогда рекурсивно, поэтому существующие данные проектов внутри не затрагиваются.
<tier-root>/node-infra root:root Рекурсивно.
<tier-root>/<project> uid:gid Рекурсивно; ID читаются из .env проекта.
<tier-root>/shared/<project> uid:shared_gid Рекурсивно, плюс sticky-бит — участники могут добавлять файлы, но удалять только свои.

Проекты с неполным набором APEX_UID/APEX_GID/APEX_SHARED_GID пропускаются с предупреждением, указывающим на tiers/useradd.

Переменные уровней движка

Переменная Разрешается в
APEX_TIER_ROOT1..3 Корни хранилищ уровней (compositions/@tierN, полностью разрешённые).
APEX_TIER1..3 Каталоги данных ядрового проекта внутри каждого уровня (compositions/apex/@tierN).
APEX_TIER1..3_SHARED Общая область внутри уровней ядрового проекта.

Ядровая композиция монтирует исключительно через них; исполнитель резервного копирования вместо этого монтирует корень данных флота /srv в режиме только для чтения и разрешает контейнерные монтирования каждого помеченного сервиса обратно в их хостовые пути.

Резервные копии

apex backup/run <telegram-bot-url> управляет ядровым сервисом resticontainer (профиль manual, одноразовый) от начала до конца. Намерение резервного копирования управляется метками: resticontainer обнаруживает каждый сервис, несущий restic.enable=true, читает его restic.backup.paths (и опциональные restic.backup.stop / restic.hooks.*), разрешает эти контейнерные пути в хостовые пути и делает снимок их объединения в одном запуске restic.

  1. Проверяет доступность репозитория через snapshots; инициализирует репозиторий при необходимости.
  2. Выполняет backup с --host <APEX_NODE_HOST> и --tag biweekly — resticontainer выполняет pre-hook каждого помеченного сервиса, останавливает любой контейнер, помеченный restic.backup.stop, делает снимок разрешённых хостовых путей, затем перезапускает и выполняет post-hooks. Запуск отказывается сообщать об успехе, если не появляется новый снимок (защита от обнаружения нулевого количества меток).
  3. Применяет удержание через forget --prune (7 ежедневных, 4 еженедельных, 12 ежемесячных).
  4. Отправляет статус в Telegram в любом случае; успех, уведомление о котором не может быть доставлено, всё равно завершается с кодом 1, чтобы планировщики это заметили.

Расположение репозитория и учётные данные полностью берутся из конфигурации APEX_RESTIC_* (см. Справочник: Переменные окружения). Какие данные захватываются, решается для каждого сервиса его метками restic.* — например, ядровые сервисы резервируют только свою конфигурацию (динамические правила traefik, конфигурацию xray/adguard), оставляя воспроизводимые данные уровня 3, такие как кэши и логи, вне набора.


См. также: