MAATRIX / Блог / Восстановление виртуалки из образа: репетиция аварии

Восстановление виртуалки из образа: репетиция аварии

MAATRIX

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

Бэкап, который никогда не восстанавливали, — это не бэкап

Задание бэкапа, которое каждую ночь отчитывается «успешно завершено», создаёт ложное чувство защищённости. Отчёт о завершении говорит только одно: процесс дошёл до конца и не упал с ошибкой. Он ничего не говорит о том, что можно ли из этого архива поднять рабочую машину. Это тот же принцип, что и с мониторингом, за которым никто не следит: система формально работает, метрики собираются, но пока никто не смотрит на графики и не проверяет алерты руками, вы не знаете, действительно ли она вас защищает.

С бэкапами то же самое, только опаснее — ошибку в мониторинге вы обнаружите на живой системе почти сразу, а битый бэкап вскрывается только в момент восстановления, то есть когда оригинала уже нет. Мы подробно разбирали, как настраивается и восстанавливается Proxmox Backup Server — но настройка PBS решает только первую половину задачи. Вторая половина — систематически проверять, что записанное действительно поднимается обратно, а это отдельная дисциплина, которую легко пропустить, потому что она не даёт немедленной отдачи: всё и так вроде работает.

Репетиция восстановления — это не разовая проверка «после установки бэкапа один раз потренировались и записали в вики». Это периодическая практика, которая должна повторяться на протяжении всей жизни системы, и вот почему.

Что именно ломается со временем и почему разовой проверки недостаточно

Есть два независимых источника риска, и оба усиливаются именно временем, а не разовым фактом настройки.

Первый — дрейф конфигурации. Процедура восстановления, которая работала полгода назад, описывает систему полугодовой давности. За это время на сервере могли поменяться: схема разделов и точки монтирования, сетевые интерфейсы (имена вида ens18 превращаются в ens19 при смене виртуального железа), список systemd-юнитов, которые должны стартовать автоматически, secrets и токены доступа к внешним сервисам, DNS и hosts-записи, от которых зависит приложение. Инструкция «восстановили образ, подождали загрузки, всё само поднялось» перестаёт быть правдой незаметно — до тех пор, пока кто-то не пройдёт её шаг за шагом на свежем восстановлении.

Второй, более коварный — сам механизм бэкапа может сломаться, продолжая рапортовать об успехе. Несколько реальных сценариев:

  • Хранилище бэкапов заполнилось, ротация начала удалять старые архивы быстрее, чем создаются новые, и на сторадже остаётся только частично записанный последний бэкап — задание при этом завершается кодом 0, потому что с точки зрения демона бэкапа всё прошло штатно.
  • Сменились или истекли учётные данные доступа к целевому хранилищу (S3-ключ, токен PBS, пароль NFS-шары) — часть заданий начала молча писать в fallback-локацию с меньшим местом, а мониторинг диска на самой VM это не видит: он смотрит на свой раздел, а не на то, куда реально долетают чанки.
  • Обновление клиента бэкапа изменило формат метаданных, и часть VM в задании тихо пропускается («no such device», проглоченное в логе debug-уровня), пока остальные бэкапятся нормально и зелёный статус всего задания маскирует единичный сбой.
  • Дедупликация в PBS ссылается на чанк, физически повреждённый на диске хранилища (bit rot) — проверка контрольных сумм запускается не при каждой записи, а по расписанию verify job, и до этого момента повреждение никак не проявляется.

Единственный способ поймать все эти сценарии раньше реальной аварии — не читать логи бэкапа, а физически восстановить машину и включить её. Проверка «файл архива существует и весит не ноль байт» не ловит ни один из перечисленных случаев: усечённый архив тоже может весить прилично, а поврежденный чанк в дедуплицированном хранилище обнаруживается только при попытке собрать из него диск целиком.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Изолированный полигон: где репетировать, не трогая продакшн

Первая практическая ошибка — тестировать восстановление там же, где крутится оригинал, «просто подняв вторую VM рядом». Если копия получит тот же IP, имя хоста или MAC и окажется в одной L2-сети с оригиналом, вы рискуете получить конфликт адресов, а кластерные сервисы (Galera, Redis Sentinel, Corosync) внезапно увидят «двойника» и начнут странно себя вести.

Правильная схема — отдельный изолированный контур для восстановления:

  • Отдельный узел или отдельный кластер Proxmox, не связанный по сети с продакшном напрямую. Если у вас уже есть кластер Proxmox из двух узлов для продакшна, тестовый полигон должен быть третьей, физически отдельной единицей — не нодой того же кластера, иначе она попадает в тот же кворум и общие настройки хранилищ.
  • Если отдельного железа нет, минимум — изолированный виртуальный мост (vlan-aware bridge) без выхода в продакшн-сеть, например отдельный vmbr1 без физического аплинка или с портом в отдельный VLAN, который никуда не маршрутизируется в сторону боевых серверов.
  • В сети восстановления меняйте IP и/или отключайте автозапуск сетевых интерфейсов сразу после старта, до того как приложение успеет что-то разослать во внешний мир (уведомления, вебхуки, задания cron, которые могут задвоить реальные операции — отправку писем клиентам, платёжные коллбэки и т.п.).
  • Если тестируете VM с базой данных, которая реплицируется в продакшн-кластер, отключайте репликацию и роль master/replica до проверки, чтобы копия не начала писать в тот же репликационный поток, что и оригинал.

