Перейти к основному содержанию Перейти к навигации Перейти к нижнему колонтитулу
Ограниченное время: Программа Design Partner. План BUSINESS бесплатно на всю жизнь.

Репозитории

Создание, управление и работа с LUKS-зашифрованными репозиториями на удалённых машинах.

Репозитории

Репозиторий - это LUKS-зашифрованный образ диска на удалённом сервере. После монтирования он предоставляет:

  • Изолированную файловую систему для данных приложения
  • Отдельный демон Docker (отдельно от Docker хоста)
  • Уникальные адреса loopback для каждого сервиса в подсети /26

Создание репозитория

rdc repo create --name my-app -m server-1 --size 10G
ПараметрОбязателенОписание
-m, --machine <name>ДаЦелевая машина, на которой будет создан репозиторий
--size <size>ДаРазмер зашифрованного образа диска (например, 5G, 10G, 50G)
--skip-router-restartНетПропустить перезагрузку маршрутизатора после операции

Результат содержит три автоматически сгенерированных значения:

  • Repository GUID - UUID, который идентифицирует зашифрованный образ диска на сервере.
  • Credential - случайная парольная фраза для шифрования/расшифровки LUKS-тома.
  • Network ID - целое число (начиная с 2816, увеличиваясь на 64), определяющее подсеть IP для сервисов этого репозитория.

Храните учётные данные в безопасности. Это ключ шифрования вашего репозитория. В случае потери данные не могут быть восстановлены. Учётные данные хранятся в локальном файле config.json, но НЕ хранятся на сервере.

Монтирование и отмонтирование

Монтирование расшифровывает и делает файловую систему репозитория доступной. Отмонтирование закрывает зашифрованный том.

rdc repo mount --name my-app -m server-1  # Расшифровать и смонтировать
rdc repo unmount --name my-app -m server-1  # Отмонтировать и переш...кать
ПараметрОписание
--checkpointСоздать контрольную точку CRIU перед монтированием/отмонтированием (для контейнеров с меткой rediacc.checkpoint=true)
--skip-router-restartПропустить перезагрузку маршрутизатора после операции

Проверка статуса

rdc repo status --name my-app -m server-1

Список репозиториев

rdc repo list -m server-1

Колонка Type и зеркало состояния

Таблица вывода содержит колонку Type с тремя значениями:

  • grand. Репозиторий верхнего уровня, зарегистрированный в локальной конфигурации CLI без родителя. Базовый случай.
  • fork. Форк copy-on-write другого репозитория. Идентифицируется либо через grandGuid в локальной конфигурации, либо через зеркало .interim/state в renet на машине. Оба источника авторитетны; оба должны совпадать после заполнения зеркала.
  • unknown. Ни один сигнал не может классифицировать репозиторий. Чаще всего это форк, созданный до кода зеркала и никогда не переустанавливаемый после, или устаревший grand, запись которого в локальной конфигурации была случайно удалена. CLI отказывается угадывать; оператор должен запустить заполнение зеркала или удалить директорию, если она действительно orphaned.

Зеркало .interim/state/<guid>/.rediacc.json - это небольшой файл-сопровождение, написанный вне LUKS-зашифрованного тома, так что инструменты резервного копирования и repo list могут читать родословную форков без разблокировки каждого образа. Он имеет ту же структуру, что и файл .rediacc.json внутри тома (is_fork, grand_guid, name и т.д.), и обновляется при каждом вызове Repository.SaveState. То есть при каждом монтировании и при каждой мутации состояния. Это источник истины для обнаружения форков в запланированных резервных копиях: немонтированный форк с зеркалом, в котором написано is_fork: true, правильно пропускается из загрузок cold и hot.

Для регулярной очистки неизвестных записей смотрите rdc machine prune --prune-unknown.

Изменение размера

Установите репозиторий на точный размер или расширьте его на заданное количество:

