Кнопка снапшота в панели — самая используемая функция нашего личного кабинета и одновременно самая непонятая. Снапшот — это ремень безопасности: он спасает от вашей же следующей команды. Он хранится на том же хосте, что и сервер, поэтому не спасёт, если вы потеряете хост, площадку или аккаунт. Ниже — рекомендуемый нами трёхуровневый план с рецептом на restic, который обходится в несколько долларов в месяц, и ежемесячная проверка, которая превращает всё это в резервную копию, а не в надежду.
Три уровня, три вида сбоев
| Уровень | Защищает от | Не защищает от | Время восстановления |
|---|---|---|---|
| Снапшот в панели | неудачного обновления, ошибочного rm, сломанной конфигурации | потери хоста, потери площадки, компрометации аккаунта | от 2 до 5 минут |
| Внешний репозиторий restic | всего перечисленного выше, а также потери хоста и площадки | злоумышленника, который с вашим ключом restic удалит репозиторий | минуты для файлов, час на полное восстановление |
| Вторая копия у другого провайдера, только на добавление (append-only) | всего перечисленного выше, а также скомпрометированного сервера | потери обоих ключей | то же, но из более «холодного» хранилища |
Уровень первый: снапшоты, используемые с умом
Делайте снапшот перед каждым обновлением или рискованным изменением; снапшоты инкрементальные и создаются быстро. Храните два-три скользящих, а не тридцать: снапшот — это состояние на момент времени на том же NVMe, а старые снапшоты — просто занятое место на диске, за которым нужно следить. Восстановление откатывает весь диск целиком, поэтому всё, что было записано после снапшота, пропадает, включая строки в базе данных. Именно это и нужно при неудачном обновлении, но совсем не то, что нужно от «резервной копии на прошлый вторник».
Уровень второй: restic во внешний бакет
restic дедуплицирует данные, шифрует их на стороне клиента и работает с любым S3-совместимым бакетом. Подойдёт любое объектное хранилище; для сервера CheapServ во Франкфурте идеален бакет в европейском регионе другого провайдера. Установка и инициализация:
apt install -y restic
cat > /etc/restic.env <<'EOF'
export RESTIC_REPOSITORY=s3:https://s3.example-storage.com/backup-web01
export RESTIC_PASSWORD=long-random-passphrase-stored-in-your-password-manager
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
EOF
chmod 600 /etc/restic.env && . /etc/restic.env
restic init
Копируйте файлы вместе с дампом базы данных, а затем по расписанию удаляйте устаревшие копии (prune):
cat > /usr/local/bin/backup.sh <<'EOF'
#!/bin/bash
set -euo pipefail
. /etc/restic.env
mkdir -p /var/backups/db
sudo -u postgres pg_dumpall --clean | gzip > /var/backups/db/pg-$(date +%u).sql.gz
restic backup /etc /srv /var/backups/db /home --exclude-caches --exclude '/srv/**/node_modules' --tag daily
restic forget --keep-daily 14 --keep-weekly 8 --keep-monthly 12 --prune
restic check --read-data-subset=5%
EOF
chmod +x /usr/local/bin/backup.sh
systemd-run --on-calendar='03:15' --unit=restic-backup /usr/local/bin/backup.sh # or a proper timer unit
Три важные детали: делайте дамп базы данных, а не копируйте её файлы (файловая копия работающего PostgreSQL не будет согласованной); --exclude-caches и правило для node_modules не дают репозиторию разрастаться; а restic check --read-data-subset каждую ночь перечитывает часть данных, чтобы повреждения нашлись раньше, чем понадобится восстановление.
Типичный веб-сервер после дедупликации даёт от 1 до 5 GB уникальных данных в месяц. По ценам объектных хранилищ это намного меньше доллара; весь этот уровень обходится дешевле чашки кофе.
Уровень третий: копия, которую сервер не может удалить
Если злоумышленник получит root, ему достанется /etc/restic.env, и он сможет выполнить restic forget --prune над вашей единственной резервной копией. Есть два решения: выдать ключу сервера права только на запись в бакет (большинство провайдеров поддерживают политику без DeleteObject) либо запускать restic copy с отдельной машины во второй репозиторий, ключ от которого сервер никогда не видит. VPS-1 за $3 на другой площадке, который каждую ночь забирает данные со своими учётными данными, — вполне хороший третий уровень.
Ежемесячная проверка
Непроверенная резервная копия — это надежда. Раз в месяц, по напоминанию в календаре:
- Разверните в панели временный VPS-1 (минута времени, несколько центов с баланса).
- Установите restic, скопируйте
/etc/restic.env, выполнитеrestic restore latest --target /restore. - Загрузите дамп базы данных в чистый PostgreSQL и выполните один настоящий запрос; откройте один из восстановленных файлов.
- Запишите, сколько это заняло. Эта цифра и есть ваше реальное время восстановления.
- Удалите временный сервер.
В первый раз проверка обязательно что-нибудь найдёт: забытый путь, пустой дамп (у пользователя cron не хватило прав), исключённый каталог, который оказался важным. Это значит, что проверка работает. Исправьте найденное, и второй месяц будет скучным.
Чего делать не стоит
- Не храните единственную резервную копию на том же сервере, в
/backups. Она погибнет вместе с диском. - Не копируйте работающие файлы базы данных через rsync. Делайте дамп.
- Не храните парольную фразу restic только на сервере. Если сервера не станет, пропадёт и ключ от резервной копии.
- Не копируйте всё подряд. Образы в
/var/lib/docker, кэши и архивы пакетов воспроизводимы; сохраняйте данные и конфигурацию, из которых они собираются.
Когда все три уровня на месте, худший случай — исчезнувший сервер — превращается в полдня работы, а не в катастрофу, способную погубить компанию. Со всем остальным, что случается в течение недели, справится снапшот в панели.
