Borg решает задачи хранения, передачи, очистки, сжатия, шифрования, дедупликации и защиты резервных копий, а также разграничивает доступ к различным репозиториям с резервными копиями. В этой статье мы рассмотрим использование инструмента borgbackup для упрощения построения системы резервного копирования. Единственный аспект, который я опущу в этой статье — шифрование. Если для вас принципиально шифровать свои бекапы, то в этом нет никакой проблемы — в официальной документации описано как использовать шифрование и вы легко сможете использовать шифрование с предложенными мной решениями.Также borg не занимается подготовкой данных для резервирования и их восстановлением. На входе и выходе вы получаете только файлы, а что и как с ними делать — решать вам. Если скомандуете "положи в бекап каталог с файлами баз mysql", то borg это сделает, но на выходе вы получите кашу вместо данных. Консистентность — это ваша задача и её обсуждение выходит за рамки этой статьи. Для решения этой задачи используется множество инструментов, зависящих от службы, данные которой вы собираетесь копировать — будь то mysqldump, снапшоты lvm, zfs или виртуальных машин.
Borg представляет из себя единственный исполняемый файл. Отдельной службы, которая следит на бекапами у него нет, поэтому автоматизировать его работу придется самостоятельно. Он хранит резервные копии в репозиториях, которые представляют собой простые каталоги с файлами. Вы можете получать доступ к ним как локально, указав пусть, так и по сети. Для доступа по сети используется ssh. Важной функцией borg, наличие которой повлияло на выбор именно этой системы, является возможность разграничения доступа клиентов по ключам, используемым для входа на сервер с бекапом.
В статье мы рассмотрим организацию резервного копирования на предприятии, в котором я работаю. Вам не обязательно всё делать также — решения, применяемые нами, не обязательно должны подходить всем и могут быть не оптимальными для вас.
++ Установка
В большинстве дистрибутивов уже есть пакет borgbackup и можно просто установить этот пакет.
Для CentOS
sudo yum install borgbackup
Для Debian/Ubuntu
sudo apt install borgbackup
Или можно скачать исполняемый файл и установить его в систему. Скачиваем его со этой [[https://github.com/borgbackup/borg/releases страницы]] и выполняем
sudo cp borg-linux64 /usr/local/bin/borg
sudo chown root:root /usr/local/bin/borg
sudo chmod 755 /usr/local/bin/borg
[[https://borgbackup.readthedocs.io/en/stable/installation.html Подробнее]] об установке на другие дистрибутивы
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.
Подробнее эта особенность обсуждается [[https://github.com/borgbackup/borg/issues/3504 здесь]].
Как мы обошли эту проблему при автоматизации удаления старых бекапов я покажу ниже.
++ Настройка сервера. Часть 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
Подробнее всё это описано [[https://borgbackup.readthedocs.io/en/stable/usage/notes.html... здесь]]
++ Извлечение и монтирование бекапов
Вы можете добавить добавить свой 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 и хорошо занимается одним делом — управляет архивами. Используя этот инструмент вы сможете создать схему резервного копирования подходящую именно вам.
URL:
Обсуждается: http://www.opennet.dev/tips/info/3180.shtml