rdc repo resize --name my-app -m server-1 --size 20G  # Установить точный размер
rdc repo expand --name my-app -m server-1 --size 5G  # Добавить 5G к текущему размеру

Репозиторий должен быть отмонтирован перед изменением размера. repo expand работает в режиме онлайн. Изменение размера меняет максимальный размер репозитория; чтобы вернуть освободившиеся блоки в пул без изменения максимума, используйте вместо этого repo trim.

Освобождение пространства (trim)

Удаление файлов внутри репозитория освобождает пространство для этого репозитория, а repo trim возвращает освободившиеся блоки в общий пул хранилища. Команда работает в режиме онлайн без каких-либо простоев:

rdc repo trim -m server-1                       # Trim every mounted repository plus the datastore
rdc repo trim -m server-1 --name my-app          # Trim one repository
rdc repo trim -m server-1 --report-only          # Show reclaimable space without trimming
rdc repo trim -m server-1 --docker               # Also clear stopped containers, dangling images, and build cache first

Принцип работы: образы репозиториев являются разреженными файлами, и зашифрованный том пропускает discards насквозь. Trim сообщает файловой системе внутри репозитория освободить все неиспользуемые блоки, что пробивает дыры в исходном образе и немедленно сокращает использование пула.

Примечания:

  • Для репозиториев с активным резервным копированием операция trim файловой системы пропускается и об этом сообщается: снимок резервной копии по-прежнему ссылается на блоки, поэтому пробивать дыры бессмысленно с точки зрения пула. Операция --docker этим не затрагивается и выполняется в штатном режиме (см. ниже).
  • Двойной запуск trim подряд сообщает 0 байт при втором запуске. Файловая система запоминает, какие группы блоков уже были обработаны; это ожидаемое поведение, а не сбой.
  • --docker никогда не удаляет помеченные тегами образы, только зависшие образы, остановленные контейнеры и кэш сборки. Добавьте --docker-volumes для удаления также неиспользуемых томов (это удаляет данные; только CLI). В отличие от trim файловой системы, --docker работает даже во время резервного копирования, так что вы можете очистить зависший кэш сборки, не дожидаясь окончания окна резервного копирования.

Политика автоматического размера

Вместо того чтобы изменять размер вручную, позвольте машине управлять размерами репозиториев. Политика включает автоматическое увеличение онлайн (максимальный размер репозитория увеличивается при заполнении) и запланированные операции trim. Машина применяет политики каждые несколько минут с помощью таймера systemd rediacc-storage-maintain.

# Machine-wide default: trim every repository daily
rdc repo policy set -m server-1 --auto-trim true

# Per-repository: grow my-app automatically, up to a hard ceiling
rdc repo policy set -m server-1 --name my-app --auto-grow true --max-quota 50G

# Inspect the stored and effective policy
rdc repo policy get -m server-1 --name my-app

Поля политики:

ПолеЗначениеПо умолчанию
--auto-growУвеличивать репозиторий онлайн при превышении файловой системой порогового значениявыключено
--max-quotaЖёсткий потолок для автоувеличения. Обязателен: его установка является явным согласием на сверхпроизводительность пуланет
--grow-thresholdПроцент использования файловой системы, при котором запускается увеличение85
--grow-stepСколько добавлять за одно увеличение: абсолютное значение (10G) или процент от текущего размера (20%)20%
--auto-trimВыполнять плановые операции trimвыключено
--trim-intervalМинимальный интервал в часах между автоматическими операциями trim24

Ограничения безопасности: автоувеличение не выполняется, когда свободное пространство в пуле ниже резерва (10 ГБ или 5% пула, в зависимости от того, что больше), ожидает не менее 30 минут между увеличениями одного репозитория и никогда не превышает --max-quota. Автоматического уменьшения нет: снижение максимального размера репозитория остаётся ручной офлайн-операцией repo resize.

Настройки на уровне репозитория переопределяют общий машинный параметр по умолчанию. Повторные вызовы policy set изменяют только переданные флаги.

