У многих сочетание понятий «контейнеры» и «резервное копирование» вызывает недоумение. Зачем бэкапить те сущности, которые были созданы специально для быстрого развертывания и уничтожения? Однако в мире ИТ больших компаний такая «странность» необходима. Расскажем о ситуациях, когда резервные копии оказываются полезны, и подробно разберем бэкап двумя способами: с помощью Kasten — решения, установленного внутри кластера Kubernetes, — и внешнего Commvault. Но чтобы не cмешивать всё в одном посте, начнем с Kasten. Поехали!

Особенности запуска некоторых видов ПО

Одна из проблем, которая заставляет задумываться о резервном копировании Kubernetes — условия работы некоторых видов ПО. Сегодня СУБД всё чаще запускаются в контейнерах, и становится актуальным вопрос настройки конфигураций, а также загрузки дополнительных объектов, необходимых для работы СУБД.

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

Казалось бы, всё это не важно при использовании GitOps, и все конфигурации уже лежат в Git. Но по факту повторное развертывание кластера может стать триггером дополнительных событий, а для параметров, конфигураций, объектов и данных могут потребоваться трансформации. Поэтому, чтобы гарантировать восстановление продуктивных сред в разумное время, всё больше компаний выбирают бэкап.

Что бэкапить в Kubernetes?

При поверхностном взгляде кажется, что проблему восстановления данных и сервисов можно решить с помощью резервного копирования виртуальных машин мастер-узлов кластера. Но, увы, успешное восстановление в этом случае гарантировать не получится. Невозможно угадать, в каком состоянии будет сервис на момент создания резервной копии. Например, может оказаться, что часть данных находилась только в кэше СУБД, и после восстановления база данных окажется неконсистентной и СУБД вообще не запустится. Выходит, инструмент резервного копирования контейнеров должен понимать, что:

  • он делает бэкап контейнерного приложения;        

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

Для эффективного бэкапа конфигураций и персистентных хранилищ можно использовать три разных инструмента:

  • Snapshot. Легко и быстро делаем снимок пода и размещаем его во внешнем хранилище. Однако гарантировать работу содержимого контейнера после восстановления можно не для всякой «начинки». Например, это справедливо для СУБД, потому что запуск контейнера из snapshot’a в новых условиях может потребовать дополнительной настройки.    

  • Side-car контейнер. Kubernetes позволяет разместить два контейнера в рамках одного пода. Можно получить доступ к интерфейсу, чтобы снять бэкап, но требуются дополнительные решения. То есть сделать это исключительно штатными средствами кластера не получится.    

  • Pre-post скрипты. Позволяют подготовить ПО к резервному копированию: очистить кеш, сохранить логи, а также запустить процедуру резервного копирования. Скрипты нужно использовать вместе с каким-либо решением для бэкапа.

Сами средства резервного копирования также бывают двух типов: размещенные внутри кластера и внешние. Первые запускаются непосредственно внутри Kubernetes, вторые подключаются к кластеру извне.

Бэкап внутри кластера

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

Из наиболее популярных решений такого класса можно выделить Velero и Kasten. Однако на самом деле существует еще добрый десяток разных продуктов, размещаемых внутри кластера, как Open Source, так и коммерческих. Схематически бэкап внутри кластера выглядит следующим образом:

Веб-интерфейс.

Через консоль Applications можно управлять резервным копированием. Раздел Policies задает правила выполнения РК. Раздел Settings показывает параметры и позволяет настроить распределение емкостей хранилищ данных.

В этом примере к нашему решению подключено два внешних хранилища: NFS и S3. Впрочем, можно подключить и другие.

Настройки хранилища.

В консоли Applications мы найдем различные приложения. В нашем случае речь пойдет про СУБД PostgreSQL. Как показано на скриншоте, это приложение уже защищено политикой РК.

Раздел Applications.

Переходим в раздел Policies, создаем новую политику. Первым шагом система делает Snapshot, для которого можно указать частоту и время его хранения.

Настройки политики.

Второй вариант хранения резервной копии — это Export. Разница между Export и Snapshot заключается в том, что Snapshot размещается в том же хранилище, что и исходные данные. И если мы теряем к нему доступ, то пропадут также резервные копии. При экспортировании Snapshot автоматически сжимается, выполняется его дедупликация, шифрование и копирование на внешнее хранилище. Для экспорта также можно указать частоту, профиль и время хранения.

Выбор приложений.

После этого нужно выбрать объекты, которые должны попасть в резервную копию. В меню предусмотрены настройки предварительных скриптов для подготовки СУБД (или любого другого приложения) к резервному копированию.

Следить за процессом можно из основного дашборда. В нем отображается стадия процесса, а после завершения будет понятно, какие объекты попали в Snapshot фактически.

Процесс резервного копирования.

Если не использовать политики, то резервное копирование любого приложения можно выполнить вручную: кликом мышки запустить создание нового Snapshot’a, восстановить или экспортировать.

