У многих сочетание понятий «контейнеры» и «резервное копирование» вызывает недоумение. Зачем бэкапить те сущности, которые были созданы специально для быстрого развертывания и уничтожения? Однако в мире ИТ больших компаний такая «странность» необходима. Расскажем о ситуациях, когда резервные копии оказываются полезны, и подробно разберем бэкап двумя способами: с помощью 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. Как показано на скриншоте, это приложение уже защищено политикой РК.
Переходим в раздел Policies, создаем новую политику. Первым шагом система делает Snapshot, для которого можно указать частоту и время его хранения.
Второй вариант хранения резервной копии — это Export. Разница между Export и Snapshot заключается в том, что Snapshot размещается в том же хранилище, что и исходные данные. И если мы теряем к нему доступ, то пропадут также резервные копии. При экспортировании Snapshot автоматически сжимается, выполняется его дедупликация, шифрование и копирование на внешнее хранилище. Для экспорта также можно указать частоту, профиль и время хранения.
После этого нужно выбрать объекты, которые должны попасть в резервную копию. В меню предусмотрены настройки предварительных скриптов для подготовки СУБД (или любого другого приложения) к резервному копированию.
Следить за процессом можно из основного дашборда. В нем отображается стадия процесса, а после завершения будет понятно, какие объекты попали в Snapshot фактически.
Если не использовать политики, то резервное копирование любого приложения можно выполнить вручную: кликом мышки запустить создание нового Snapshot’a, восстановить или экспортировать.
Восстановление с Kasten Чтобы восстановить сервис нужно зайти в раздел Applications и нажать на кнопку Restore рядом с нужным приложением. После этого на экране появится перечень доступных для восстановления точек.
В качестве таких точек могут быть доступны как Snapshot’ы, так и внешние экспортированные образы.
Можно восстановить в тот же Namespace, например, если приложение было полностью удалено, или разместить его в новом Namespace’е.
При восстановлении можно использовать hook’и, а также выбирать объекты, которые требуется восстановить. Например, можно отказаться от восстановления персистентного хранилища, или, наоборот, восстановить данные, но не сам сервис.
Преимущество восстановления с Kasten заключается в том, что можно гранулярно выбирать нужные сервисы. А четкая настройка объектов Kubernetes — это ключ к успешному запуску. Благодаря этому СУБД сможет восстановиться из Snapshot’a и сразу начать работать.
Чтобы проверить, всё ли прошло гладко, откроем консоль Red Hat OpenShift. Там уже виден новый Namespace — Postgres-new. Если подключиться к поду, то можно запустить его терминал и посмотреть результат выполнения восстановления. Тут видно, что PostgreSQL запустился и работает корректно.
На случай, если кластер вообще умер, в Kasten также существуют свои решения. Покажем на конкретном примере. Наша резервная копия была сохранена на S3. Во втором кластере тоже настроен Kasten, к которому подключено то же хранилище S3. Чтобы второй кластер был «в курсе» резервных копий из первого, нужно создать политику импорта.
Можно настроить частоту импорта и даже выбрать автоматическое восстановление из импортированных с S3 копий. Все они лежат в хранилище в сжатом и зашифрованном формате. Чтобы получить доступ к этим данным, первому кластере нужен ключ Importing Data.
Копируем ключ в том кластере, где были созданы резервные копии, и просто вставляем его в политику импорта для второго кластера. Создаем новую политику и запускаем ее. В результате Kasten второго кластера получает информацию о резервных копиях, созданных в первом кластере. Так можно проверить работу контейнеров в новых условиях, а также мигрировать контейнеры между кластерами (хотя бы частично). Конечно, для миграции есть специализированное решение Migration Tools for Containers, которое включает в себя дополнительные методы тестирования работоспособности. Но и с Kasten можно решить подобные задачи для простейших случаев.
После завершения импорта нужно выполнить восстановление. Оно происходит в новом кластере, где такого же Namespace’а не существует, поэтому приложения будут находиться в группе 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-решений «Инфосистемы Джет»
shurup
Не увидел явных упоминаний, что Kasten — это платное и закрытое решение. (Как оно, кстати, соотносится к Kanister, ссылка на GitHub которого висит на сайте продукта?) Почему ему отдали предпочтение вместо упомянутого в статье Velero, который Open Source?
JetHabr Автор
Выводы будут во второй части статьи (она уже готовится), аспект «платности» Kasten мы обсудим там. Собственно, этот продукт доступен и в бесплатной версии с ограничением в 10 нод на кластер.
Отвечая на второй вопрос. По умолчанию Kasten применяет для резервного копирования снапшоты, если требуется консистентность на уровне БД, то в данном случае для взаимодействия с СУБД Kasten будет использовать Kanister.
И, наконец, почему не open source Velero. Мы рассматриваем в этом посте и следующем вендорские решения, потому что им предпочтения отдают наши заказчики из мира Enterprise, а им важна поддержка от производителя.