Форк

Создайте копию существующего репозитория в его текущем состоянии:

rdc repo fork --parent my-app --tag staging -m server-1

Форки используют модель name:tag: полученный форк называется my-app:staging. Это создаёт новую зашифрованную копию с её собственным GUID и network ID, при этом делясь именем родителя. Форк использует тот же LUKS-credential, что и родитель.

Форки разделяют данные родителя через BTRFS reflink, включая любые учётные данные, хранящиеся на диске. Смотрите Что Rediacc не изолирует для обсуждения последствий, когда эти учётные данные авторизуют внешние сервисы, такие как Stripe, AWS или Railway. Чтобы защитить учётные данные развёртывания от доступа форка, используйте secrets для каждого репозитория вместо прямого внедрения значений в .env файлы внутри репозитория.

При создании форка repo fork записывает файл-сопровождение зеркала состояния по адресу <datastore>/.interim/state/<fork-guid>/.rediacc.json немедленно. Без разблокировки тома. Поэтому новый форк правильно идентифицируется как is_fork: true с момента создания. Это позволяет запланированным резервным копиям пропускать его (форки исключены из pipeline загрузок по умолчанию) даже если он никогда не был смонтирован. При форкировании форка grand_guid цепочка работает правильно: зеркало нового форка указывает на GUID оригинального родителя grand, а не на промежуточный форк.

Форк и запуск за один шаг

--up создаёт форк, монтирует репозиторий и запускает сервисы в рамках одной удалённой операции. Флаг --detach возвращает управление терминалом сразу после старта контейнеров; проверки готовности завершаются в фоновом режиме, а прокси повторяет попытки подключения, пока каждый сервис не будет доступен:

rdc repo fork --parent my-app --tag staging -m server-1 --up
rdc repo fork --parent my-app --tag scratch -m server-1 --up --detach

В наших тестах репозиторий объёмом 128 ГБ форкировался и выходил на работающие сервисы примерно за 57 секунд, а с --detach это занимает около 31 секунды. Отсоединённый запуск выводит подсказку для отслеживания прогресса: rdc machine query --containers --name <machine>.

Куда уходит время

Операции длительностью несколько секунд и более завершаются сводкой по времени: пошаговая разбивка, вотерфол с параллельными шагами и строка атрибуции, разделяющая конвейер Rediacc и время старта ваших сервисов:

  Rediacc pipeline 19.2s (61%) · service startup 12.3s (39%)

Время запуска сервисов означает загрузку контейнеров: образы, инициализация, проверки готовности, определённые в Rediaccfile репозитория, поэтому оно зависит от приложения. Диаграммы отображаются в интерактивных терминалах; задайте RDC_TIMING_CHART=1, чтобы принудительно вывести их при работе в конвейере.

Версионирование в стиле Git

Форки могут выступать как git-коммиты. rdc repo commit замораживает рабочий форк в неизменяемый, байт-стабильный коммит; rdc repo branch называет линию истории; rdc repo checkout клонирует коммит через reflink в новый записываемый форк; rdc repo log обходит цепочку родителей; rdc repo merge объединяет две линии без мутации живого репозитория на месте. rdc repo fork --immutable создаёт коммит-эквивалентную базу в один шаг.

rdc repo commit --name my-app:work --message "schema migration applied" -m server-1
rdc repo branch --branch staging --name my-app:work
rdc repo checkout --ref staging --from my-app:work --tag staging-copy -m server-1

Смотрите справочник по версионированию в стиле Git для полного набора команд, параметров и примеров.

Secrets

Secrets для каждого репозитория - это учётные данные развёртывания, вводимые в контейнеры без записи в зашифрованный образ репозитория. Они хранятся в отдельной плоскости от данных репозитория, поэтому rdc repo fork не распространяет их. Форк начинает с пустой карты secrets, и его контейнеры загружаются, идентифицируя себя как другой внешний principal, чем родитель.

