Резервное копирование и восстановление
Rediacc создает резервные копии зашифрованных репозиториев во внешние хранилища и восстанавливает их на той же или другой машине. Резервные копии зашифрованы; для восстановления требуются учетные данные LUKS репозитория.
Настройка хранилища
Перед отправкой резервных копий зарегистрируйте провайдера хранилища. Rediacc поддерживает любое совместимое с rclone хранилище: S3, B2, Google Drive и многие другие.
Импорт из rclone
Если у вас уже настроен удаленный ресурс rclone:
rdc config storage import --file rclone.conf
Эта команда импортирует конфигурации хранилища из файла конфигурации rclone в текущую конфигурацию. Поддерживаемые типы: S3, B2, Google Drive, OneDrive, Mega, Dropbox, Box, Azure Blob и Swift.
Просмотр хранилищ
rdc config storage list
Отправка резервной копии
Отправьте резервную копию репозитория во внешнее хранилище:
rdc repo push --name my-app -m server-1 --to my-storage
Резервная копия попадает в папку hot/ хранилища, если репозиторий смонтирован в момент отправки, и в cold/, если не смонтирован. Эта раскладка совпадает с той, что используют запланированные резервные копии, поэтому rdc repo backup list показывает все резервные копии в одной таблице.
| Опция | Описание |
|---|---|
--to <storage> | Целевое хранилище |
--to-machine <machine> | Целевая машина для копирования между машинами |
--dest <filename> | Пользовательское имя файла назначения |
--checkpoint | Создать контрольную точку CRIU перед отправкой (для контейнеров с меткой rediacc.checkpoint=true). Целевая машина автоматически восстанавливает при repo up |
--force | Перезаписать существующую резервную копию |
--bwlimit <limit> | Ограничение пропускной способности для rsync-передачи (например, 10M, 500K) |
--tag <tag> | Пометить резервную копию тегом |
-w, --watch | Отслеживать прогресс операции |
--debug | Включить подробный вывод |
--skip-router-restart | Пропустить перезапуск сервера маршрутов после операции |
Получение / Восстановление резервной копии
Получите резервную копию репозитория из внешнего хранилища:
rdc repo pull --name my-app -m server-1 --from my-storage
Команда pull всегда проверяет, смонтирован ли целевой репозиторий перед записью. Если он не смонтирован, операция прерывается.
| Опция | Описание |
|---|---|
--from <storage> | Исходное хранилище |
--from-machine <machine> | Исходная машина для восстановления между машинами |
--force | Перезаписать существующую локальную резервную копию |
--bwlimit <limit> | Ограничение пропускной способности для rsync-передачи (например, 10M, 500K) |
-w, --watch | Отслеживать прогресс операции |
--debug | Включить подробный вывод |
--skip-router-restart | Пропустить перезапуск сервера маршрутов после операции |
Список резервных копий
Просмотрите доступные резервные копии в хранилище:
rdc repo backup list --from my-storage -m server-1
Вывод представляет собой объединённую таблицу, которая сводит обе папки запланированных резервных копий (hot/ и cold/), так что вы видите каждую резервную копию в одном представлении:
| Колонка | Значение |
|---|---|
Mode | hot или cold. В какой папке запланированных резервных копий находится эта запись |
Name | Имя репозитория, разрешённое из вашей локальной конфигурации (для репозиториев не из конфигурации используется GUID) |
GUID | GUID репозитория на диске |
Size | Удобочитаемый размер файла резервной копии |
Modified | Метка времени UTC от хранилища |
Чтобы перейти к одному режиму, передайте --path:
rdc repo backup list --from my-storage -m server-1 --path hot
rdc repo backup list --from my-storage -m server-1 --path cold
Раскладка хранилища
Запланированные резервные копии попадают в подпапки по режиму внутри настроенной папки хранилища, поэтому одно и то же хранилище аккуратно содержит как почасовой, так и еженедельный потоки, не смешивая их:
<bucket>/<folder>/
├── hot/
│ ├── <guid-1>
│ ├── <guid-2>
│ └── ...
└── cold/
├── <guid-1>
├── <guid-3>
└── ...
Репозиторий может появляться и в hot/, и в cold/ (почасовое расписание делает его снимок; еженедельное расписание делает его снимок снова). Объединённый список показывает обе строки, чтобы было ясно, какие потоки покрывают какие репозитории.
Массовая синхронизация
Отправьте или получите все репозитории одновременно:
Отправка всех в хранилище
rdc repo push --to my-storage -m server-1
Получение всех из хранилища
rdc repo pull --from my-storage -m server-1
| Опция | Описание |
|---|---|
--to <storage> | Целевое хранилище (направление отправки) |
--from <storage> | Исходное хранилище (направление получения) |
--repo <name> | Синхронизировать определенные репозитории (можно указывать несколько раз) |
--override | Перезаписать существующие резервные копии |
--debug | Включить подробный вывод |
--skip-router-restart | Пропустить перезапуск сервера маршрутов после операции |
Запланированное резервное копирование
Rediacc использует именованные стратегии резервного копирования. Каждая стратегия определяет расписание, режим резервного копирования, необязательное ограничение пропускной способности и фильтры файлов. Машины привязываются к стратегиям по имени, чтобы определить, какие резервные копии на них выполняются.
Режимы резервного копирования
| Режим | Поведение | Простой |
|---|---|---|
hot | Снимок BTRFS создается во время работы сервисов (согласованность при сбое) | Отсутствует |
cold | Сервисы остановлены, снимок сделан, сервисы перезапущены, снимок загружен (согласованность на уровне приложения) | Окно остановки+запуска для каждого репозитория, распараллеленное между репозиториями. См. «Оценка простоя при холодном резервном копировании» ниже. |
Используйте hot для сервисов, допускающих снимки с согласованностью при сбое. Используйте cold, когда нужна гарантированная согласованность и допустим кратковременный перезапуск.
Семантика холодного резервного копирования
Холодное резервное копирование выполняется в трех фазах для каждого включенного репозитория: остановка, снимок, запуск. Понимание границ гарантий помогает операторам своевременно обнаруживать частичные сбои.
Что гарантирует холодное резервное копирование:
- Перед снимком каждый работающий контейнер в каждом включенном репозитории корректно останавливается через хук
down()Rediaccfile, а Docker daemon репозитория переводится в состояние покоя. Таким образом, снимок согласован на уровне приложения, а не только при сбое. - Набор ID контейнеров, работавших до снимка, сохраняется в файл-sidecar по пути
/var/run/rediacc/cold-backup-<guid>.running.json. Это источник истины о том, какие контейнеры должны быть запущены после завершения. - После снимка вызывается хук
up()Rediaccfile репозитория для восстановления полного compose-стека. - Файл-sidecar статуса выполнения по пути
/var/run/rediacc/cold-backup-<guid>.status.jsonфиксирует фазу, результат и ошибки каждой попытки.
Что холодное резервное копирование НЕ гарантирует:
up()выполняется по принципу “наилучших усилий”. Он может завершиться неудачей по причинам, не зависящим от холодного резервного копирования (условиеdepends_on: service_healthyещё ожидает, синтаксическая ошибка в файле compose, временный сбой сети при загрузке образа). При сбое холодное резервное копирование логирует ошибку на уровне error, записывает файл-sidecar статуса и переходит к следующему репозиторию.- Если
up()завершается неудачей, активируется прямой запасной перезапуск: читается running-sidecar, и каждый записанный ID контейнера перезапускается напрямую через Docker API (без compose). Это возвращает сервисы в рабочее состояние даже при проблемах с compose-потоком, хотя без повторного выполнения хуков Rediaccfile. - Если даже запасной вариант не срабатывает для некоторых ID контейнеров (например, сам Docker daemon недоступен), sidecar остается на месте, чтобы watchdog маршрутизатора мог продолжать попытки при каждом тике.
Восстановление через watchdog: при каждом тике watchdog проверяет наличие running-sidecar. Любой ID контейнера из списка, который в данный момент остановлен, перезапускается независимо от сохраненного restart_policy контейнера. Это означает, что сервисы с restart: on-failure (которые Docker НЕ перезапустит после чистой остановки) всё равно восстанавливаются после холодного резервного копирования. Как только все перечисленные контейнеры запущены, sidecar удаляется.
Как операторы обнаруживают сбои:
rdc machine query --name <machine> --containersпоказывает состояние выполнения. Сравните с ожидаемым набором./var/run/rediacc/cold-backup-<guid>.status.jsonна машине. Проверьте черезrdc term connect -m <machine> -r <repo> -c "cat /var/run/rediacc/cold-backup-$GUID.status.json".success: falseс устаревшимstartedAtозначает, что последнее резервное копирование не завершилось корректно.- Логи запуска резервного копирования renet (
journalctl -u renet-*или прямой вызовrdc machine backup schedule) содержат итоговую строку видаCold backup: post-snapshot restart summary total=N compose_ok=N fallback_ok=N failed=N failed_repos=[...]. Непустойfailed_reposявляется целевым шаблоном для grep.
Оценка простоя при холодном резервном копировании
Каждый репозиторий остаётся недоступен только на время собственного окна down() + up(). На прогретом хосте эти значения обычно такие:
| Тип репозитория | Типичное время остановки+запуска |
|---|---|
| Малый (1-2 контейнера, без БД) | 5-15 с |
| Средний (веб-приложение + кэш) | 20-45 с |
| Тяжёлый (БД + очереди + почта) | 60-120 с |
Шаг снимка (btrfs subvolume snapshot -r) выполняется за O(1) независимо от размера репозитория: 0,1-1 с. Репозиторий не остаётся остановленным во время снятия снимков других репозиториев. Загрузчик затем работает с доступным только для чтения снимком, пока все репозитории уже снова запущены.
Общее время выполнения всего прогона определяется тем, сколько репозиториев перезапускается параллельно. renet выводит это значение из параметров хоста:
concurrency = min(repoCount, max(2, NumCPU/2), 8)
Примеры:
| Хост | Репозитории | Параллелизм | Время перезапуска |
|---|---|---|---|
| ВМ с 4 CPU | 5 репозиториев, в среднем 30 с каждый | 2 | ~75 с |
| Сервер с 16 CPU | 10 репозиториев, в среднем 40 с каждый | 8 | ~80 с |
| Узел флота с 64 CPU | 50 репозиториев, в среднем 40 с каждый | 8 | ~4 мин |
Переопределение через переменную окружения: установите REDIACC_COLD_BACKUP_CONCURRENCY=N в окружении сервиса резервного копирования (обычно через drop-in systemd), чтобы зафиксировать конкретное значение. Значение =1 принудительно включает строго последовательные перезапуски, что полезно при отладке цикла крашей в хуке up() одного из репозиториев.
Если у вас есть репозиторий, чувствительный к задержкам (публичное веб-приложение, почта), его простой ограничен собственным окном остановки+запуска (обычно 30-90 с), а не общей длительностью прогона. Репозитории распределяются по слотам параллелизма в порядке их обнаружения; очереди приоритетов нет. Разделите тяжёлые репозитории в отдельные стратегии с ограничением через --exclude, если нужна более тонкая настройка расписания.
Длительные резервные копии и перекрывающиеся расписания
Холодное резервное копирование, длящееся дольше собственного интервала расписания (например, первичный сид репозитория на 500 ГБ через умеренный канал может легитимно потребовать более 24 ч, в течение которых ночной таймер срабатывает снова), не ставит в очередь и не запускает второй прогон. Юнит systemd Type=oneshot является единственным экземпляром: когда таймер срабатывает, а сервис уже activating, systemd объединяет запуск с существующей задачей. Новый процесс не запускается, прогон не ставится в очередь на потом.
Конкретно, прогон, начатый в понедельник в 03:00 UTC и завершившийся в четверг в полдень:
| День | Срабатывание в 03:00 UTC | Результат |
|---|---|---|
| Понедельник | Первое срабатывание | Прогон начинается |
| Вторник | Второе срабатывание | Молча отброшено (предыдущий прогон всё ещё активен) |
| Среда | Третье срабатывание | Молча отброшено (предыдущий прогон всё ещё активен) |
| Четверг | Прогон завершается в полдень | Нет догона; следующий прогон в пятницу 03:00 UTC |
Директива Persistent=true таймера не спасает эти срабатывания. Persistent=true воспроизводит срабатывания, пропущенные потому, что сам таймер был неактивен (система выключена, таймер отключен). Срабатывания, отброшенные потому, что сервис был занят, теряются.
Это поведение по умолчанию преднамеренно. Запуск двух холодных резервных копий параллельно против одного и того же datastore будет конкурировать за путь снимка BTRFS, удалённое хранилище rclone и файлы-sidecars репозиториев в /var/run/rediacc/cold-backup-<guid>.status.json. Сериализация за длительным прогоном является безопасным исходом.
Следствия для мониторинга. Зависший бэкап (например, rclone, заклинивший на сетевой чёрной дыре) молча отбрасывает каждое последующее срабатывание таймера. Планировщик не выдаёт тревог. Следите за systemctl show <unit> -p ActiveEnterTimestamp: если сервис находится в состоянии activating дольше ожидаемой длительности прогона (например, более 48 ч на ночном таймере), проведите расследование.
Если вам нужно, чтобы каждое запланированное срабатывание выполнилось, переключите таймер с OnCalendar=<cron> на OnUnitInactiveSec=<интервал>. Это срабатывает через N часов после завершения предыдущего прогона вместо фиксированного расписания по настенным часам, так что длительные прогоны не вызывают потерь. Они просто смещают следующий прогон. Компромисс заключается в дрейфе расписания: ваш ночной 03:00 становится “24 ч после завершения последнего”.
Снимки, прерывания и пространство пула
Каждая операция push работает с моментальным снимком хранилища, поэтому загружаемые данные согласованы, даже пока репозитории продолжают выполнять запись. Пока идёт резервное копирование, этот снимок продолжает ссылаться на каждый блок, разделяемый с живыми репозиториями: удаления и операции trim освобождают меньше пространства в пуле до завершения цикла и удаления снимка. В отчёте о состоянии хранилища отображается, сколько пространства в данный момент удерживают снимки резервных копий.
Прерывания безопасны. Остановка службы (или перезагрузка машины) заставляет резервное копирование прервать передачу и удалить снимок перед завершением; следующий плановый запуск продолжит с того места, где остановился, поскольку неизменённые файлы пропускаются по контрольной сумме. Если процесс завершён слишком жёстко для выполнения очистки (отключение питания), осиротевший снимок обнаруживается и автоматически удаляется обслуживающей службой хранилища в течение нескольких минут.
Определение стратегии
Стандартная конфигурация по умолчанию разделяет на две стратегии: быстрый почасовой hot-поток, охватывающий каждый репозиторий, и более медленный еженедельный cold-поток, делающий согласованные на уровне приложения снимки. Две стратегии пишут в разные подпапки хранилища (hot/ и cold/), так что резервные копии никогда не смешиваются.
rdc config backup-strategy set \
--name hourly-hot \
--destination my-storage \
--cron "0 * * * *" \
--mode hot \
--bwlimit 20M \
--enable
rdc config backup-strategy set \
--name weekly-cold \
--destination my-storage \
--cron "15 3 * * 0" \
--mode cold \
--exclude very-large-repo \
--enable
Фильтр --exclude в cold-стратегии - рекомендуемый запасной вариант для очень больших репозиториев, не помещающихся в ваше еженедельное окно обслуживания. Почасовая hot-стратегия по-прежнему их охватывает; cold их просто пропускает. Имена репозиториев в --exclude совпадают с именем репозитория в локальной конфигурации (без :tag).
| Опция | Описание |
|---|---|
--name <name> | Имя стратегии (используется для привязки к машине) |
--destination <storage> | Провайдер хранилища для загрузки |
--cron <expression> | Cron-выражение (например, "0 2 * * *" для ежедневного запуска в 2 часа ночи) |
--mode <hot|cold> | Режим резервного копирования |
--bwlimit <limit> | Ограничение пропускной способности для загрузок (например, 10M) |
--include <pattern> | Фильтр включения (можно указывать несколько раз) |
--exclude <pattern> | Фильтр исключения (можно указывать несколько раз) |
--enable / --disable | Включить или отключить стратегию |
Просмотр стратегий
rdc config backup-strategy list
rdc config backup-strategy show --name weekly-cold
Удаление стратегии
rdc config backup-strategy remove --name weekly-cold
Привязка стратегий к машине
В конфигурации привяжите одно или несколько имен стратегий к машине:
{
"machines": {
"hostinger": {
"backupStrategies": ["hourly-hot", "weekly-cold"]
}
}
}
Привязка действует только в локальной конфигурации. Определение стратегии и её привязка к машине не вносят изменений на саму машину. Выполните
rdc machine backup schedule -m <machine>(см. Развертывание расписания на машине), чтобы развернуть таймеры systemd, и повторите команду после любого изменения стратегии или привязки.
Выбор горячего или холодного режима и фильтрация по репозиториям
Горячий и холодный: кратко
| Горячий | Холодный | |
|---|---|---|
| Согласованность | При сбое (снимок BTRFS во время работы) | На уровне приложения (остановка, снимок, запуск) |
| Простой | Отсутствует | Окно остановки+запуска для каждого репозитория (обычно 5-120 с) |
| Подходящая частота | Высокая (например, почасово) | Низкая (например, ежедневно или еженедельно) |
| Типичное использование | Частая страховочная сетка | Запланированное резервное копирование с гарантированной согласованностью |
Горячий - правильный выбор по умолчанию для высокочастотных прогонов. Сервисы продолжают работать во время снимка, поэтому окно резервного копирования не прерывает пользователей. Снимок согласован при сбое: он эквивалентен тому, что вы получите после некорректного выключения. Для большинства современных баз данных и очередей сообщений это приемлемо.
Холодный уместен, когда вам нужен гарантированный согласованный на уровне приложения снимок и вы можете принять кратковременный перезапуск репозитория. Сервисы останавливаются перед снимком и перезапускаются до начала загрузки, поэтому медленная или неудавшаяся загрузка никогда не продлевает окно простоя. Полную модель гарантий см. в разделе Семантика холодного резервного копирования.
Фильтрация репозиториев по стратегии
Каждая стратегия может содержать фильтры --include и --exclude. Репозитории, имена которых совпадают с шаблоном --exclude, пропускаются для этой стратегии; --include ограничивает прогон только этими именами. Фильтры совпадают с именем репозитория в локальной конфигурации (без :tag).
# Горячая стратегия: резервное копирование всего ежечасно
rdc config backup-strategy set \
--name hourly-hot \
--destination my-storage \
--cron "0 * * * *" \
--mode hot \
--bwlimit 6M \
--enable
# Холодная стратегия: резервное копирование всего еженедельно, исключая большой производный набор данных
rdc config backup-strategy set \
--name weekly-cold \
--destination my-storage \
--cron "15 3 * * 0" \
--mode cold \
--exclude analytics-demo \
--enable
Когда исключать репозиторий из частой горячей стратегии
Исключите репозиторий из высокочастотного прогона, если:
- Репозиторий большой и полностью воспроизводим из исходных данных, уже находящихся на томе, поэтому каждая почасовая резервная копия расходует значительную полосу пропускания без ощутимой ценности для восстановления.
- Прогон резервного копирования превысит собственный интервал расписания при доступной скорости загрузки.
Пример. Репозиторий analytics-demo содержит около 114 ГБ производных таблиц Postgres, которые можно полностью пересоздать из необработанных CSV-файлов, уже хранящихся на том же томе. При ограничении загрузки 6 МБ/с одна горячая резервная копия этого репозитория занимает более 5 часов. Ежечасный запуск означает, что каждый прогон всё ещё выполняется, когда запускается следующий, что приводит к молчаливому сбросу каждого последующего прогона (см. Длительные резервные копии и перекрывающиеся расписания). Исключение из hourly-hot и сохранение в weekly-cold означает, что резервное копирование выполняется раз в неделю, а не никогда.
Если данные полностью воспроизводимы, подумайте, нужно ли вообще делать их резервную копию. Альтернатива: создавать резервную копию только необработанных исходных данных (CSV-файлов в данном примере) и полностью пропустить производную копию. Еженедельная холодная резервная копия исходных данных намного меньше и полностью достаточна для восстановления.
Репозитории, не исключённые ни из одной стратегии, отображаются как в подпапке hot/, так и в cold/. Объединённый вывод rdc repo backup list показывает обе строки, чтобы вы могли проверить, какие потоки покрывают какие репозитории.
Операции резервного копирования
Развертывание расписания на машине
Отправьте привязанные стратегии на машину в виде systemd-таймеров:
rdc machine backup schedule -m server-1
rdc machine backup schedule -m server-1 --dry-run
Развёртывание является реконсилятором состояния. Оно читает текущие юнит-файлы и состояние systemd на машине, сравнивает их с тем, что произвела бы конфигурация (SHA-256 на файл), и трогает только те юниты, содержимое которых действительно изменилось. Повторный запуск без изменений конфигурации не производит действий: нет записей, нет daemon-reload, нет колебаний таймеров.
--dry-run печатает план для каждой стратегии (created, updated (service, timer, env), unchanged, removed), не трогая машину. В сочетании с --debug также печатаются сгенерированные тела юнитов; токены rclone редактируются.
Если для стратегии, которую вы собираетесь обновить или удалить, в настоящий момент выполняется резервное копирование, развёртывание завершается с ошибкой, предлагая отменить его или передать --force. С --force выполняющийся вызов сохраняет свой юнит в памяти, а новая конфигурация применяется при следующем срабатывании таймера, поэтому выполняющееся резервное копирование никогда не прерывается принудительно.
--reset-failed является опциональным флагом. Когда он передан, после успешного развёртывания сбрасывается состояние failed на затронутых сервисах. По умолчанию выключен, чтобы предыдущие сигналы об ошибках оставались видимыми для оповещений.
Запуск резервного копирования сейчас
Запустить резервное копирование немедленно, не дожидаясь таймера. Работает даже без развернутых таймеров, используя systemd-run для разовых запусков:
rdc machine backup now -m server-1
rdc machine backup now -m server-1 --strategy weekly-cold
Просмотр статуса резервного копирования
Отображает текущий статус таймеров резервного копирования и результаты последних задач:
rdc machine backup status -m server-1
rdc machine backup status -m server-1 --strategy hourly-hot
Отмена выполняющегося резервного копирования
rdc machine backup cancel -m server-1
rdc machine backup cancel -m server-1 --strategy weekly-cold
Миграция репозитория
Перенос репозитория с одной машины на другую:
rdc repo migrate --name my-app --from server-1 --to server-2
| Опция | Описание |
|---|---|
--name <repo> | Репозиторий для миграции |
--from <machine> | Исходная машина |
--to <machine> | Целевая машина |
--provision | Подготовить репозиторий на целевой машине перед переносом |
--checkpoint | Создать контрольную точку CRIU перед миграцией |
--skip-dns | Пропустить обновление DNS-записей после миграции |
--bwlimit <limit> | Ограничение пропускной способности для передачи (например, 50M) |
Миграция передает зашифрованные данные репозитория через rsync. Исходный репозиторий остается нетронутым, пока вы явно его не удалите.
Обзор хранилища
Просмотрите содержимое хранилища:
rdc storage browse --name my-storage
Лучшие практики
- Настройте ежедневное холодное резервное копирование для согласованных на уровне приложения снимков критически важных данных
- Используйте горячее резервное копирование для высокочастотных снимков с нулевым временем простоя
- Периодически проверяйте восстановление для подтверждения целостности резервных копий
- Используйте несколько провайдеров хранилищ для критически важных данных (например, S3 + B2)
- Храните учетные данные в безопасности; резервные копии зашифрованы, но для восстановления требуются учетные данные LUKS