RTP DesportoTriatlo/Mundiais: Letícia Magalhães e Catarina Santos concluem prova de juniores em 29.º e 30.ºBollywood HungamaSCOOP: Salman Khan’s Monster lands a MONSTROUS Rs. 100 crore deal; PVR INOX bags All India distribution rightsPunchPDP chieftain hails Oyebanji for donating 100 vehicles to security agenciesESPNWhat to do with seven start-sit decisions you might be dreadingDaily MaverickOUR CITY NEWS: R10bn urgently needed to fix Joburg’s crumbling roadsInquirerIloilo school cancels classes over ‘security concern’CNN TürkDİLAY ÖZDEMİR KİMDİR, KAÇ YAŞINDA, NERELİ? Voleybolcu Dilay Özdemir Hangi Takımlarda Forma Giydi? Filenin Sultanları'nın Genç YıldızıESPN DeportesCheco Pérez, con buena primera práctica en GP de Azerbaiyán de F1The Jerusalem PostIsraeli envoy to US's son fighting for life in hospital after car-ramming attack, Leiter saysVanguardFour suspected Boko Haram terrorists arrested in Yoben-tvWo beginnt Antisemitismus?: Was die Debatte um die Berliner Linke so kompliziert machtCBS NewsJudge blocks Trump's ban on CNN, MS NOW and Politico's White House access for now
The Daily Newsstand · Free, Always
Thursday, September 24, 2026

[Перевод] Аварийное восстановление в Kubernetes: три воспроизводимых сценария сбоя

Translate

Команда VK Cloud перевела статью, описывающую три сценария сбоя, которые отличают наличие резервных копий от возможности восстановления, а также рекомендации, следующие из каждого сценария. Каждый сценарий воспроизводим на ноутбуке из указанного выше репозитория стенда, и каждый показанный вывод терминала является реальным выводом терминала, полученный в стенде 

Документ посвящён восстановлению stateful-приложений, работающих в Kubernetes: проверке наличия данных в резервных копиях, разделению между декларативным и хранимым состоянием, а также обеспечению согласованности в приложениях с несколькими томами. В нём не рассматриваются требования комплаенса, сравнение продуктов и восстановление базовой облачной инфраструктуры или инфраструктуры дата-центра, однако указано, где начинается ответственность за эти задачи.

Конкретные инструменты упоминаются там, где они нужны для описания сценария: Velero и CSI snapshot APIs. Они приведены как эталонные реализации, чтобы сделать сценарии более предметными. Описанные отказы и рекомендации применимы к любому инструменту, который выполняет ту же роль.

Определения

RPO и RTO на одной временной шкале

RPO и RTO на одной временной шкале

Четыре уровня восстановления

Чтобы восстановление можно было считать успешным, нужно вернуть четыре уровня: 

Четыре уровня восстановления

Четыре уровня восстановления

Для каждого уровня есть зрелые инструменты, и по отдельности они обычно восстанавливаются без проблем. Сбои возникают на стыках между уровнями: кластер восстановлен, но данных нет; данные восстановлены, но к ним нет нет пути, по которому к приложению поступает трафик; описание приложения создаёт пустой том. В трёх следующих сценариях нарушается один из таких стыков.

Стенд

Весь стенд на одной картинке

Весь стенд на одной картинке

Два кластера и два сервиса, всё локально:

  • Production: кластер Kubernetes, в котором каждый узел представляет собой отдельную лёгкую виртуальную машину со своим ядром. Поэтому потеря production-кластера означает фактическое выключение машины.

  • Recovery: второй кластер, который существует ещё до того, как что-либо пойдёт не так.

  • Хранилище резервных копий: S3-совместимое объектное хранилище за пределами обоих кластеров. Благодаря этому потеря любого из кластеров не приводит к потере точек восстановления. Инструмент резервного копирования в обоих кластерах настроен на один и тот же бакет.

  • Git: локальный Git-сервис, где хранятся манифесты приложения. За изменениями в нём следит GitOps-контроллер в recovery-кластере.

В качестве рабочей нагрузки используется приложение с PostgreSQL и заранее известным содержимым базы данных — четырьмя строками. Поэтому каждое восстановление можно проверить по ожидаемому результату, а не по зелёному статусу на дашборде.

Сценарий 1. Проверка, что бэкап содержит данные

Инструмент бэкапа переносит объекты и байты volume в S3-хранилище

Инструмент бэкапа переносит объекты и байты volume в S3-хранилище

Резервное копирование Kubernetes состоит из двух отдельных частей: определений ресурсов в YAML и данных постоянных томов. Инструменты резервного копирования защищают данные томов с помощью снапшотов (снимков) на стороне провайдера или через CSI, резервного копирования файловой системы либо переноса данных снапшотов во внешнее хранилище. В этом стенде используется последний подход — Velero и его механизм переноса данных.

