Что защищает эта конфигурация резервного копирования
План резервного копирования рабочей среды должен соответствовать принципу 3-2-1: храните как минимум три копии данных, размещайте их на двух типах носителей и храните одну копию в другом месте. Для выделенного сервера рабочий сервер является одной копией, локальная промежуточная среда или снимки могут быть второй копией, а зашифрованное объектное хранилище в другом местоположении — копией вне площадки.
В этом руководстве настраивается Restic, поскольку он шифрует данные перед загрузкой, устраняет дубликаты неизменившихся файлов, поддерживает политики хранения и может восстанавливать отдельные файлы или полное дерево каталогов. Конфигурация подходит для веб-хостинга, самостоятельно размещаемых приложений, игровых серверов, баз данных, исполнителей CI/CD, систем мониторинга, VPN-шлюзов, почтовых серверов и медиасервисов.
Резервные копии файлов Restic автоматически не обеспечивают согласованность приложений. Файлы баз данных PostgreSQL или MySQL необходимо резервировать с помощью штатных инструментов создания дампов или согласованных снимков. В этом руководстве перед запуском Restic создаётся дамп PostgreSQL.
Предварительные требования и минимальные требования к серверу
- Выделенный сервер под управлением Ubuntu 22.04 или Ubuntu 24.04 с доступом root или sudo.
- Минимальная конфигурация исходного производственного сервера: 4 vCPU, 8 ГБ ОЗУ и 240 ГБ NVMe-накопителя.
- Бакет объектного хранилища, совместимого с S3, в отдельной от сервера зоне отказа.
- Ключ доступа, ограниченный резервным бакетом; не используйте учётные данные хранилища с правами на весь аккаунт.
- В удалённом бакете должно быть достаточно места минимум для 30 дней предполагаемого хранения резервных копий.
- Доступ по исходящему HTTPS с выделенного сервера к конечной точке объектного хранилища.
Используйте VPS для небольшого веб-сайта с одним сервисом или лёгкого стека мониторинга. Выбирайте выделенный сервер для наборов данных объёмом в несколько терабайт, загруженных баз данных, больших парков игровых серверов, почтового хранилища, постоянной загрузки резервных копий или рабочих нагрузок, требующих предсказуемой дисковой производительности и изоляции CPU.
Определите размер сервера и репозитория резервных копий
Планируйте объём удалённого объектного хранилища с учётом первоначальной полной резервной копии, ежедневных изменений, сохраняемых снимков и дампов баз данных. Дедупликация может значительно сократить использование хранилища, но базы данных и сжатые медиафайлы часто плохо поддаются дедупликации. Перед выбором объёма измерьте текущий объём данных с помощью sudo du -sh /etc /home /srv /var/www 2>/dev/null.
Используйте следующие начальные производственные значения; увеличьте объём удалённого хранилища, если сохраняемые данные изменяются более чем на 5% в день.
| Активные защищаемые данные | vCPU | ОЗУ | Диск | Месячный трафик |
|---|---|---|---|---|
| До 100 ГБ | 4 vCPU | 8 ГБ | 240 ГБ локального NVMe-диска + 1 ТБ удалённого объектного хранилища | 300 ГБ |
| От 100 ГБ до 1 ТБ | 8 vCPU | 16 ГБ | 480 ГБ локального NVMe-диска + 4 ТБ удалённого объектного хранилища | 2 ТБ |
| От 1 ТБ до 5 ТБ | 12 vCPU | 32 ГБ | 1,92 ТБ локального NVMe-диска + 20 ТБ удалённого объектного хранилища | 8 ТБ |
Объём диска включает место для операционной системы, журналов, данных приложений и временных дампов баз данных; удалённое хранилище является отдельным и не должно монтироваться как рабочая файловая система.
1. Установите Restic и инструменты для работы с базами данных
Обновите метаданные пакетов и установите Restic, клиентские утилиты PostgreSQL и curl. Удалите postgresql-client из команды, если сервер не использует PostgreSQL.
sudo apt update
sudo apt install -y restic postgresql-client curl
restic versionУбедитесь, что Restic выводит номер версии. В приведённых ниже командах предполагается, что резервные данные хранятся в совместимом с S3 бакете с именем server-backups и префиксом prod-01. Замените конечную точку, бакет, имя базы данных и пути на собственные значения.
2. Создайте ограниченные учётные данные для резервного копирования
Создайте отдельный бакет для резервных копий, включите версионирование бакета, если оно доступно, и создайте ключ доступа с ограничением на этот бакет. Ключ должен иметь разрешения на перечисление, чтение, запись и удаление объектов в пределах префикса репозитория, поскольку очистка хранения Restic удаляет устаревшие файлы pack.
Храните пароль репозитория Restic отдельно от учётных данных объектного хранилища. Если пароль будет утрачен, зашифрованные резервные копии восстановить невозможно. Сохраните его в автономном менеджере паролей и храните аварийную копию в соответствии с процессом контроля доступа вашей организации.
sudo install -d -m 0700 /root/.config/restic
sudo sh -c 'umask 077; openssl rand -base64 48 > /root/.config/restic/password'Создайте файл окружения, содержащий расположение репозитория и учётные данные хранилища. Используйте фактическую конечную точку S3, предоставленную вашим сервисом хранения.
sudo tee /root/.config/restic/backup.env > /dev/null <<'EOF'
export RESTIC_REPOSITORY='s3:https://s3.example.net/server-backups/prod-01'
export RESTIC_PASSWORD_FILE='/root/.config/restic/password'
export AWS_ACCESS_KEY_ID='REPLACE_WITH_RESTRICTED_ACCESS_KEY'
export AWS_SECRET_ACCESS_KEY='REPLACE_WITH_RESTRICTED_SECRET_KEY'
export AWS_DEFAULT_REGION='us-east-1'
EOF
sudo chmod 0600 /root/.config/restic/backup.envДля пользовательской конечной точки, требующей определённого региона или параметров подписи, используйте значения, необходимые этому сервису объектного хранения. Никогда не размещайте этот файл в общедоступном репозитории Git или в каталоге развёртывания приложения.
3. Инициализируйте и проверьте зашифрованный репозиторий
Загрузите окружение и один раз инициализируйте репозиторий. Restic создаёт зашифрованные метаданные и ключевой материал в удалённом расположении.
sudo bash -c 'source /root/.config/restic/backup.env && restic init'
sudo bash -c 'source /root/.config/restic/backup.env && restic snapshots'Первая команда должна сообщить, что репозиторий инициализирован. Вторая команда обычно не возвращает снимков, пока не завершится первая резервная копия. Если инициализация завершается ошибкой, проверьте разрешение DNS-имён, исходящий трафик через TCP-порт 443 в брандмауэре, написание конечной точки, разрешения бакета и системные часы.
4. Создайте скрипт резервного копирования с дампом PostgreSQL
Скрипт создаёт временный дамп PostgreSQL, записывает установленные пакеты, а затем выполняет резервное копирование выбранных системных каталогов и каталогов приложений. Он не копирует изменчивые каталоги, такие как /proc, /sys, /dev или временные кэши.
Замените appdb именем базы данных, используемой вашим приложением. Если PostgreSQL находится на удалённом сервере, замените локальную команду sudo -u postgres на ограниченную учётную запись базы данных и защищённый файл .pgpass.
sudo tee /usr/local/sbin/restic-backup.sh > /dev/null <<'EOF'
#!/usr/bin/env bash
set -Eeuo pipefail
source /root/.config/restic/backup.env
WORKDIR=$(mktemp -d /var/backups/restic.XXXXXX)
trap 'rm -rf "$WORKDIR"' EXIT
dpkg-query -W -f='${binary:Package}\t${Version}\n' > "$WORKDIR/packages.tsv"
sudo -u postgres pg_dump -Fc --no-owner appdb > "$WORKDIR/appdb.dump"
PATHS=()
for path in /etc /home /srv /var/www "$WORKDIR"; do
[ -e "$path" ] && PATHS+=("$path")
done
restic backup \
--tag dedicated-server \
--tag nightly \
--exclude /home/*/.cache \
--exclude /var/www/*/cache \
"${PATHS[@]}"
EOF
sudo chmod 0700 /usr/local/sbin/restic-backup.shДля рабочих нагрузок Docker создавайте резервные копии файлов Compose, файлов окружения, экспортов именованных томов и дампов баз данных, а не копируйте активно изменяющиеся файлы томов баз данных. Для MySQL или MariaDB используйте mariadb-dump --single-transaction для баз данных InnoDB. Для игровых серверов остановите игру или сохраните мир перед резервным копированием, если игра не умеет безопасно сбрасывать файлы во время работы.
5. Запустите первую резервную копию вручную
Перед автоматизацией запустите скрипт вручную. Первая резервная копия загружает все выбранные данные и может занять несколько часов на серверах с несколькими терабайтами данных.
sudo /usr/local/sbin/restic-backup.sh
sudo bash -c 'source /root/.config/restic/backup.env && restic snapshots --tag dedicated-server'
sudo bash -c 'source /root/.config/restic/backup.env && restic stats latest'Проверьте сводку снимка и убедитесь, что ожидаемые каталоги и дамп базы данных присутствуют. Снимки Restic показывают как исходный размер файлов, так и объём новых загруженных данных после дедупликации.
6. Добавьте хранение и проверки целостности
Распространённая политика хранения предусматривает 7 ежедневных, 4 еженедельных и 12 ежемесячных точек восстановления. Это обеспечивает недавние точки восстановления и сохраняет историю за год. Запускайте prune только после forget; очистка освобождает неиспользуемое удалённое хранилище.
sudo tee /usr/local/sbin/restic-maintenance.sh > /dev/null <<'EOF'
#!/usr/bin/env bash
set -Eeuo pipefail
source /root/.config/restic/backup.env
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune
restic check
EOF
sudo chmod 0700 /usr/local/sbin/restic-maintenance.sh
sudo /usr/local/sbin/restic-maintenance.shЗапустите обслуживание после создания первого успешного снимка. Если в бакете включено хранение с блокировкой объектов, настройте его на период, соответствующий или превышающий требуемый период хранения; в противном случае Restic может не суметь удалить устаревшие данные во время очистки.
7. Запланируйте резервное копирование с помощью таймеров systemd
Таймеры systemd обеспечивают ведение журналов, обработку пропущенных запусков и понятный статус служб. В этой конфигурации резервное копирование запускается каждую ночь в 02:15 с добавлением случайной задержки до 20 минут. Еженедельное обслуживание выполняется по воскресеньям в 04:30.
sudo tee /etc/systemd/system/restic-backup.service > /dev/null <<'EOF'
[Unit]
Description=Restic encrypted dedicated server backup
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/restic-backup.sh
Nice=10
IOSchedulingClass=best-effort
EOF
sudo tee /etc/systemd/system/restic-backup.timer > /dev/null <<'EOF'
[Unit]
Description=Nightly Restic backup timer
[Timer]
OnCalendar=*-*-* 02:15:00
RandomizedDelaySec=20m
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo tee /etc/systemd/system/restic-maintenance.service > /dev/null <<'EOF'
[Unit]
Description=Restic retention and repository check
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/restic-maintenance.sh
Nice=15
IOSchedulingClass=idle
EOF
sudo tee /etc/systemd/system/restic-maintenance.timer > /dev/null <<'EOF'
[Unit]
Description=Weekly Restic maintenance timer
[Timer]
OnCalendar=Sun *-*-* 04:30:00
RandomizedDelaySec=30m
Persistent=true
[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer restic-maintenance.timer
systemctl list-timers --all | grep restic8. Каждый месяц проверяйте восстановление
Резервная копия полезна только в том случае, если её можно корректно восстановить. Восстановите последний снимок в отдельный каталог, сравните конфигурационные файлы и проверьте дамп базы данных. Во время теста не восстанавливайте данные непосредственно поверх рабочих файлов.
sudo mkdir -p /restore-test
sudo bash -c 'source /root/.config/restic/backup.env && restic restore latest --target /restore-test'
sudo diff -qr /etc /restore-test/etc | head -50
sudo -u postgres createdb restore_test
sudo -u postgres pg_restore --clean --if-exists --no-owner -d restore_test /restore-test/var/backups/restic.*/appdb.dumpИмя временного каталога внутри восстановленного пути меняется, поскольку скрипт использует mktemp. Найдите дамп с помощью sudo find /restore-test -name appdb.dump перед запуском pg_restore. После проверки удалите тестовую базу данных и каталог восстановления.
sudo -u postgres dropdb restore_test
sudo rm -rf /restore-testУстранение распространённых сбоев резервного копирования
Репозиторий заблокирован
Прерванный процесс может оставить блокировку. Сначала убедитесь, что задание резервного копирования или обслуживания не выполняется, с помощью systemctl status restic-backup.service restic-maintenance.service. Если активных процессов нет, удалите устаревшие блокировки с помощью sudo bash -c 'source /root/.config/restic/backup.env && restic unlock'.
Отказано в доступе при чтении файлов приложения
Запускайте службу резервного копирования от имени root, но разрешите чтение учётных данных только пользователю root. Проверьте недоступные пути с помощью sudo journalctl -u restic-backup.service -n 100 --no-pager. Добавляйте в скрипт только необходимые каталоги, а не выполняйте резервное копирование всей корневой файловой системы.
Не удаётся создать дамп базы данных
Проверьте существование базы данных и работу PostgreSQL с помощью команд sudo systemctl status postgresql и sudo -u postgres psql -l. Для больших баз данных убедитесь, что объём свободного места на локальном диске превышает ожидаемый размер дампа до начала окна резервного копирования.
Резервное копирование выполняется медленно или потребляет слишком много трафика
Запланируйте таймер вне периода пиковой нагрузки, используйте показанные параметры планирования ввода-вывода Nice=10 и best-effort, а также исключите кэши, которые можно пересоздать. Проверьте скорость загрузки с помощью curl -o /dev/null https://speed.hetzner.de/100MB.bin только если эта тестовая конечная точка доступна из вашей сети; в противном случае измеряйте трафик с помощью iftop или мониторинга провайдера.
Очистка не уменьшает удалённое хранилище сразу
Версионируемые бакеты сохраняют старые версии объектов до тех пор, пока их не удалит политика жизненного цикла. Проверьте настройки версионирования и жизненного цикла в консоли хранилища, затем рассчитывайте объём хранилища с учётом хранения как текущих, так и неактуальных версий объектов.