Быстрый вариант без отдельного железа — временный изолированный мост прямо на существующем узле:

# создаём изолированный мост без физического порта
auto vmbr99
iface vmbr99 inet manual
    bridge-ports none
    bridge-stp off
    bridge-fd 0
# восстановленной VM подключаем сетевой интерфейс именно в этот мост
qm set 9101 -net0 virtio,bridge=vmbr99

Так машина полностью в сети, но физически не может достучаться ни до продакшна, ни наружу, пока вы сами не откроете нужный проброс для конкретной проверки (например, временный NAT только на один порт приложения).

Пошаговая методика: от последнего бэкапа до включённой машины

Ключевой принцип — брать реальный последний доступный бэкап, а не заранее подготовленный «удобный» архив. Смысл репетиции именно в том, чтобы проверить то состояние резервной копии, которое было бы использовано в настоящей аварии сегодня.

  1. Определить, какой бэкап реально «последний». В PBS это делается через список снапшотов датастора:
proxmox-backup-client snapshot list --repository backup@pbs@10.0.0.5:store1

Берём самый свежий снапшот нужной VM — не тот, который «должен был отработать», а тот, который реально есть в хранилище.

  1. Восстановить полностью, на изолированный узел, тем же инструментом и с теми же правами, которыми будет пользоваться дежурный в реальной аварии:
qmrestore /mnt/pbs/dump/vzdump-qemu-9101-2026_08_20-03_00_01.vma.zst 9199 \
  --storage local-lvm

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

  1. Подключить восстановленную VM только к изолированной сети (см. предыдущий раздел), сменить IP на тестовый диапазон, при необходимости — прописать нужные hosts-записи локально, чтобы приложение резолвило свои зависимости (базу, кэш, очередь) на тестовые адреса, а не на продакшн.
  1. Запустить VM и зафиксировать время старта — это отправная точка для замера RTO, о котором ниже.
  1. Пройти по списку критичных сервисов и проверить каждый функционально, а не по факту загрузки ОС — следующий раздел про это отдельно.
  1. Задокументировать расхождения: если какой-то шаг потребовал ручного вмешательства, которого не было в инструкции («пришлось руками поправить fstab», «не стартовал nginx из-за отсутствующего сертификата»), это и есть находка репетиции — то, что нужно исправить в процедуре или автоматизации до следующей аварии, а не забыть сразу после теста.

Проверка не «загрузилась ОС», а «сервисы реально работают»

Самая частая профанация репетиции — «восстановили, увидели логин-промпт по SSH, отчитались, что тест пройден». Загрузка ядра и получение SSH-доступа — необходимое, но абсолютно недостаточное условие. Реальная проверка должна доходить до уровня конкретной бизнес-функции.

Практический чек-лист для типичного веб-сервиса на VM:

Уровень проверкиНедостаточноДостаточно
ОСping отвечаетsystemctl is-active для всех юнитов из списка обязательных
База данныхпроцесс postgres/mysqld запущенSELECT count(*) FROM users; возвращает ожидаемое число строк, а не 0 или ошибку
Приложениепорт слушается (ss -tlnp)HTTP-запрос к реальному эндпоинту отдаёт 200 и корректные данные, а не заглушку/500
Очереди/кэшRedis отвечает на PINGобработчик очереди реально разбирает тестовое задание, положенное в очередь во время теста
Внешние интеграцииесли сервис по протоколу должен слать вебхуки — они уходят на тестовый приёмник, а не молчат

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

# не просто "активен", а реально принимает подключения и отвечает данными
psql -h 127.0.0.1 -U app -d app -c "SELECT count(*) FROM orders WHERE created_at > now() - interval '1 day';"

curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/api/health/deep

redis-cli -h 127.0.0.1 ping

Обратите внимание на /api/health/deep — если в приложении нет отдельного «глубокого» health-check эндпоинта, который реально дёргает базу и внешние зависимости, а не просто отвечает 200 OK статикой, стоит завести его именно ради подобных репетиций (и заодно ради обычного мониторинга). Поверхностный health-check, который отвечает «ОК» даже с отвалившейся базой, — тот же самый антипаттерн ложного зелёного статуса, что и с самим бэкапом.

Замер реального RTO вместо теоретических оценок

RTO (recovery time objective, целевое время восстановления) часто существует только на бумаге — как оценка «ну, наверное, за час управимся» — до тех пор, пока его никто не засекал секундомером на реальном восстановлении. Разница между теоретической оценкой и фактическим временем может быть в разы: теория не учитывает ни скорость скачивания архива по сети, ни ручные шаги, которые не задокументированы, ни поиск токена доступа, который кто-то сменил и забыл обновить в инструкции.