Обычно проверка ограничивается статусом Completed у резервной копии. Но стоит пойти дальше и убедиться, что байты данных тома действительно были перенесены:

$ kubectl -n velero get datauploads -l velero.io/backup-name=$BACKUP \
    -o custom-columns='NAME:.metadata.name,PHASE:.status.phase,BYTES:.status.progress.bytesDone'
NAME                                  PHASE       BYTES
guestbook-rehearsal-20260727001126-q2j9m   Completed   47989888

Здесь механизм переноса данных подтверждает, что 47 989 888 байт данных тома покинули кластер и были записаны во внешнее хранилище. Если инструмент резервного копирования не может показать это число для конкретной резервной копии, к нему стоит отнестись внимательно.

После удаления пространства имён вместе с PVC и восстановления из этой резервной копии те же четыре строки вернулись примерно за две минуты. Это позитивный сценарий, но он скрывает три вещи, которые ни один инструмент резервного копирования не сделает автоматически:

  • Защита данных тома не делает резервную копию базы данных согласованной на уровне приложения. Если приложение этого требует, необходимо настроить хуки для сброса данных на диск или перевода приложения в согласованное состояние.

  • Восстановление на другой инфраструктуре может потребовать сопоставления классов хранения и других преобразований. Инструменты предоставляют необходимые механизмы, но проектировать и тестировать их должна каждая команда самостоятельно.

  • Статус резервной копии Completed означает лишь, что операция резервного копирования завершилась. Он не доказывает, что приложение запустится, будет содержать ожидаемые данные или сможет обслуживать трафик. Такие доказательства даёт только сквозной тест восстановления.

Граница ответственности. Инструменты резервного копирования восстанавливают ресурсы в уже существующий кластер. Они не создают сам кластер, его узлы, сеть, балансировщики нагрузки или DNS. Восстановлением Kubernetes как платформы должен заниматься другой механизм: например, инфраструктура как код или Cluster API.

Поэтому в DR-плане, который начинается со слов «восстановить резервную копию», нужно указать, во что именно будет восстанавливаться эта копия.

Сценарий 2. Объявленное состояние не является сохранённым состоянием

Ловушка GitOps: контроллер восстанавливает объявления, а хранилище содержит данные

Ловушка GitOps: контроллер восстанавливает объявления, а хранилище содержит данные

Production-кластер выключен. Recovery-кластер, существовавший ещё до аварии, содержит GitOps-контроллер, настроенный на Git, и инструмент резервного копирования, настроенный на общее хранилище. До этого момента приложение в нём ни разу не запускалось.

Синхронизация приложения из Git завершается успешно: статус синхронизации — Synced, StatefulSet разворачивается, под базы данных переходит в состояния Running и Ready, все дашборды показывают зелёный статус. Однако запрос к базе данных возвращает:

ERROR: relation "attendees" does not exist

База данных работает, но она пуста. Ничего не сломалось. В Git хранились только декларации, поэтому Kubernetes в точности выполнил то, что описано в YAML: создал StatefulSet, Service и выделил для PVC новый пустой том. GitOps безупречно восстановил объявленное состояние, но не восстановил сохранённое состояние.

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

  • Удалить пустое приложение, созданное синхронизацией.

  • Восстановить приложение из хранилища резервных копий вместе с томами.

  • Проверить данные по ожидаемому содержимому.

Восстановление также происходило между разными инфраструктурными средами: на одном node runtime, а на другом восстановлена. Авария может вынудить восстанавливаться на другой инфраструктуре, поэтому переносимость восстановления нужно проверять на практике, а не считать её гарантированной.

Измерение. В стенде путь от выключения production-кластера до проверки данных в recovery-кластере занял четыре минуты при первом выполнении и чуть меньше двух минут при повторном, отрепетированном запуске. Обе цифры отражают только автоматизированную часть сценария. Производственный RTO включает также обнаружение инцидента, принятие решения, переключение трафика и последующий возврат к штатной схеме.

Общий вывод: момент, когда дашборды стали зелёными, ещё не был восстановлением. Восстановлением стал момент, когда данные вернулись и были проверены.


Разворачивайте кластеры Kubernetes с Managed Containers

Автоматизируйте деплой
и снижайте затраты на инфраструктуру
до 60%

Попробовать

Сценарий 3. Согласованность нескольких volume

Два снапшота из разных моментов времени рвут данные

Два снапшота из разных моментов времени рвут данные

Реальные stateful-приложения используют несколько томов: данные базы данных и WAL, партиции брокера сообщений, наборы реплик. В примере приложение пять раз в секунду записывает согласованные пары: заказ n в один PVC и платёж n — в другой. При этом соблюдается один инвариант: каждому платежу должен соответствовать его заказ.