Восстановление с Kasten Чтобы восстановить сервис нужно зайти в раздел Applications и нажать на кнопку Restore рядом с нужным приложением. После этого на экране появится перечень доступных для восстановления точек.

Выбор точки восстановления.

В качестве таких точек могут быть доступны как Snapshot’ы, так и внешние экспортированные образы.

Выбор источника резервной копии.

Можно восстановить в тот же Namespace, например, если приложение было полностью удалено, или разместить его в новом Namespace’е.

Выбор Namespace.

При восстановлении можно использовать hook’и, а также выбирать объекты, которые требуется восстановить. Например, можно отказаться от восстановления персистентного хранилища, или, наоборот, восстановить данные, но не сам сервис.

Выбор объектов резервного копирования.

Преимущество восстановления с Kasten заключается в том, что можно гранулярно выбирать нужные сервисы. А четкая настройка объектов Kubernetes — это ключ к успешному запуску. Благодаря этому СУБД сможет восстановиться из Snapshot’a и сразу начать работать.

Веб-консоль Red Hat OpenShift.

Чтобы проверить, всё ли прошло гладко, откроем консоль Red Hat OpenShift. Там уже виден новый Namespace — Postgres-new. Если подключиться к поду, то можно запустить его терминал и посмотреть результат выполнения восстановления. Тут видно, что PostgreSQL запустился и работает корректно.

Терминал пода.

На случай, если кластер вообще умер, в Kasten также существуют свои решения. Покажем на конкретном примере. Наша резервная копия была сохранена на S3. Во втором кластере тоже настроен Kasten, к которому подключено то же хранилище S3. Чтобы второй кластер был «в курсе» резервных копий из первого, нужно создать политику импорта.

Настройки импорта резервных копий.

Можно настроить частоту импорта и даже выбрать автоматическое восстановление из импортированных с S3 копий. Все они лежат в хранилище в сжатом и зашифрованном формате. Чтобы получить доступ к этим данным, первому кластере нужен ключ Importing Data.

Получение данных импорта.

Копируем ключ в том кластере, где были созданы резервные копии, и просто вставляем его в политику импорта для второго кластера. Создаем новую политику и запускаем ее. В результате Kasten второго кластера получает информацию о резервных копиях, созданных в первом кластере. Так можно проверить работу контейнеров в новых условиях, а также мигрировать контейнеры между кластерами (хотя бы частично). Конечно, для миграции есть специализированное решение Migration Tools for Containers, которое включает в себя дополнительные методы тестирования работоспособности. Но и с Kasten можно решить подобные задачи для простейших случаев.

Импорт резервных копий.

После завершения импорта нужно выполнить восстановление. Оно происходит в новом кластере, где такого же Namespace’а не существует, поэтому приложения будут находиться в группе Removed.

Группа Removed.

Вы получите доступ к нескольким точкам восстановления, включая последнюю. Для восстановления нужно выбрать новый Namespace. В нашем примере выбираем Postgres-new2... а можно и не заполнять это поле. Тогда восстановление выполнится в такой же Namespace, как и в первом кластере.

Теперь нужно трансформировать образ. Дело в том, что один кластер был развернут на Bare Metal, где персистентные тома подключались как блочные устройства Ceph, а второй кластер — в VMware с хранилищами в виде Vmdk-дисков. Нужно показать системе, что в новом кластере нет того же класса хранилища. Для этого в Persistent Volume Claims необходимо подменить запросы на новую систему. Делается это с помощью операции трансформации. В ней отмечаем объекты, которые нужно трансформировать (в нашем случае Persistent Volume Claims). Выбираем операцию replace, а в ней — путь, значение и имя. Также указываем, что восстанавливать данные о старом классе хранилища не нужно.

Настройки трансформации.

Чтобы проверить работоспособность СУБД, можно подключиться к поду в OpenShift. В нашем примере мы видим, что теперь у нас есть все те же базы данных, которые были в первом кластере.

Disaster Recovery — это еще одна возможность для восстановления Kasten на случай полной потери кластера. Мы просто развертываем кластер заново, устанавливаем Kasten, и механизм Disaster Revocery позволяет ему восстановить данные обо всех резервных копиях, которые были сделаны ранее. Это очень полезная функция, ведь в случае сбоя вы не тратите время на восстановление самого кластера и его функциональности. Можно запустить систему и начать восстановление критичных сервисов в новом кластере, уже существующем или развернутом только что для этих целей.

На финише

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

Мы рассмотрели два разных варианта резервного копирования Kubernetes, а в следующем посте подробно поговорим про резервное копирование кластера при помощи Commvault.

Авторы:

Вячеслав Детинников, инженер-проектировщик систем хранения данных «Инфосистемы Джет»

Ренат Мустафин, архитектор DevOps-решений «Инфосистемы Джет»