Что именно измерять и фиксировать при каждой репетиции:

  • Время от команды qmrestore/pve-qm-restore до её завершения — это фактическая скорость восстановления данных с учётом реальной сети и дисков хранилища бэкапов.
  • Время от старта VM до момента, когда ОС готова принимать SSH.
  • Время от готовности ОС до момента, когда последний из критичных сервисов проходит функциональную проверку — часто самый долгий и самый недооценённый интервал, потому что в него попадают ручные шаги: правка конфигов под новое окружение, восстановление секретов, прогрев кэшей.
  • Суммарное время от «объявили аварию» до «сервис снова принимает трафик» — это и есть честный RTO для конкретной системы.

Стоимость каждой минуты этого простоя стоит оценивать заранее и в конкретных цифрах для своего бизнеса — мы разбирали методику такого расчёта в статье про стоимость минуты простоя интернет-магазина. Замеренный RTO, сопоставленный с этой стоимостью, — единственный способ понять, оправдана ли текущая архитектура бэкапа, или для критичной системы нужен более быстрый путь восстановления (например, готовый резервный узел с горячим standby вместо восстановления из холодного архива).

Если у вас ещё нет ни одного замера, не выдумывайте цифру RTO «на глаз» — честнее сказать себе и руководству «мы пока не знаем реальное время восстановления» и запланировать первую репетицию, чем оперировать красивой, но непроверенной оценкой в час, которая на практике может обернуться сутками.

Периодичность: как не забросить репетицию после первого раза

Разовая репетиция «на старте, для галочки» устаревает ровно с той скоростью, с которой меняется система — а меняется она почти всегда быстрее, чем кажется. Практический ориентир по частоте, от которого можно отталкиваться и адаптировать под свою критичность:

  • Некритичные вспомогательные системы (внутренние dev/staging-стенды, тестовые окружения) — репетиция раз в полгода–год достаточна: цена простоя невелика, а изменения происходят реже.
  • Важные, но не критичные для бизнеса продакшн-системы — раз в квартал: этого обычно хватает, чтобы поймать дрейф конфигурации и деградацию бэкапов раньше, чем они накопятся до серьёзной проблемы.
  • По-настоящему критичные системы (платёжный шлюз, основная база данных, система, простой которой считают в деньгах в реальном времени) — репетиция должна быть регулярной по расписанию, а не «когда руки дойдут»: раз в месяц или чаще. Держать это на памяти дежурного — плохая идея: расписание стоит завести как повторяющуюся задачу в календаре команды с конкретным ответственным.

Практический приём, который экономит время на будущих репетициях, — вести короткий журнал по каждому прогону: дата, откуда восстанавливали, сколько заняло каждый этап, что пошло не так и что поправили в процедуре. Через несколько итераций журнал сам превращается в актуальную инструкцию восстановления — куда полезнее, чем документ, который писали один раз и с тех пор не трогали. Если в компании ещё не формализован план действий при аварии, начать стоит с более широкого документа — мы разбирали его структуру в статье про план аварийного восстановления для малого бизнеса, а репетиция восстановления VM — конкретная, регулярно повторяемая практика внутри такого плана.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Сколько времени в среднем занимает одна репетиция?

Зависит от размера VM и скорости хранилища бэкапов — от 20–30 минут для небольшой VM с быстрым SSD-хранилищем PBS до нескольких часов для крупной базы данных на медленном NFS. Именно поэтому первая репетиция важна сама по себе: без неё вы не знаете даже порядок величины.

Обязательно ли для репетиции отдельное физическое железо?

Нет, обязательна изоляция по сети и по идентификаторам (IP, hostname, MAC), а не обязательно отдельный сервер. Изолированный VLAN-мост без физического аплинка на существующем узле — рабочий и недорогой вариант, если нет свободного отдельного железа под тестовый узел.

Что делать, если репетиция вскрыла, что бэкап битый?

Немедленно проверить остальные бэкапы того же задания и того же датастора — если сломался механизм (место, учётные данные, повреждённые чанки), под ударом обычно не одна VM, а всё задание целиком. Только после устранения причины и получения нового, подтверждённого бэкапа репетицию нужно повторить, чтобы убедиться, что проблема реально устранена.

Нужно ли репетировать восстановление для каждой VM отдельно?

Не обязательно для всех сразу — разумно сгруппировать VM по критичности и по типу нагрузки (веб-сервер, база данных, очередь) и репетировать по представителю каждой группы регулярно, а редко используемые вспомогательные машины — реже, но не исключать совсем.

Как быть, если восстановление на изолированный полигон физически невозможно (нет свободных ресурсов)?

Минимальный компромисс — восстанавливать в то же окружение, но в отдельное время обслуживания с полным отключением сетевых интерфейсов сразу после старта и проверкой строго по чек-листу изнутри консоли (без сети), это хуже полноценной изоляции, но всё ещё несравнимо честнее, чем вообще не восстанавливать.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →