Borg решает задачи хранения, передачи, очистки, сжатия, шифрования,
дедупликации и защиты резервных копий, а также разграничивает доступ к
различным репозиториям с резервными копиями. В этой статье мы рассмотрим
использование инструмента borgbackup для упрощения построения системы
резервного копирования. Единственный аспект, который я опущу в этой статье
- шифрование. Если для вас принципиально шифровать свои бекапы, то в этом
нет никакой проблемы - в официальной документации описано как
использовать шифрование и вы легко сможете использовать шифрование с
предложенными мной решениями.
Также borg не занимается подготовкой данных для резервирования и их
восстановлением. На входе и выходе вы получаете только файлы, а что и как с
ними делать - решать вам. Если скомандуете "положи в бекап каталог с
файлами баз mysql", то borg это сделает, но на выходе вы получите кашу вместо
данных. Консистентность - это ваша задача и её обсуждение выходит за
рамки этой статьи. Для решения этой задачи используется множество инструментов,
зависящих от службы, данные которой вы собираетесь копировать - будь то
mysqldump, снапшоты lvm, zfs или виртуальных машин.
Borg представляет из себя единственный исполняемый файл. Отдельной службы,
которая следит за бекапами у него нет, поэтому автоматизировать его работу
придется самостоятельно. Он хранит резервные копии в репозиториях, которые
представляют собой простые каталоги с файлами. Вы можете получать доступ к ним
как локально, указав путь, так и по сети. Для доступа по сети используется ssh.
Важной функцией borg, наличие которой повлияло на выбор именно этой системы,
является возможность разграничения доступа клиентов по ключам, используемым для
входа на сервер с бекапом.
В статье мы рассмотрим организацию резервного копирования на предприятии, в
котором я работаю. Вам не обязательно всё делать так же - решения,
применяемые нами, не обязательно должны подходить всем и могут быть не
оптимальными для вас.
Установка
В большинстве дистрибутивов уже есть пакет borgbackup и можно просто установить этот пакет.
Для CentOS
sudo yum install borgbackup
Для Debian/Ubuntu
sudo apt install borgbackup
Или можно скачать исполняемый файл и установить его в систему. Скачиваем его со этой
страницы и выполняем
sudo cp borg-linux64 /usr/local/bin/borg
sudo chown root:root /usr/local/bin/borg
sudo chmod 755 /usr/local/bin/borg
Подробнее об установке на другие дистрибутивы
Borg необходимо установить как на сервере так и на клиентах.
Настройка сервера. Часть 1
Подготовив пространство для хранения бекапов, создадим пользователя с домашним
каталогом в этом пространстве. В моё случае это пользователь borg с домашним
каталогом /backup/borg
adduser --home /backup/borg --disabled-password borg
Доступ к пользователю borg сделаем только по ключам, поэтому вход с пустым
паролем по ssh должен быть отключён. Во всех известных мне дистрибутивах это
сделано по умолчанию.
Поправим две опции в конфиге ssh-сервера /etc/ssh/sshd_config
ClientAliveInterval 10
ClientAliveCountMax 30
Перезапустим ssh-сервер
sudo systemctl restart sshd
Зайдем в сеанс пользователя borg
sudo -i -u borg
Подготовим ssh
mkdir .ssh
touch .ssh/authorized_keys
chmod 700 .ssh
chmod 600 .ssh/authorized_keys
Теперь создадим репозиторий
borg init -e none MyRepo
В домашнем каталоге появится каталог репозитория MyRepo. На этом первоначальная
настройка сервера закончена.
В качестве имени сервера будем использовать backup.foo.
Настройка клиента
У пользователя, от имени которого будет запускаться скрипт, должен быть
ssh-ключ. Если его нет, то генерируем его, выполнив команду от имени этого пользователя
ssh-keygen
Теперь нужно настроить отправку файлов бекапа на сервер. Как уже говорилось
выше, borg занимается только хранением файлов - их подготовка ваша
задача. Создадим скрипт /usr/local/bin/backup.sh, который будет готовить данные
и отправлять их в бекап.
#!/bin/bash
####
#Готовим данные и копируем их в каталог /var/backup
#Если данные не нуждаются в подготовке, то этот этап пропускаем
#и вместо /var/backup указываем каталог с данными
####
borg create -C lz4 borg@backup.foo:MyRepo::`date +%Y%m%d_%H%M%S` /var/backup
Последняя команда отправит файлы из каталога /var/backup на сервер backup.foo,
в репозиторий MyRepo, в бекап с названием в виде текущей даты/времени, сжатый
алгоритмом lz4.
Настраиваем cron на выполнение этого скрипта от имени нужного вам пользователя
по расписанию на ваше усмотрение.
Забираем с клиента файл id_rsa.pub и продолжаем настраивать сервер.
Настройка сервера. Часть 2
Снова заходим в сеанс пользователя borg
sudo -i -u borg
На этот раз редактируем файл .ssh/authorized_keys. Добавляем строку
command="/usr/bin/borg serve --restrict-to-repository /backup/borg/MyRepo --append-only",restrict <user key>
Теперь обладатель ключа, зайдя на сервер backup.foo под логином borg, получит
возможность создавать и просматривать бекапы только в репозитории MyRepo и ни в
каком более. Также обладатель этого ключа не сможет получить shell
пользователя, а значит взлом клиента не даст злоумышленнику испортить ваши
бекапы или даже заглянуть в другие репозитории. Это существенно поднимает
безопасность реализованной схемы. Но в данном решении есть не очевидный нюанс,
о котором ниже.
Опция --append-only
Механизм --append-only реализован не совсем интуитивно. Дело в том, что при
использовании borg с этим ключом, разрешено добавлять данные, а команды на
удаление пишутся в журнал транзакций, но не применяются по настоящему. По
команде delete или prune, с опцией --append-only, borg сделает вид, что бекапы
удалены, но на самом деле записывает команды в журнал и перестает отображать
бекапы в списке. Изменения будут применены в момент выполнения любой команды,
подразумевающей внесение изменений в репозиторий, без ключа --append-only,
например create, delete или prune.
Подробнее эта особенность обсуждается здесь.
Как мы обошли эту проблему при автоматизации удаления старых бекапов я покажу ниже.
Настройка сервера. Часть 3
Теперь мы автоматизируем удаление старых бекапов, чтобы не занять всё место на
сервере. Настроим всё так, чтобы хранить последние 14 копий с интервалом в
день, 8 копий с интервалом в неделю и 12 копий с интервалом в месяц. Также мы
обойдем проблему с неочевидным поведением опции --append-only.
Заходим в сеанс пользователя borg
sudo -i -u borg
Поместим список имеющихся репозиториев в файл repo.list
echo MyRepo > repo.list
Создадим пустой файл backup.list в каталоге репозитория
touch MyRepo/backup.list
Создадим настройку политики хранения копий, описанную выше
echo "--keep-daily 14 --keep-weekly 8 --keep-monthly 12" > MyRepo/trim.conf
Подготовим скрипт /usr/local/bin/trim.sh
#!/bin/bash
HOME_DIR="/backup/borg/"
REPO_LIST=`cat ${HOME_DIR}/repo.list`
alarm(){
####
#Тут нужно предусмотреть отправку оповещения
####
}
trim_repo(){
#Получаем путь до репозитория и настройку сохранения бекапов
REPO_DIR="${HOME_DIR}${1}"
TRIM_CONF=`cat ${REPO_DIR}/trim.conf`
#Получаем список бекапов в репозитории
borg list --format '{id}{NL}' "${REPO_DIR}" > ${REPO_DIR}/backup_new.list
#Ищем каждый ID из старого списка в новом. Если не нашли хотябы один бекап,
#то код возврата будет 1. Если всё хорошо, то 0.
cat ${REPO_DIR}/backup.list \\
| awk -v dir=${REPO_DIR} '{print "grep -q " $0 " " dir "/backup_new.list || exit 1" }' \\
| bash
exit_code=$?
if [[ $exit_code -gt 0 ]]; then
#Если хотябы один ID не найден, то оповещаем ответственного за бекап человека
alarm "В бекапе ${1} не хватает копий. Trim остановлен."
else
#Если старые бекапы на месте, то делаем trim, сохраняем новый список бекапов и удаляем старый
borg prune ${TRIM_CONF} ${REPO_DIR}
borg list --format '{id}{NL}' ${REPO_DIR} > ${REPO_DIR}/backup.list
rm ${REPO_DIR}/backup_new.list
fi
}
for REPO in ${REPO_LIST}; do
trim_repo ${REPO}
done
Этот скрипт будет проверять на месте ли бекапы, которые лежали в репозитории
после прошлого запуска и если ни один из них не пропал, то выполняет удаление
старых копий, не попадающих под шаблон. Как видите скрипт рассчитан на то, что
у вас будет множество репозиториев с разными настройками хранения.
Политика хранения копий
Для настройки того сколько и каких копий будет хранить borg мы использовали
опции, с которыми вызывалась команда prune, записанные в файле trim.conf.
Рассмотрим возможные опции подробнее
--keep-within INTERVAL храним все архивы в течение указанного промежутка времени
--keep-last, --keep-secondly сколько последних копий хранить
--keep-minutely сколько поминутных архивов хранить
-H, --keep-hourly сколько почасовых архивов хранить
-d, --keep-daily сколько ежедневны архивов хранить
-w, --keep-weekly сколько еженедельных архивов хранить
-m, --keep-monthly сколько ежемесячных архивов хранить
-y, --keep-yearly сколько ежегодных архивов хранить
Команда prune удалит архивы, которые не попали под указанные опции.
Опция --keep-within принимает аргумент вида "<int><char>", где char-это "H",
"d", "w", "m", "y". Например, --keep-within 2d означает, что все архивы,
созданные за последние 48 часов удалять нельзя. "1m" означает "31d". Архивы,
попадающие под этот шаблон, не учитываются в других опциях при построении
списка сохраняемых архивов.
Откат команд удаления
Для возврата бекапов, удалённых в режиме --append-only, нужно понять в какой
момент произошло удаление и удалить транзакции, содержащие команды на удаление.
Список транзакций находится в файле transactions, в каталоге репозитория. Поняв
когда произошли вредоносные изменения, нужно удалить файлы транзакций с
номерами вредоносной и всех последующих. Например если мы видим вот такой лог
transaction 1, UTC time 2016-03-31T15:53:27.383532
transaction 5, UTC time 2016-03-31T15:53:52.588922
transaction 11, UTC time 2016-03-31T15:54:23.887256
transaction 12, UTC time 2016-03-31T15:55:54.022540
transaction 13, UTC time 2016-03-31T15:55:55.472564
И выяснили, что последняя легитимная транзакция имеет номер 5, то нужно удалить
все транзакции после 5. Для этого в каталоге с репозиторием выполняем
rm data/**/{6..13}
borg delete --cache-only <имя репозитория>
Это действие вызовет предупреждение со стороны клиентов borg при следующем
обращении к репозиторию и просьбу подтвердить продолжение.
Поэтому, если предполагается продолжить использование этого репозитория
настроенными на него клиентами, то на всех нужно выполнить list репозитория и
согласится использовать репозиторий. Либо на клиентах удалить файл
rm ~/.config/borg/security/REPOID/manifest-timestamp
Подробнее всё это описано здесь
Извлечение и монтирование бекапов
Вы можете добавить добавить свой ssh-ключ для пользователя borg без опций
--restrict-to-repository и --append-only, для управления репозиториями со
своего рабочего места. В этом случае команды будут выглядеть так.
Получить список бекапов в репозитории
borg list borg@backup.foo:<репозиторий>
Получить список файлов в бекапе
borg list borg@backup.foo:<репозиторий>::<имя бекапа>
Извлекаем весь бекап или его часть в текущий каталог
borg extract borg@backup.foo:<репозиторий>::<имя бекапа> [что извлекаем]
Монтируем бекап с помощью механизма FUSE
borg mount -o users borg@backup.foo:<репозиторий>::<имя бекапа> <точка монтирования>
При монтировании могут возникнуть проблемы с правами доступа к файлам. В этом
случае можно смонтировать через sudo, переопределив команду ssh. В этом случае
ходить по смонтированному бекапу также придется с помощью sudo
sudo borg mount -o users --rsh "ssh -i <ваш ключ>" borg@backup.foo:<репозиторий>::<имя бекапа> <точка монтирования>
Отмонтируем командой
borg umount <точка монтирования>
При извлечении и монтировании можно исключить файлы по шаблону ключом --exclude.
Заключение
На этом всё. Я надеюсь, что эта статья станет хорошей отправной точкой при
проектировании или модернизации вашей схемы резервного копирования. Borg
старается следовать философии unix и хорошо занимается одним делом -
управляет архивами. Используя этот инструмент вы сможете создать схему
резервного копирования подходящую именно вам.
|