Duplicity – экстремально простой способ резервного копирования
Как гласит старинная шутка, системные администраторы делятся на две группы: те, которые не делают бэкапы, и те, которые уже делают бэкапы. Систем резеревного копирования существует великое множество, от простейшего самописного скрипта до огромных монстров ценой в “боинг”. Все системы нужны для разных целей и выполняют разные задачи.
Основная, самая известная и популярная система в мире unix и linux – это, безусловно, bacula. Умеет bacula очень много - сложные расписания и политики хранения, шифрование данных и клиент-серверного трафика, управление операциями “на ходу”, десятки способов упаковки и проверки данных. Полный список возможностей bacula занимает несколько страниц мелкого текста. Основной минус бакулы находится ровно там, где находится ее плюс. Внедрение и настройка бакулы - это приключение, как минимум, на неделю. Документации очень много (но ее все равно не хватает). Бакула состоит из 4 самостоятельных компонентов (director, storage, filedaemon, console), каждый из которых настраивается и живет отдельно. Все эти компоненты имеют сложные взаимоотношения и должны быть доступны друг другу напрямую, что тоже жизнь не облегчает. Элементарный конфиг bacula легко может весить десятки килобайт (и bacula очень трепетно относится к опечаткам в конфиге - он в лучшем случае вообще не прочитается, а в худшем сервис упадет). В случае, если нужно делать резервные копии с одного-двух серверов - bacula - явный оверкилл. Вместо сложного комбайна нужен простой и понятный молоток. И такой молоток есть - он называется duplicity.
Duplicity - это очень просто. Это одна-единственная команда, которая запускается на том сервере, откуда будут копироваться данные. Все, что она может:
- сделать резервную копию. Резервная копия пакуется в блоки (назывются тома), и, по желанию, шифруются. Резервная копия может быть или полной, или инкрементальной. Уровень определяется возрастом копии - если последняя полная копия старше определенного возраста - будет сделана полная, если нет - инкрементальная копия.
- отправить резервную копию на удаленный сервер. Удаленный сервер может быть rsync, ftp, scp, s3 (вариантов много). Можно хранить прямо в файловой системе. Устройства хранения (ленточные библиотеки, дисковые массивы) – не поддерживатюся.
- найти расходждения между каталогом и определенной версией бекапа. Полезно, чтобы понять, что изменилось с момента бэкапа.
- показать список файлов в бэкапе.
- восстановить файлы из бэкапа (или весь бэкап целиком).
- почистить удаленный сервер от старых бэкапов.
На этом функционал duplicity заканчивается. Ничего сложного, головоломного, неочевидного. Система, понятная, как кирпич.
Установка и настройка
Duplicty входит в пакет с одноименным названием, и устанавливается традиционно для вашей операционной системы:
#debian, ubuntu
apt-get install duplicity
#centos, redhat, fedora
yum install duplicity
Теперь нужно решить, куда будут отправляться пакеты. Duplicty не может работать с удаленным сервером самостоятельно - в зависимости от типа удаленного сервера ему потребуется тот или иной пакет. Сам duplicity только “дирижирует процессом”. Самые ходовые типы серверов и пакеты:
- ftp, ftps (ftp over TLS): ncftp
- rsync: rsync
- s3 (aws S3, openstack swift, ceph object gateway, minio): boto
Если планируется шифровать и/или подписывать бэкап - нужно сгенерировать gpg-ключ. Шифровать бэкап рекомендуется, если нет доверия серверу хранения. Правило хорошего тона гласят, что доверия нет никогда и никому. Помните о том, что бэкап, по сути – отложеное по времени нарушение безопасности. Ключ генерируется вполне традиционым способом:
gpg --gen-key
Параметры ключа (размер, алгоритм) менять не обязательно, они вполне разумны. После окончания генерации GPG вернет идентификатор ключа. Его так же можно посмотреть вот так:
gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub 2048R/F6822D5F 2017-01-28
uid Paul I Rudnitskiy (bck server) <[email protected]>
sub 2048R/292EB891 2017-01-28
ID нам чуть дальше пригодится, рекомендую его запомнить.
Так же очень рекомендуется сделать разеревную копию GPG-ключа. Если бэкап зашифрован - потеря ключа автоматически означает потерю возможности восстановить данные из бэкапа. Выгрузим ключ, чтобы сохранить его в надежное место:
gpg --export-secret-keys -a F6822D5F > backup.asc
Резервное копирование
Общий принцип - duplicity [args] {source} {destination}
. Аргументов множество, ниже я приведу пример и распишу, что означает каждый. Проще всего сделать shell-скрипт с командой и типовыми аргументами, чтобы не вспоминать их каждый раз
duplicity --verbosity notice \
--encrypt-key "F6822D5F" \
--full-if-older-than 14D \
--num-retries 3 \
--asynchronous-upload \
--volsize 100 \
--archive-dir /var/tmp/.duplicity \
--log-file /var/log/duplicity.log \
--exclude "/var/lib/postgresql/9.5/main/archive" \
"/var/lib/postgresql/9.5/main/" \
"ftp://bckuser:[email protected]/pgsql"
На что обратить внимание:
- verbosity - уровень “говорливости” при работе. Рекомендуется info при отладке (показывает файлы и текущие операции) и notice в production (кратко сообщает о текущем этапе работы)
- encrypt-key - ID ключа для шифрования. Важен, если ключей несколько. Если шифровать не нужно - используйте аргумент
--no-encryption
. При шифровании gpg спросит пароль ключа шифрования. Побеждается или настройкой gpg-agent или созданием переменнойPASSPHRASE
с паролем. - full-if-older-than - через срок после создания полной копии нужно сделать не инкрементальную, а снова полную копию. В данном примере - 14 дней.
- volsize - размер одного тома в мегабайтах. Каждый том пакуется и загружается на сервер отдельно, это отдельный файл.
- archive-dir - папка, где duplicity локально хранит метаданные (информацию о томах и их содержимом). Копия метаданных лежит на сервере. Если по какой-то причине метаданные пропадут - duplicity придется скачать копию метаданных с сервера перед началом бэкапа. Размер папки метаданных пропорционально зависит от количества файлов и количества бэкапов, так что стоит выделить ей побольше места.
- exclude - позволяет исключить папку из бэкапа. аргументов exclude может быть несколько.
- destination - последний аргумент, куда копируем данные. Задается в виде классического url. URL для копии в локальную файловую систему имеет вид
file:///path/to/folder
Проверка состояния бэкапов на удаленном сервере:
duplicity collection-status "ftp://bckuser:[email protected]/pgsql" \
--archive-dir /var/tmp/.duplicity
Пример ответа:
NcFTP version is 3.2.5
Local and Remote metadata are synchronized, no sync needed.
Last full backup date: Fri Sep 15 04:10:03 2017
Collection Status
-----------------
Connecting with backend: FTPBackend
Archive dir: /var/tmp/.duplicity/c9edc22d8a99b972fdf4bd3cec26e19f
Found 1 secondary backup chain.
Secondary chain 1 of 1:
-------------------------
Chain start time: Thu Aug 31 04:10:03 2017
Chain end time: Thu Sep 14 04:10:02 2017
Number of contained backup sets: 15
Total number of contained volumes: 252
Type of backup set: Time: Num volumes:
Full Thu Aug 31 04:10:03 2017 137
Incremental Fri Sep 1 04:10:02 2017 6
----------------------------CUT----------------------------------------
-------------------------
Found primary backup chain with matching signature chain:
-------------------------
Chain start time: Fri Sep 15 04:10:03 2017
Chain end time: Fri Sep 29 04:10:03 2017
Number of contained backup sets: 15
Total number of contained volumes: 245
Type of backup set: Time: Num volumes:
Full Fri Sep 15 04:10:03 2017 142
Incremental Sat Sep 16 04:10:02 2017 8
----------------------------CUT----------------------------------------
Incremental Fri Sep 29 04:10:03 2017 7
-------------------------
No orphaned or incomplete backup sets found.
Duplicity не позволяет помечать бэкап как устаревший автоматически (retention в терминологии “взрослых” систем). Чистить ненужные бэкапы придется в ручном режиме:
duplicity --verbosity notice \
--archive-dir /var/tmp/.duplicity \
--force \
remove-all-but-n-full 4 \
"ftp://bckuser:[email protected]/pgsql"
Эта команда удалит все бэкапы старше 4 последних полных бэкапов. В примере выше мы делали полный бекап каждые 2 недели, то есть duplicity удалит бэкапы старше 2 месяцев (8 недель). Если убрать ключ --force
– duplicity найдет старые бэкапы, но не будет их удалять - только выведет на консоль. Забывать о чистке не рекомендуется - место на сервере для резервных копий может неожиданно кончиться и оставить вас без свежих бэкапов. Выясняется это весьма болезненно.
Проверка и восстановление
Посмотрим файлы, которые у нас есть в бэкапе:
duplicity --archive-dir /var/tmp/.duplicity list-current-files \
"ftp://bckuser:[email protected]/pgsql"
Пример ответа:
NcFTP version is 3.2.5
Local and Remote metadata are synchronized, no sync needed.
Last full backup date: Sat Sep 29 04:10:03 2017
Mon Oct 2 04:10:02 2017 .
Mon Aug 29 21:07:04 2016 PG_VERSION
Mon Oct 2 04:10:02 2017 backup_label
-----------------------CUT---------------------------------
Команда выше покажет состояние на момент последнего бэкапа. Чтобы получить информацию из более старых бэкапов, нужно использовать ключ -t
. К примеру, -t6D
вернет информацию о бэкапе, сделаном 6 дней назад.
Восстановление данных выглядит ровно так же, как бэкап, нужно просто поменять местами source (откуда брать данные) и destination:
duplicity --verbosity notice \
--encrypt-key "F6822D5F" \
--archive-dir /var/tmp/.duplicity \
--log-file /var/log/duplicity.log \
"ftp://bckuser:[email protected]/pgsql" \
"/var/lib/postgresql/9.5/main/"
На что обратить внимание:
- Если нужно восстановить бэкап на определенную дату - выручает ключ
-t
- Для восстановления определенного файла нужно использовать ключ
--file-to-restore
. Таких ключей может быть несколько. - Восстановление возможно только в совершенно пустую папку
- Для восстановления duplicity вытащит с сервера резервных копий весь полный бэкап и все инкрементальные бэкапы с момента полного до точки восстановления. Места уйдет много.