Хотите пошаговое руководство? Смотрите учебник Управление Secrets для полного цикла set/list/deploy/verify/rotate.

Модель write-only (в стиле GitHub): get возвращает только SHA-256 digest. Значение в открытом виде никогда не возвращается никому, ни человеку, ни агенту. Если вы забыли значение, посмотрите его в менеджере паролей и произведите ротацию; вы не можете прочитать его обратно из Rediacc по дизайну. Это исключает целый класс утечек: записи терминала, историю shell, случайное перенаправление, подглядывание через плечо.

Два режима доставки:

  • env. Secret экспортируется как REDIACC_SECRET_<KEY> в оболочке renet на целевой машине. Ссылайтесь на него из docker-compose.yml через интерполяцию ${REDIACC_SECRET_<KEY>}. Видимо внутри окружения контейнера, поэтому используйте это для значений, похожих на строки подключения, которые приложение уже ожидает в env.
  • file. Secret записывается в /var/run/rediacc/secrets/<networkID>/<KEY> на хосте (tmpfs, никогда не сохраняется). Ссылайтесь на него из файла compose через декларацию secrets: верхнего уровня с источником file:, плюс список secrets: для каждого сервиса. Контейнеры читают из /run/secrets/<key>. Предпочитайте этот режим для всего, что чувствительно. Он никогда не появляется в docker inspect или /proc/<pid>/environ.
# Set, list, get (digest only), unset
rdc repo secret set --name my-app --key STRIPE_LIVE_KEY --value sk_live_xxx --mode file --current ""
rdc repo secret set --name my-app --key DB_HOST         --value postgres.internal --mode env --current ""
rdc repo secret list --name my-app
rdc repo secret get  --name my-app --key DB_HOST    # → { key, mode, digest } — no value
rdc repo secret unset --name my-app --key STRIPE_LIVE_KEY --current sk_live_xxx

Симметричный mutation gate. И люди, и агенты нуждаются в --current <previous-value> для перезаписи или отмены secret (предусловие в стиле passwd). Для первой записи нового ключа передайте --current "" (пусто). Чтобы произвести ротацию без проверки предыдущего значения, передайте --rotate-secret. Это громко логируется как ротация. --current и --rotate-secret являются взаимоисключающими.

Передайте --value - для чтения из stdin вместо argv (избегает exposure истории shell для одноразовых записей).

В вашем docker-compose.yml:

services:
  api:
    image: myapp
    environment:
      DATABASE_HOST: ${REDIACC_SECRET_DB_HOST}
    secrets:
      - stripe_live_key

secrets:
  stripe_live_key:
    file: /var/run/rediacc/secrets/${REDIACC_NETWORK_ID}/STRIPE_LIVE_KEY

Ссылка на сервис в нижнем регистре (stripe_live_key) - это имя файла /run/secrets/<name> внутри контейнера; последний part хостовой пути в верхнем регистре (STRIPE_LIVE_KEY) совпадает с тем, что вы установили с помощью --key. ${REDIACC_NETWORK_ID} автоматически интерполируется renet compose.

Кросс-репозиторная изоляция обеспечена: validator compose renet отклоняет пути secrets: file:configs: file:, и env_file:), которые ссылаются на network ID любого другого репозитория. Литеральный токен ${REDIACC_NETWORK_ID} (или целое число вашей собственной сети) - это единственно допустимая форма для ссылок /var/run/rediacc/secrets/.... И --unsafe НЕ переопределяет эту проверку. Песочница Landlock вокруг subprocess bash Rediaccfile также ограничивает доступ к файловой системе только к директории secrets вашей собственной сети, поэтому злонамеренный cat /var/run/rediacc/secrets/<other>/X из Rediaccfile не работает с EACCES на уровне ядра.

Форки: rdc repo fork не копирует secrets. Чтобы использовать secrets в форке, запустите rdc repo secret set --name <fork> на форке явно. Это load-bearing свойство безопасности. Контейнеры форка не должны иметь возможность действовать как production principal против внешних сервисов.

