Облако удобно воспринимать как бесконечный набор ресурсов: в нужный момент мы создаём виртуальную машину, диск, балансировщик или кластер и платим только за использование. Из этого легко сделать опасный вывод: раз инфраструктурой управляет крупный провайдер, её отказоустойчивость уже обеспечена.
На практике облако снимает с команды часть аппаратных проблем, но не принимает за неё архитектурные решения. Виртуальная машина остаётся привязана к зоне. Диск может быть зональным ресурсом. Квоты могут закончиться именно тогда, когда понадобится создать резерв. API и панель управления могут быть недоступны одновременно. А резервная копия, лежащая в том же аккаунте и у того же провайдера, разделяет часть его рисков.
Мы столкнулись с ситуацией, в которой недоступность одной зоны затронула сразу несколько внутренних сервисов и заблокировала обычный путь восстановления. Самым полезным результатом оказался не список команд, которыми мы переносили системы, а пересмотр исходной модели: какие отказы мы вообще учитывали, где находились резервные копии и сколько ручных зависимостей оставалось между конфигурацией в Git и работающим сервисом.
В этой части разберём, как принимать эти решения до инцидента. Во второй — как организовать сам аварийный переезд.
О чём эта часть
Сначала определите, от чего защищаетесь
Фраза «у нас отказоустойчивая инфраструктура» ничего не значит без указания уровня отказа. У каждого уровня свой способ защиты.
Уровень отказа |
Пример |
Что должно его пережить |
|---|---|---|
Процесс или контейнер |
приложение завершилось с ошибкой |
система перезапуска, оркестратор и проверки работоспособности |
Виртуальная машина |
отказ ОС, гипервизора или узла |
несколько экземпляров, автоматическое пересоздание |
Диск |
повреждение или потеря тома |
репликация данных и проверяемая резервная копия |
Зона доступности |
недоступны VM, диски или часть сети в одном ЦОД |
размещение сервиса и данных в нескольких зонах |
Регион или контур управления облаком |
нельзя создавать ресурсы, менять сеть или управлять сервисами |
заранее подготовленный контур восстановления вне региона |
Облачный провайдер |
длительная техническая, договорная или финансовая недоступность |
копия данных и возможность развернуться у независимого провайдера |
Аккаунт организации |
блокировка, компрометация или ошибочное удаление |
отдельный контур безопасности, аварийный доступ и независимые копии |
Зоны одного облака обычно изолированы друг от друга на уровне части аппаратной и программной инфраструктуры. Например, документация Yandex Cloud прямо разделяет ресурсы на зональные и глобальные и рекомендует несколько зон для защиты от зональных отказов. Это полезная, но ограниченная гарантия: несколько зон одного провайдера не устраняют зависимость от его общего API, IAM, биллинга, квот и организационного аккаунта.
Поэтому вопрос должен звучать не «сколько у нас зон», а «какой сценарий отказа мы готовы пережить и за какое время».
RPO и RTO превращают тревогу в инженерную задачу
Для каждого сервиса нужны два показателя.
RPO — допустимая потеря данных. Показатель отвечает на простой вопрос: «На сколько назад мы готовы откатиться?» Если база копируется каждые шесть часов, её формальный RPO не может быть меньше шести часов. Асинхронная репликация может сократить этот интервал до минут или секунд, но не делает его нулевым: реплика может отставать, а ошибочные изменения копируются вместе с правильными.
RTO — допустимое время восстановления. Это ответ на вопрос: «Сколько сервис может не работать?» Сюда входит не только загрузка резервной копии, но и обнаружение аварии, принятие решения, получение квот, создание инфраструктуры, проверка и переключение трафика.
Не следует назначать всем системам одинаковые цели. Это либо слишком дорого, либо неправдоподобно. Удобнее разделить сервисы на три класса.
Класс |
Примеры |
Ориентир по RPO |
Ориентир по RTO |
Тип защиты |
|---|---|---|---|---|
Критичный |
GitLab, IAM, секреты, VPN/NGFW, основные БД |
минуты–1 час |
1–4 часа |
репликация или частые внешние копии, готовая пошаговая инструкция |
Важный |
задачи, документация, мониторинг, UAT |
несколько часов |
рабочий день |
регулярная копия и автоматизированное восстановление |
Восстанавливаемый |
временные стенды, кэши, раннеры без состояния |
без RPO либо сутки |
1–3 дня |
пересоздание из кода |
Цифры здесь не норматив, а пример. Настоящие значения определяет бизнес: сколько стоит час простоя, сколько данных можно воспроизвести и какой бюджет оправдан.
До выбора архитектуры составьте карту зависимостей
Список виртуальных машин не является картой инфраструктуры. Сервис может состоять из VM, базы, бакетов, DNS-записей, сертификатов, ключей, внешней почтовой службы, адресов обратных вызовов и ручного правила межсетевого экрана. Если сохранить только диск, приложение может не запуститься.
Для каждого сервиса стоит зафиксировать:
владельца и критичность;
входящие и исходящие зависимости;
источник конфигурации и версию приложения;
расположение базы, файлов и объектного хранилища;
способ резервного копирования и последний успешный тест восстановления;
RPO, RTO и порядок проверки после восстановления;
DNS-имена, сертификаты, внешние списки разрешённых адресов и статические IP;
секреты, ключи шифрования и способ аварийного доступа;
минимальные CPU, RAM, диск и пропускную способность для аварийного режима.
Эта карта часто обнаруживает неожиданные одиночные точки отказа: GitOps хранится в GitLab, а инструкция по восстановлению GitLab — только в том же GitLab; доступ к резервному бакету выдаёт Vault, резервная копия которого лежит за тем же доступом; DNS управляется из конвейера CI/CD, который нельзя запустить без недоступного раннера.
После этого можно выбирать один из двух основных подходов.
Подход 1. Два независимых провайдера или два независимых ЦОД
Это наиболее полная защита от потери облачного провайдера. Ключевое слово — независимых. Два бренда могут использовать один ЦОД, одну магистраль, общий биллинг или одну административную учётную запись. Перед покупкой нужно проверить реальную изоляцию.
Вариант 1. Обе площадки активны (active-active)
Обе площадки принимают рабочий трафик. Глобальный балансировщик или DNS распределяет запросы, приложения работают параллельно, данные реплицируются.
Это даёт минимальный RTO, но требует самого сложного проектирования. Приложение должно корректно работать при сетевом разделении. Для данных нужен понятный владелец записи или механизм разрешения конфликтов. Нельзя просто запустить два основных узла PostgreSQL и надеяться, что они договорятся после разрыва связи.
Схема с двумя активными площадками оправдана там, где минуты простоя стоят дороже постоянной второй площадки и отдельной команды, способной её сопровождать.
Вариант 2. Основная площадка и тёплый резерв (active-passive)
Основная площадка обслуживает пользователей, на второй уже существуют сеть, вычислительные ресурсы, секреты и реплики данных. Во время аварии команда останавливает или изолирует старый основной узел, проверяет актуальность реплик и переключает трафик.
Такой вариант дешевле и проще двух одновременно активных площадок. Главный риск — «тёплый» резерв постепенно становится холодным: не обновляются версии, сертификаты, правила сети, секреты или схемы базы. Поэтому переключение на резерв нужно регулярно репетировать.
Вариант 3. Минимальный резервный контур (pilot light)
На резервной площадке постоянно работают только минимальные компоненты: сеть, хранилище копий, ключевые базы или их журналы, DNS и средства управления. Вычислительные ресурсы приложений создаются из кода инфраструктуры только при аварии.
Это разумный компромисс для небольшой команды. Он уменьшает постоянную стоимость, но RTO зависит от доступных квот, скорости получения образов и времени восстановления данных.
Вариант 4. Восстановление из резервной копии
Второй провайдер хранит только независимые резервные копии, код инфраструктуры, образы и инструкции. Во время аварии инфраструктура создаётся с нуля.
Это самый дешёвый межпровайдерный вариант и минимально необходимый уровень защиты для критичных данных. Его слабое место — непроверенная скорость восстановления. Если копию никогда не разворачивали, её существование ещё не означает, что RTO достижим.
Как проектировать данные между провайдерами
С вычислениями обычно проще, чем с данными. Приложение без локального состояния можно пересоздать. База, файлы пользователей, Git-репозитории и ключи требуют отдельной стратегии.
Для баз данных возможны:
асинхронная репликация в другую площадку;
передача журналов транзакций — WAL или binlog — и периодические полные копии;
логические дампы как дополнительный переносимый формат;
снимки дисков только как один из слоёв, а не единственная резервная копия.
Для объектного хранилища полезны версионирование, запрет изменения и удаления объектов (Object Lock) и репликация в независимый S3-совместимый сервис. Нужно сверять не только количество объектов, но и ключи, размеры, контрольные суммы и версии.
Ключи шифрования нельзя потерять и нельзя бездумно хранить рядом с зашифрованной копией. Команде требуется отдельный, ограниченный и проверяемый механизм восстановления секретов.
Сеть и переключение
Межпровайдерная схема требует заранее решить:
кто управляет публичным DNS и доступен ли он независимо от основного облака;
как быстро меняются записи и каков реальный TTL у резолверов;
нужны ли постоянные публичные IP для списков разрешённых адресов у партнёров;
где завершается TLS и где хранятся ключи сертификатов;
как сотрудники попадут во вторую площадку при отказе VPN/NGFW;
как предотвратить расхождение двух активных копий, когда обе площадки считают себя основной.
Таблица выбора внутри подхода с двумя провайдерами
Вариант |
Ожидаемый RTO |
Возможный RPO |
Постоянная стоимость |
Сложность |
Для чего подходит |
|---|---|---|---|---|---|
Обе площадки активны |
секунды–минуты |
близко к нулю, зависит от данных |
очень высокая |
очень высокая |
публичные критичные сервисы с дорогим простоем |
Основная площадка и тёплый резерв |
десятки минут–часы |
секунды–минуты |
высокая |
высокая |
GitLab, IAM, основные БД, ключевые API |
Минимальный резервный контур |
часы |
минуты–часы |
средняя |
средняя |
небольшая платформа с ограниченным бюджетом |
Восстановление из резервной копии |
часы–дни |
равно интервалу копирования |
низкая |
средняя во время аварии |
большинство внутренних сервисов и минимальный контур аварийного восстановления |
Эта таблица не обещает конкретный RTO: он появляется только после измеренной репетиции на ваших объёмах данных.
Подход 2. Один провайдер, несколько зон и независимые резервные копии
Иногда второй постоянно работающий провайдер слишком дорог, запрещён договором или превышает возможности команды. Тогда инфраструктуру можно сделать значительно устойчивее внутри одного облака — при условии, что команда честно принимает остаточный риск отказа всего провайдера.
Разнесите приложение и данные по зонам
Для компонентов без локального состояния это обычно означает несколько экземпляров в разных зонах за балансировщиком. Для Kubernetes — рабочие узлы по зонам, правила распределения topologySpreadConstraints, разнесение реплик podAntiAffinity и PodDisruptionBudget. Само наличие трёх рабочих узлов не помогает, если все они оказались в одной зоне.
Сервисы, хранящие состояние, сложнее. Кворум из трёх узлов должен переживать потерю одной зоны, но схема размещения зависит от задержек и гарантий конкретного хранилища. Реплика базы в другой зоне защищает от потери VM или зоны, но не от ошибочного DELETE, повреждения данных приложением или украденной административной учётной записи. Поэтому репликация дополняет резервное копирование, а не заменяет его.
Храните копии отдельно от источника
Для важных сервисов минимумом будет резервная копия в другой зоне или региональном объектном хранилище с версионированием. Для критичных — дополнительная копия у независимого провайдера или в физически отдельном хранилище.
Полезная модель — 3-2-1:
три экземпляра данных;
два разных типа или контура хранения;
одна копия вне основной площадки.
Для защиты от удаления или шифровальщика добавляют неизменяемую копию. Право удалять резервные копии не должно автоматически выдаваться администратору боевой среды.
Не рассчитывайте на создание резерва после начала аварии
Во время крупного сбоя все клиенты одновременно пытаются создать VM в здоровой зоне. Формальная квота не гарантирует физическую ёмкость. Заранее созданный минимальный резерв, зарезервированная мощность или договорённость с поддержкой могут оказаться важнее красивой схемы в Terraform.
Нужно проверить и ограничения типов ресурсов: доступность нужной CPU-платформы, размер диска, возможность подключить статический IP, лимиты балансировщиков и управляемых баз данных. Зоны одного провайдера могут поддерживать разные наборы платформ.
Разделите сервисы по критичности
При ограниченном бюджете нельзя одинаково защищать всё. Например:
GitLab, Vault/IAM, сеть и основные базы получают копии вне провайдера и короткую пошаговую инструкцию;
документация и система управления задачами получают частые резервные копии средствами самих приложений;
стенды разработки и приёмочного тестирования пересоздаются из GitOps после возвращения базовых сервисов;
реестр образов и кэш пакетов можно не переносить первыми, если артефакты воспроизводимы из исходников;
временные узлы CI/CD и кэши вообще не копируются.
Здесь важно не перепутать «воспроизводимо» и «кажется, можно собрать». Сборка должна быть проверена: исходники, файлы с зафиксированными версиями зависимостей, базовые образы и внешние зависимости могут исчезнуть одновременно.
Таблица выбора внутри одного провайдера
Вариант |
Защита от VM |
Защита от зоны |
Защита от провайдера/аккаунта |
Стоимость |
Комментарий |
|---|---|---|---|---|---|
Одна зона + снимки дисков |
да |
нет |
нет |
низкая |
годится только для некритичных систем |
Несколько зон без отдельной резервной копии |
да |
да, частично |
нет |
средняя |
репликация переносит логические ошибки |
Несколько зон + резервная копия в другой зоне |
да |
да |
почти нет |
средняя |
хорошая защита от отказа зоны, но общий контур отказа сохраняется |
Несколько зон + неизменяемая копия вне провайдера |
да |
да |
да, для восстановления данных |
средняя |
практичный минимум для критичных данных |
Несколько зон + минимальный контур у второго провайдера |
да |
да |
да, с меньшим RTO |
средняя–высокая |
следующий шаг после внешних резервных копий |
Главная граница этого подхода: несколько зон повышают доступность внутри облака, но не превращаются в несколько независимых облаков только потому, что зон несколько.
Сравнение двух основных подходов
Критерий |
Два независимых провайдера/ЦОД |
Один провайдер, несколько зон + внешние резервные копии |
|---|---|---|
Отказ одной зоны |
переживает |
переживает при корректной архитектуре |
Отказ контура управления провайдера |
резерв может продолжить работу |
автоматизация и масштабирование могут остановиться |
Потеря аккаунта |
можно изолировать второй контур |
боевая среда недоступна, остаются внешние копии |
Минимальный RTO |
секунды или минуты |
обычно часы при отказе провайдера |
Стоимость |
выше |
ниже |
Операционная сложность |
высокая: разные API, сети и сервисы |
умеренная |
Риск скрытых расхождений с конфигурацией |
высокий на пассивной площадке |
ниже, если всё регулярно создаётся из кода инфраструктуры |
Требования к команде |
опыт распределённых систем и аварийного переключения |
сильные процессы резервного копирования и восстановления и автоматизация |
Когда выбирать |
простой критичнее стоимости |
бюджет ограничен, но потеря данных недопустима |
На практике эти подходы образуют шкалу, а не два взаимоисключающих лагеря. Компания может держать приложение в нескольких зонах одного облака, копировать критичные данные во второе облако и постепенно превратить этот контур хранения копий в минимальную резервную площадку.
Что обязательно автоматизировать
Подход «инфраструктура как код» (Infrastructure as Code, IaC) позволяет описывать сеть, виртуальные машины, политики, DNS и управляемые сервисы в версионируемых конфигурациях. В документации HashiCorp этот подход описан как управление инфраструктурой через конфигурационные файлы вместо ручной работы в панели. Это уменьшает число забытых шагов и делает перенос повторяемым.
Но код инфраструктуры — это рецепт, а не продукты на кухне. В нём нет данных приложения, секретов, свободной мощности у провайдера, загруженного образа специализированной системы и гарантии, что API сейчас доступен. Поэтому одного Terraform недостаточно. Рядом с ним нужны:
GitOps-манифесты приложений;
система управления конфигурацией ОС и сервисов;
независимое хранилище состояния Terraform и его резервная копия;
переносимый способ первичного восстановления секретов;
зафиксированные версии модулей провайдеров и способ получить их даже при недоступности основного реестра;
автоматические резервные копии средствами самих приложений;
тесты восстановления и контрольные манифесты;
пошаговая инструкция, которую можно открыть без основного GitLab.
Особенно опасно хранить единственную копию кода инфраструктуры и состояния Terraform внутри системы, которую этот код должен восстановить.
Минимальная программа подготовки
Если бюджет ограничен, я бы выполнял работу в таком порядке:
Инвентаризировать сервисы и назначить им владельцев, RPO и RTO.
Убрать критичную инфраструктуру из одной зоны.
Настроить резервные копии баз, файлов, Git-репозиториев и служебных данных хранилища секретов средствами самих приложений.
Копировать критичные резервные копии в независимый аккаунт или к другому провайдеру.
Включить версионирование или запрет изменения копий и разделить права боевой среды и хранилища резервных копий.
Описать сеть и вычислительные ресурсы кодом инфраструктуры, приложения — в GitOps.
Сохранить аварийную копию кода инфраструктуры, состояния Terraform, документации и ключей первичного доступа вне основной площадки.
Раз в квартал восстанавливать хотя бы один критичный сервис на чистой площадке.
Раз в полгода проводить учение с переключением DNS и измерением фактических RPO/RTO.
Проверка восстановления важнее сообщения «задание резервного копирования завершилось успешно». Успешной резервной копия становится только после того, как из неё удалось получить работающий сервис и подтвердить целостность данных.
Во второй части разберём сам переезд: как остановить увеличение ущерба, выбрать целевое облако, что восстанавливать первым, как проверять GitLab глубже количества проектов и пользователей и когда безопасно переключать DNS.
Как это связано с DevSecOps, безопасностью и AppSec
На первый взгляд отказ облака — инфраструктурная проблема: не запускаются виртуальные машины, недоступны диски, приходится менять маршруты. Но последствия быстро выходят за границы DevOps. Если недоступен GitLab, разработчики не могут получить исходный код и выпустить исправление. Если потерян Vault или IAM, команда либо останавливается, либо начинает раздавать временные доступы. Если резервная копия восстановлена без ключей, политик и журналов аудита, сервис может работать технически, но уже не соответствовать требованиям безопасности.
Именно здесь появляется DevSecOps: безопасность должна быть частью способа создания и восстановления системы, а не отдельной проверкой перед запуском. Код инфраструктуры проходит такое же ревью, как код приложения. Политики доступа и сетевые правила хранятся в версионируемом виде. Резервные копии шифруются, право на их удаление отделяется от администрирования боевой среды, а восстановленный сервис проходит не только проверку доступности, но и проверку защитных механизмов.
AppSec тоже участвует напрямую. Во время аварии легко запустить старую версию приложения, забыть секрет, отключить проверку сертификата или временно открыть административный интерфейс всему интернету. Поэтому в план восстановления должны входить версия приложения, состав зависимостей, способ получения доверенных образов, проверка конфигурации TLS, ротация скомпрометированных секретов и минимальный набор тестов безопасности.
Ответственность распределяется между несколькими ролями:
Кто |
За что отвечает до и во время восстановления |
|---|---|
Разработчики |
переносимость приложения, миграции базы, обратная совместимость и проверка данных |
DevOps/SRE |
инфраструктура, автоматизация, наблюдаемость, резервное копирование и переключение |
AppSec и ИБ |
модель угроз, ключи, доступы, доверенные артефакты, аудит и безопасные временные решения |
Владельцы продукта |
критичность функций, допустимые RPO/RTO и порядок возвращения сервисов |
Руководство и финансы |
бюджет резерва, договоры с провайдерами и принятие остаточного риска |
Юристы и специалисты по соответствию требованиям |
требования к месту хранения данных, срокам хранения и уведомлению об инциденте |
Поэтому устойчивость к отказу облака — не «задача админов». Это часть непрерывности бизнеса и безопасности продукта. DevOps может поднять новую площадку, но только совместное решение определяет, какие данные допустимо потерять, какие временные риски можно принять и в какой момент восстановленный сервис действительно готов принимать пользователей.