Привет, Хабр!
Сегодня я хочу рассказать о нашем опыте автоматизации резервного копирования больших данных хранилищ Nextcloud в разных конфигурациях. Я работаю СТО в «Молния АК», где мы занимаемся конфигурационным управлением IT систем, для хранения данных используется Nextcloud. В том числе, с распределенной структурой, с резервированием.
Проблемы вытекающие из особенностей инсталляций в том, что данных много. Версионирование которое дает Nextcloud, резервирование, субъективные причины, и другое создает много дублей.
Предыстория
При администрировании Nextcloud остро встает проблема организации эффективного бэкапа который нужно обязательно шифровать, так как данные ценны.
Мы предлагаем варианты хранения бэкапа у нас или у заказчика на его отдельных от Nextcloud машинах, что требует гибкого автоматизированного подхода к администрированию.
Клиентов много, все они с разными конфигурациями, и все на своих площадках и со своими особенностями. Тут стандартная методика когда вся площадка принадлежит тебе, и бэкапы делаются из крона подходит плохо.
Для начала посмотрим на вводные данные. Нам нужно:
- Масштабируемость в плане одна нода или несколько. Для крупных исталляций мы используем в качестве хранилища minio.
- Узнавать о проблемах с выполнением бэкапа.
- Нужно хранить бэкап у клиентов и/или у нас.
- Быстро и легко разбираться с проблемами.
- Клиенты и установки сильно отличаются один от другого — единообразия добиться не получается.
- Скорость восстановления должна быть минимальна по двум сценариям: полное восстановление (дизастер), одна папка — стерто по ошибке.
- Обязательна функция дедупликации.
Для решения задачи управления бекапами мы прикрутили GitLab. Подробнее подкатом.
Безусловно, мы не первые кто решает подобную задачу, но нам кажется что наш практический выстраданный опыт может быть интересным и мы готовы им поделиться.
Поскольку в нашей компании принята политика opensource, решение мы искали именно с открытым исходным кодом. В свою очередь мы делимся своими разработками, и выкладываем их. Например, на GitHub есть наш плагин для Nextcloud, который мы ставим клиентам, усиливающий сохранность данных на случай случайного или преднамеренного удаления.
Средства бэкапирования
Поиск методов решения мы начали с выбора средства создания бэкапа.
Обычный tar + gzip работает плохо — данные дублируются. Инкремент часто содержит очень мало изменений по факту, и большая часть данных внутри одного файла повторяется.
Есть еще одна проблема — избыточность распределенного хранилища данных. Мы используем minio и его данные в принципе избыточны. Либо нужно было бэкап делать через сам minio – нагружать его и пользоваться всеми прокладками между файловой системой, и что не менее важно, есть риск забыть про часть бакетов и мета-информации. Либо использовать дедупликацию.
Средства бэкапирования с дудпликацией есть в опенсорсе (на хабре были статьи на эту тему) и нашими финалистами стали Borg и Restic. О нашем сравнении двух приложений ниже, а пока расскажем как мы организовали всю схему.
Управление созданием резервных копий
Borg и Restic хороши, но ни тот ни другой продукт не имеет централизованного механизма управления. Для цели управления и контроля мы выбрали инструмент который и так у нас внедрен, без которого мы не мыслим свою работу, в том числе по автоматизации — это известный CI/CD – GitLab.
Идея состоит в следующем: на каждую ноду хранящую данные Nextcloud ставится gitlab-runner. Раннер запускает по расписанию скрипт следящий за процессом бэкапирования, и тот запускает Borg или Restic.
Что мы получили? Обратную связь от выполнения, удобный контроль за изменениями, подробности в случае ошибки.
Вот здесь на GitHub мы выложили примеры скрипта для разных задач, а мы его в итоге прикрутили к бэкапу не только Nextcloud, но и многих других сервисов. Там же лежит планировщик, если неохота руками его настраивать (а нам неохота) и .gitlab-ci.yml
В API гитлаба пока нет возможности менять таймаут CI/CD, а он там небольшой. Его надо увеличить, скажем до 1d
.
GitLab к счастью умеет запускать не только по коммиту, но только по расписанию, это ровно то что нам надо.
Теперь о скритпе-обертке.
Мы поставили такие условия для этого скрипта:
- Должен запускаться как раннером, так и руками из консоли с одинаковым функционалом.
- Обязательно должны быть обработчики ошибок:
- return code.
- поиск строки в логе. Например, для нас ошибкой может быть сообщение которое программа фатальной не считает.
- Обработка timeout. Время выполнения должно быть разумным.
- Нам нужен подробнейший лог. Но только в случае ошибки.
- Так же проводится ряд тестов перед началом.
- Небольшие плюшки для удобства, которые мы нашли полезными в процессе поддержки:
- Запуск и окончание фиксируется в сислоге локальной машины. Это помогает связать системные ошибки и работу бэкапа.
- Часть лога ошибок, когда они есть, выдается в stdout, весь лог пишется в отдельный файл. Удобно сразу глянуть в CI и оценить ошибку если она тривиальная.
- Режимы для дебага.
Полный лог сохраняется в виде артефакта в GitLab, если ошибки нет, то лог удаляется. Скрипт пишем на bash.
Любые предложения и замечания по опенсорсу будем рады рассмотреть — welcome.
Как это работает
На бэкапируемой ноде запускается раннер с башевским экзекьютером. По планировщику в специальной репе запускается job CI/CD. Раннер запускает скрипт универсальную обертку для таких задач, в нем проходят проверки валидности репозитория бэкапа, точек монтирования и всего что захотим, затем выполняется бэкапирование и очистка старого. Сам готовый бэкап отправляется на S3.
Мы работаем по такой схеме — это внешний провайдер AWS или российский аналог (это быстрее и данные не покидают РФ). Либо клиенту ставим отдельный minio кластер на его площадке для этих целей. Обычно так делаем по соображениям безопасности, когда клиент совсем не хочет чтобы данные покидали их контур.
Пользоваться фичей отправки бэкапа по ssh мы не стали. Безопасности это не добавляет, а сетевые возможности провайдера S3 сильно выше одной нашей ssh машины.
Для того чтобы обезопасить от хакера на локальной машине — ведь он может стереть данные на S3, обязательно нужно включить версионирование.
бэкапер всегда шифрует бэкап.
У Borg есть режим без шифрования none
, но мы категорически не рекомендуем его включать. В этом режиме не будет не только шифрования, но не вычисляется контрольная сумма того что записывается, а значит целостность проверить можно только косвенно, по индексам.
По отдельному шедулеру производится проверка бэкапов на целостность индексов и содержимого. Проверка происходит медленно и долго, поэтому мы запускаем ее отдельно раз в месяц. Может идти несколько суток.
Ридми на русском
Основные функции
prepare
подготовкаtestcheck
проверка готовностиmaincommand
основная командаforcepostscript
функция которая выполняется вконце или по ошибке. Используем чтобы отмонтировать раздел.
Service functions
cleanup
записываем ошибки или стираем лог файл.checklog
парсим лог на вхождение строки с ошибкой.ret
exit handler.checktimeout
проверка на таймаут.
Environment
VERBOSE=1
выводим ошибки на экран сразу (stdout).SAVELOGSONSUCCES=1
сохраняем лог при успехе.INIT_REPO_IF_NOT_EXIST=1
Создаем репозиторий, если его не было. По-умолчанию выключено.TIMEOUT
максимальное вермя на основную операцию. You can set it as 'm', 'h' or 'd' at the end.
Режим храниения старых копий. По-умолчанию:
KEEP_DAILY=7
KEEP_WEEKLY=4
KEEP_MONTHLY=6
Переменные внутри скрипта
ERROR_STRING
— string for the check in log for error.EXTRACT_ERROR_STRING
— expression for show string if error.KILL_TIMEOUT_SIGNAL
— signal for killing if timeout.TAIL
— how many strings with errors on screen.COLORMSG
— color of mesage (default yellow).
Тот скрипт, который называется wordpress носит название условно, его фишка в том, что он еще бэкапит базу mysql. А значит может применяться для однонодовых установок Nexcloud, где можно заодно и забэкапить базу. Удобство не только в том, что все в одном месте, но и содержимое базы близко к содержимому файлов, так как разница во времени минимальна.
Restic vs Borg
Сравнения Borg и Restic есть в том числе здесь на Хабре, и у нас не было задачи сделать просто еще одно, но своё. Нам было важно как это будет выглядить на наших данных, с нашей спецификой. Мы их приводим.
Наши критерии выбора, помимо уже упоминавшихся (дедупликация, быстрое восстановление и пр.):
- Устойчивость к незавершенной работе. Проверка на kill -9.
- Размер на диске.
- Требовательность к ресурсам (ЦПУ, память).
- Размер хранимых блобов.
- Работа с S3.
- Проверка целостности.
Для тестирования мы взяли одного клиента с реальными данными и общим размером 1,6Тб.
Условия.
Borg не умеет напрямую работать с S3, и мы монтировали как fuse диск, через goofys. Restic отправлял в S3 сам.
Goofys работает очень быстро и хорошо, и к нему есть модуль дискового кеша, что еще больше ускоряет работу. Он находится в стадии beta, и, признаться, у нас падал с потерей данных на тестах (других). Но удобство в том, что сама процедура бэкапа не требует большого чтения, а в основном запись, поэтому кеш мы используем только во время проверки целостности.
Чтобы снизить влияние сети, использовали местного провайдера — Яндекс Облако.
Результаты тестирования сравнения.
- Kill -9 с дальнейшим перезапуском оба прошли успешно.
- Размер на диске. Borg умеет сжимать поэтому результаты ожидаемые.
Backuper | Размер |
---|---|
Borg | 562Gb |
Restic | 628Gb |
- По CPU
Сам по себе borg расходует мало, с дефолтным сжатием, но оценивать надо вместе с процессом goofys. В сумме они сравнимы и утилизируют около 1,2 ядра на одной и той же тестовой виртуалке. - Память. Restic приблизительно 0,5Гб, Borg около 200Мб. Но это все незначительно в сравнении с файловым кешем системы. Так что памяти желательно выделять побольше.
- Разница в размере блобов оказалась разительной.
Backuper | Размер |
---|---|
Borg | около 500Мб |
Restic | около 5Мб |
- Работа с S3 от Restic отличная. Работа Borg через goofys вопросов не вызывает, но замечено, что желательно по окончании бэкапа делать umount чтобы полностью сбросить кеш. Особенность работы S3 в том, что недокачанные чанки никогда не будут отправлены в бакет, а значит не полностью залитые данные приводят к большим повреждениям.
- Проверка целостности работает хорошо в обоих случаях, но скорость отличается значительно.
Restic – 3,5 часа.
Borg, с файловым кешем в 100Гб SSD – 5 часов.Приблизительно такой же результат по скорости если данные лежат на локальном диске.
Borg читает прямо с S3 без кеша 33 часа. Чудовищно долго.
В сухом остатке Borg умеет сжимать и имеет бОльшие блобы — что делает более дешевым хранение и операции GET/PUT в S3. Но за это приходится платить более сложной и медленной проверкой. Что касается скорости восстановления — то мы разницы не заметили. Последующие бэкапы (после первого) restic делает несколько дольше, но не существенно.
Не на последнем месте в выборе стоял размер коммьюнити.
И мы выбрали borg.
Пару слов о сжатии
У Borg’а есть в арсенале прекрасный новый алгоритм сжатия — zstd. По качеству сжатия не хуже gzip, но значительно быстрее. И сравним по скорости с дефотным lz4.
Например дамп MySQL базы сжимается раза в два лучше lz4 при той же скорости. Однако, опыт на реальных данных показывает, что очень небольшую разницу в степени сжатия ноды Nextcloud .
В Borg есть довольно бонусный режим сжатия — если файл имеет большую энтропию, то сжатие не применяется вообще, что увеличивает скорость работы. Включается опцией при создании
-C auto,zstd
для алгоритма zstd
Так вот с этой опцией в сравнении со сжатием по-умолчанию мы получили
560Gb и 562Gb соответственно. Данные из примера выше, напомню, без сжатия результат 628Gb. Результат в 2Гб разницы несколько нас удививший, но мы посчитали что выберем все-таки auto,zstd
.
Методика проверки бэкапа
По планировщику запускается виртуалка прямо у провайдера или у клиента, что сильно снижает сетевую нагрузку. Как минимум это дешевле, чем поднимать у себя и гонять трафик.
goofys --cache "--free:5%:/mnt/cache" -o allow_other --endpoint https://storage.yandexcloud.net --file-mode=0666 --dir-mode=0777 xxxxxxx.com /mnt/goofys
export BORG_PASSCOMMAND="cat /home/borg/.borg-passphrase"
borg list /mnt/goofys/borg1/
borg check --debug -p --verify-data /mnt/goofys/borg1/
По этой же схеме мы проверяем файлы антивирусом (постфактум). Ведь пользователи заливают разное в Nextcloud и не у всех есть антивирус. Проводить проверку в момент заливки занимает слишком много времени, и мешает бизнесу.
Масштабируемость достигается запуском раннеров на разных нодах с разными тегами.
В нашем мониторинге собираются статусы бэкапов через API GitLab в одном окне, при необходимости проблемы легко замечаются, и так же легко локализуются.
Заключение
Как итог мы точно знаем что бэкапы мы делаем, что наши бэкапы валидные, проблемы которые с ними возникают занимают мало времени и решаются на уровне дежурного администратора. Бэкапы занимают реально мало места в сравнении с tar.gz или Bacula.