Агенты (Claude Code, Cursor и т.д.): repo secret list и repo secret get предоставляются как MCP-инструменты (read-safe. Только имена и digests, никогда значения). set и unset доступны только в CLI, потому что церемония --current/--rotate-secret требует человеческого надзора; агенты, вызывающие их через shell, получают тот же gate, что и люди. Когда предусловие не выполняется, JSON-оболочка содержит структурированное поле errors[].next.options[].run. Агенты должны передавать эти команды пользователю verbatim. Смотрите безопасность AI-агентов для полной модели.

Проверка

Проверить целостность файловой системы репозитория:

rdc repo validate --name my-app -m server-1

Владение

Установите владение файлами в репозитории для универсального пользователя (UID 7111). Это обычно требуется после загрузки файлов с вашей рабочей станции, которые приходят с вашим локальным UID.

rdc repo ownership --name my-app -m server-1

Команда автоматически обнаруживает директории данных Docker-контейнеров (монтируемые bind-мауты с правом записи) и исключает их. Это предотвращает разрушение контейнеров, которые управляют файлами со своими собственными UID (например, MariaDB=999, www-data=33).

ПараметрОписание
--uid <uid>Установить пользовательский UID вместо 7111
--skip-router-restartПропустить перезагрузку маршрутизатора после операции

Чтобы принудительно установить владение всеми файлами, включая данные контейнеров:

rdc repo ownership --name my-app -m server-1

Смотрите Руководство по миграции для полного пошагового объяснения того, когда и как использовать владение во время миграции проекта.

Шаблон

Применить шаблон для инициализации репозитория файлами:

rdc repo template apply --name my-template -m server-1 -r my-app --file ./my-template.tar.gz

Удаление

Постоянно уничтожить репозиторий и все данные внутри него:

rdc repo delete --name my-app -m server-1

Это постоянно уничтожает зашифрованный образ диска. Это действие нельзя отменить.

Миграция репозитория

Live-миграция репозитория с одной машины на другую. Единственный downtime - это финальная фаза delta-sync: обычно секунды до низких минут в зависимости от скорости записи в момент перехода.

rdc repo migrate --name my-app --from server-1 --to server-2
ПараметрОписание
--provisionПодготовить репозиторий на целевой машине перед миграцией (создаёт LUKS-образ и регистрирует конфиг)
--checkpointСоздать контрольную точку CRIU запущенных контейнеров перед переходом
--bwlimit <kbps>Ограничить пропускную способность rsync в килобайтах в секунду
--skip-dnsПропустить обновление DNS-записей после перехода

Трёхфазный процесс:

  1. Hot pre-copy - rsync передаёт данные, пока репозиторий остаётся запущенным на источнике. Большие файлы передаются до любого downtime.
  2. Cutover - репозиторий остановлен на источнике, финальный проход rsync синхронизирует оставшиеся изменения, и репозиторий запускается на целевой машине.
  3. Start on target - renet монтирует и запускает репозиторий на целевой машине. DNS обновляется, если не передан --skip-dns.

Repository Live Migration

Push vs migrate:

repo pushrepo migrate
ОперацияКопироватьПереместить
Источник послеБез измененийОстановлен
DowntimeНет (только копирование)Краткое окно перехода
DNS updateНетДа (если не --skip-dns)
Use caseРезервная копия, клон stagingЗамена машины, перемещение сервера

Очистка

После удаления репозиториев или восстановления после неудачных операций могут оставаться orphaned директории монтирования, файлы блокировки и неподвижные маркеры. Очистка удаляет их безопасно:

# Просмотрите, что будет удалено
rdc machine prune --name server-1 --dry-run

# Удалить orphaned ресурсы
rdc machine prune --name server-1

Затрагиваются только ресурсы без соответствующего образа репозитория. Непустые директории монтирования никогда не удаляются.