Представьте: вы недавно основали небольшое веб-приложение. Но только он стал расти как полноценный проект — Бац! — серверы легли, а данные не сохранились. Нужно было делать бэкапы. Казалось бы, совет достаточно простой и базовый, но какой тип резервного копирования выбрать? И как правильно к нему «подойти»?
Сегодня — международный день бэкапов. Кажется, это отличный повод, чтобы вспомнить, почему резервное копирование так важно, какое оно бывает и как его настроить. Подробности в статье!
В облаке Selectel есть почти все возможные сервисы для бэкапов на сегодняшний день. И часто клиенты нас спрашивают, какое решение лучше использовать. Это, можно сказать, вопрос с подвохом, поскольку сервисы не конкурируют между собой. Они решают одну задачу, но «в разных условиях».
От чего зависит выбор подхода и технологии резервного копирования? Чтобы это понять, мы погрузимся в историю одного pet-проекта, который развился до полноценного облачного приложения.
Предыстория: баг, который удалил все
Сисадмин Леша запустил небольшой pet-проект — аналог Google-диска. В его распоряжении один сервер, а сам сервис состоит всего из одной кнопки для загрузки фото.
Спустя время появились первые клиенты: бабушка Леши и еще несколько его друзей. Сервис работает на nginx и gunicorn вот уже пару дней, но в один момент число клиентов резко выросло. Ресурсы сервера смогли отмасштабироваться, но воркер-ноды упали. А кривой код, взятый со Stack Overflow, удалил все подчистую.
Итого: бабушка разочаровалась в проекте внука, а он остался с голым репозиторием. По какой-то причине последний коммит был сделан месяц назад, поэтому даже скрипты восстановить не удалось. Как можно было этого избежать?
Простые решения для бэкапов
Каким-то образом удалось все восстановить, где-то — разработать заново. Наш герой добавил воркер-нод — и все работает, хотя осадочек остался. Начинающий сисадмин решает, что пора делать бэкапы.
Снапшоты
Выбор подходящего инструмента резервного копирования — это настоящий квест. Нужно учесть целый ряд факторов, включая финансовую составляющую, и помнить о том, что это стратегически важный аспект для проекта.
Пока сервисом Леши пользуется не так много человек и объемы данных не слишком велики, можно ограничиться ручным резервированием и сохранять полностью ОС сервера. В облаке Selectel для этого можно использовать снапшоты, образы и бэкапы по кнопке. Наш сисадмин выбрал пока первый вариант, и вот почему:
Снапшот — это мгновенный снимок состояния диска на определенный момент времени. Он хранится там же, где и диск, что снижает безопасность, но позволяет быстро «откатить» диск к состоянию до внесения изменений.
Герой воспользовался снапшотами, но спустя время понял, что полагаться на собственный код не стоит, ведь он может снести весь диск и даже больше. Это особенно критично, так как на нем загружены резервные копии. Поэтому Леша предпочел снапшотам хранение образов.
Образы
Пока сервисом пользовались три клиента, все было нормально. Но потом случилось непредвиденное: после публикации статьи на Хабр людям стало интересно, что разрабатывает сисадмин Леша, и десятки человек зарегистрировались в его сервисе. Кривой код никуда не делся, но в этот раз ничего не рухнуло. В любом случае, причин для волнения нет: герой перестраховался и сохранил образ диска.
Однако спустя время, когда аудитория познакомилась с сервисом и удалилась оттуда с разочарованием, оказалось, что образ системы не смог точно сохранить состояние диска. В момент, когда сисадмин нажал кнопку, один из пользователей загружал архив с 4k-видео. Если его восстановить из образа, окажется, что файлы битые.
Позже выяснилось, что для консистентного результата образ нужно создавать в такой момент, чтобы данные не менялись в процессе копирования. Для столь динамических систем, как сервис Леши, нужно другое решение.
Бэкапы по кнопке
Альтернативное и, наверное, самое подходящее решение для ручного бэкапирования данных с сервера Леши — бэкапы по кнопке. Это функция в панели управления, которая позволяет единоразово зафиксировать состояние диска в данный момент времени. И самое главное: в отличие от снапшотов, все данные хранятся отдельно от дисков.
Автоматизация бэкапов по времени
Шло время, годы, зимы — число пользователей росло, а вместе с ними — риски потерпеть фиаско. А такое может случиться, если в один злополучный момент забыть нажать на кнопку и сервер упадет. Нужно хотя бы минимально автоматизировать бэкапы, чтобы копии диска создавались по расписанию, без участия человека.
Бэкапы по расписанию
За решением далеко ходить не пришлось. Оказалось, в панели управления можно легко настроить бэкапы по расписанию. Эта функция позволяет автоматически создавать резервные копии.
Можно сказать, что это самый простой способ настройки автоматических бэкапов — как полных, так и инкрементальных. Достаточно перейти в раздел Облачная платформа → Бэкапы, нажать Создать план, настроить расписание, указать тип бэкапов (полные или инкрементальные) и их количество (можно сохранять до 90 копий) и выбрать диски, которые нужно забэкапировать.
Полный бэкап — это полная резервная копия диска со всеми данными.
Инкрементальный бэкап — это копия изменений между текущим состоянием диска и предыдущим бэкапом, созданным по плану. Такой бэкап создается быстрее, чем полный, и занимает меньше места, потому что хранит только изменения на диске.
Готово — больше ничего настраивать не нужно: резервные копии будут создаваться полностью автоматически.
Кастомные бэкапы на лету
Леша опробовал бэкапы по расписанию — ему все понравилось. Сервис стал более отказоустойчивым и внешне привлекательным, а число пользователей выросло. О проекте узнали во всех дворах родного города героя.
В какой-то момент на сервере накопилось много мусора, который не хотелось бы бэкапить. Кроме того, пользователей стало уже настолько много, что нельзя делать бэкапы с заданной периодичностью — фотографии должны дублировать себя прямо в момент загрузки, «на лету».
Леша нашел способ решения проблемы. Он может на стороне сервера обозначить, какие данные нужно бэкапировать, чтобы не сохранять состояние всей операционной системы, и по API отправлять их в объектное или файловое хранилище.
По сравнению с остальными способами, это довольно сложная задача, но нашему герою все нипочем. Впрочем, на одних словах объяснять бессмысленно. Посмотрим, как сисадмин Леша настроил кастомные бэкапы «на лету».
На примере файлового хранилища
Первый вариант — делать бэкапы в файловое хранилище. Его можно в рамках подсети примонтировать к серверу как обычный диск, упростив загрузку резервных копий.
Создание хранилища
Для начала работы необходимо создать само файловое хранилище в панели управления. Это можно сделать через раздел Файловое хранилище, указав имя, пул, необходимый диск (базовый HDD, универсальный или быстрый SSD) и его объем.
Также нужно указать используемый протокол. Если будете подключать хранилище к серверу на базе Linux — используйте NFSv4, а если на Windows — CIFS SMBv3.
Монтирование хранилища
Далее нужно подключиться к серверу, установить протокол для работы с NFS, создать папку для монтирования хранилища и подключить его.
sudo apt install nfs-common
sudo mkdir -p /mnt/nfs
sudo mount -vt nfs "<filestorage_ip_address>:/shares/share-<mountpoint_uuid>" /mnt/nfs
Здесь <filestorage_ip_address> — IP-адрес файлового хранилища, который можно узнать из панели управления в разделе Облачная платформа → Файловое хранилище → <страница хранилища> → Настройки. А <mountpoint_uuid> — ID точки монтирования.
Автоматизация резервного копирования
Почти готово — с файловым хранилищем уже можно работать как с обычным диском. Все, что попадет в примонтированную директорию, автоматически загрузится на отдельный сервер, которому не страшны сбои на основной машине.
Но бэкапить данные с помощью команды cp — это как минимум странно. Процесс нужно автоматизировать. Сделать это довольно просто: достаточно написать Python-скрипт, который будет записывать данные в каталог примонтированного файлового хранилища /mnt/nfs.
import os
import shutil
…
def unpack_img(self):
img_path_all = dict([])
# распаковываем загруженные изображения
for img_path in self.images_paths.values():
img_path_all.append(img_path)
# бэкапим данные через NSF
shutil.copy(img_path, '/mnt/nfs')
Готово! Теперь каждый раз, когда пользователи загружают изображения в облачный сервис Леши, они дублируются в примонтированное файловое хранилище.
На примере объектного хранилища
Как говорили выше, в задаче Леши можно использовать как файловое, так и объектное хранилище. Какое именно решение выбрал наш герой — пусть останется тайной. Но давайте посмотрим, как можно бэкапировать изображения в объектное хранилище.
Создание хранилища
Для начала работы необходимо создать объектное хранилище в панели управления. Это можно сделать через раздел Объектное хранилище, настроив отдельный контейнер для хранения данных и пользователя, связанного с ним.
После создания пользователя необходимо выдать S3-ключ для доступа к контейнеру объектного хранилища. Это можно сделать в разделе Профиль и настройки → Управление пользователями → Сервисные пользователи → <имя пользователя>.
Автоматизация резервного копирования
Теперь к объектному хранилищу можно подключиться и закачать все необходимые данные. О том, как это сделать, хорошо написано в документации. Достаточно выбрать протокол передачи данных, составить и отправить cURL-запрос с загрузкой файлов. Однако есть и более элегантные решения, как в случае Леши.
Проект героя построен на Django — в сети как раз есть готовый модуль для работы с объектным хранилищем из веб-приложения. Достаточно установить его внутрь виртуального окружения, добавить в настройки Django-проекта данные от сервисного пользователя S3 и описать алгоритм бэкапа.
SELECTEL_STORAGES = {
'default': {
'USERNAME': os.getenv('STORAGE_ACCESS_USERNAME'),
'PASSWORD': os.getenv('STORAGE_ACCESS_PASSWORD'),
'CONTAINER': 'trex.backups',
},
}
from managers import s3_storage
...
def unpack_img(self):
def backup_img(paths_and_urls:dict):
# загружаем файлы в хранилище
image_urls = s3_storage.upload_file(paths_and_urls=paths_and_urls)
# логируем ссылки на копии файлов
logger.write_backup(image_urls)
from_path_to_url = dict([])
# распаковываем загруженные изображения
for image_key in self.images_paths.keys():
new_images_path = os.path.join(self.extract_dir_img, image_key.split('/')[-1])
from_path_to_url[self.images_paths[image_key]] = new_images_path
# бэкапим данные
backup_img(from_path_to_url)
Готово — теперь при загрузке любых файлов происходит автоматический бэкап в объектное хранилище Selectel. Бэкап на лету — наиболее отказоустойчивый вариант, который позволяет избежать ситуации, когда из-за падения сервера и большой периодичности резервного копирования теряется часть данных.
Коробочные решения для бэкапов
Спустя еще некоторое время проект Леши разросся настолько, что нужно было централизованно управлять резервным копированием приложений, баз данных, томов, файлов физических и виртуальных машин.
Бэкапить с плеча уже не получится. Копировать все ОС попросту нерационально, поскольку данные будут неструктурированно храниться в виде снапшотов или образов — для больших проектов это неудобно. Бэкапить только фотографии и файлы пользователей можно, но это не единственные данные, которые нуждаются в «подстраховке».
Резервное копирование агентами
Нужно решение, которое позволит удобно и структурировано бэкапировать данные из «единого окна», чтобы упростить управление инфраструктурой. Писать собственный софт — слишком ресурсозатратно и рискованно, поскольку клиентская база у такого решения будет ограничена.
В любой момент могут всплыть баги, которые не были обнаружены во время самотестирования. Один из альтернативных вариантов — использовать готовый сервис резервного копирования агентами на базе Veeam Agent.
Veeam Agent — это утилита, с помощью которой можно делать бэкапы физических и виртуальных машин под управлением основных операционных систем (Windows, Linux и macOS). При этом серверы могут располагаться в любом дата-центре, у любого провайдера или даже на on-premise площадке.
Для создания бэкапа на сервер устанавливается Veeam Backup Agent — именно он выполняет резервное копирование данных. А также Management Agent, который позволяет управлять параметрами бэкапов с помощью портала самообслуживания.
Портал самообслуживания — это веб-интерфейс, с помощью которого можно устанавливать и обновлять агенты, настраивать политики бэкапов и другое. Так, например, можно установить периодичность, с которой Backup Agent будет загружать резервные копии в облачный репозиторий.
Сисадмин Леша настроил резервное копирование агентами — теперь ему доступно инкрементальное копирование всех типов данных. Бэкапирование происходит по принципу «замещение блоков со старыми данными на новые». Сперва выполняется копирование всей информации, потом создаются бэкапы файлов, которые изменились со времени последнего резервного копирования. Такой подход значительно ускоряет процесс создания копий и уменьшает их размеры.
Заключение
Есть разные способы, как настроить бэкапы. Главное, чтобы выбранный способ решал задачу. Но помните: не всегда нужно бэкапить все или настраивать инкрементальное резервное копирование, чтобы обеспечить сохранность данных. Выбор подхода зависит от масштабов вашего проекта и предпочтений. Это на своем примере доказал сисадмин Леша.