Если создавать снимки этих двух томов по отдельности с разницей в пять секунд, получатся два снимка со статусом ReadyToUse, каждый из которых по отдельности безупречен. Однако после восстановления обоих томов и сравнения последних зафиксированных номеров последовательности результат будет таким:

last order committed   : 108352
last payment committed : 108377

[FAIL] 25 payments have NO matching order.
[FAIL] Each snapshot succeeded. The restore is still wrong.

Двадцать пять платежей ссылаются на заказы, которых не существует. Ни один компонент не отказал, каждая операция завершилась успешно, но итоговая точка восстановления описывает момент времени, которого никогда не было. В production такая пятисекундная разница возникает, когда инструмент резервного копирования последовательно обходит список из сотни PVC.

Ответ на уровне API: VolumeGroupSnapshot достиг статуса GA в Kubernetes 1.36. Один объект выбирает PVC по метке, а CSI-драйвер получает единый запрос на создание согласованной при аварийном завершении точки восстановления сразу для всех томов:

apiVersion: groupsnapshot.storage.k8s.io/v1
kind: VolumeGroupSnapshot
metadata:
  name: ledger-group-snap
spec:
  volumeGroupSnapshotClassName: csi-hostpath-groupsnapclass
  source:
    selector:
      matchLabels:
        group: ledger
Один групповой снапшот срезает оба volume в один и тот же момент

Один групповой снапшот срезает оба volume в один и тот же момент

При восстановлении снимков, входящих в группу, и запуске той же проверки:

last order committed   : 109169
last payment committed : 109169
[OK] Each payment has a matching order. Restore is consistent.

Оговорки, которые относятся не только к лабораторному стенду:

  • Поддержка зависит от драйвера. Поддержка обычных VolumeSnapshot не означает, что драйвер поддерживает групповые снимки: групповые CSI RPC требуют отдельной реализации. По состоянию на середину 2026 года большинство основных облачных драйверов, проверенных для лабораторного стенда, их не реализуют.

  • Настройку нужно выполнять явно: оператор должен включить CRD и feature gates на стороне snapshot controller и CSI sidecar.

  • Согласованность при аварийном завершении работы не равна согласованности на уровне приложения. API устраняет рассинхронизацию между томами по времени, но не сбрасывает буферы базы данных и не переводит её в согласованное состояние.

  • В лабораторном стенде используется тестовый CSI-драйвер hostpath. Он реализует групповые RPC, но архивирует тома группы последовательно, поэтому во время создания группового снимка запись приостанавливается, чтобы результаты демонстрации оставались детерминированными. Гарантия единой точки во времени сама по себе зависит от бэкенда хранения, который использует production-драйвер.

Рекомендации по тестированию восстановления

Тест восстановления — это не удаление пода с последующим ожиданием его перезапуска: такой тест проверяет согласование состояния рабочей нагрузки. Тест восстановления:

  • Восстанавливает stateful-приложение целиком в чистую целевую среду, где оно раньше не запускалось.

  • Проверяет данные и пользовательский путь по ожидаемому содержимому, а не по статусам ресурсов.

  • Измеряет весь процесс по времени.

Принципы, которые можно без изменений перенести из лабораторного стенда в production:

Два независимых домена сбоя

Два независимых домена сбоя

Открытые пробелы в экосистеме

Эти сценарии выявляют пробелы, которые сегодня не может закрыть ни один отдельный инструмент:

  • Нет общего контракта для межкластерного аварийного переключения. Для данных, рабочих нагрузок, кластеров, трафика и идентификации существуют отдельные инструменты, но в каждой из этих областей не хватает общего контракта со следующей. Продукты решают эту задачу внутри собственных API; в базовом Kubernetes последовательность действий не определена.

  • Нет стандартной единицы восстановления приложения. В базовом Kubernetes нет поддерживаемого ресурса Application, который определял бы, какие объекты, операторы, сервисы данных и внешние зависимости должны восстанавливаться вместе. Инструменты резервного копирования используют пространства имён и метки, GitOps-контроллеры — собственные объекты приложений, менеджеры пакетов — релизы, и каждый из них проводит границу по-своему.

  • Успешное резервное копирование считается доказательством возможности восстановления. Метрики успешного завершения резервного копирования широко отслеживаются, а результаты регулярных проверок восстановления — редко.

Как принять участие

Инициатива Cloud Native Business Continuity в рамках CNCF TAG Operational Resilience — открытое предложение, которое ищет участников. Его цели — провести анализ пробелов в экосистеме, обновить рекомендации по резервному копированию и аварийному восстановлению, а также подготовить эталонные архитектуры: https://github.com/cncf/toc/issues/1779

Источники

Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку

View the original on Хабр

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.