BorgBackup – это программное обеспечение для эффективного и безопасного резервного копирования данных с возможностью дедупликации и удаленного хранения (SSH).
Основная часть кода BorgBackup написана на Python (необходима версия >= 3.4.0), а требовательный к производительности код (сжатие, шифрование и т.п.) реализован на C/Cython. Распространяется на условиях свободной лицензии BSD (3-clause). Поддерживает множество платформ, включая Linux, BSD, macOS, а также на экспериментальном уровне Cygwin и Windows Subsystem for Linux.
Основные достоинства:
BorgBackup может быть установлен через пакетный менеджер (поддерживается большое кол-во дистрибутивов, подробнее здесь), путем сборки из исходников (потребуется python pip) или можно просто скачать готовый бинарный файл (из требований – glibc >= 2.28).
Последний вариант проще всего:
sudo wget https://github.com/borgbackup/borg/releases/download/1.2.6/borg-linux64 -O /usr/local/bin/borg
sudo chmod +x /usr/local/bin/borg
Если у пользователя, от имени которого будет выполняться резервное копирование, еще нет ssh-ключа, то нужно сгенерировать его:
ssh-keygen -t rsa -b 4096
Публичную часть нужно добавить в список ключей услуги на странице https://panel.netangels.ru/datastorage/account/ . Сам ключ нужно указать в формате:
command="/usr/bin/borg serve --restrict-to-path /home/u6607/BorgBackup",restrict ssh-rsa AAAA...veCw== user@email
Здесь BorgBackup
– это название репозитория. Он должен совпадать с тем, который будет использоваться со стороны клиента для создания резервных копий.
Прежде чем начать работать с бэкапами нужно инициализировать borg-репозиторий в хранилище данных. Это делается при помощи следующей команды:
borg init --encryption none u6607@storage.u6607.na4u.ru:BorgBackup
В результате на удаленном сервере в каталоге /home/u6607/BorgBackup
будет развернута структура со служебными данными. Содержимое любого из этих файлов категорически запрещается изменять, поскольку это приведет к полной потере данных в репозитории.
В данном примере не используется шифрование (--encryption none
), но опционально каждый репозиторий может быть зашифрован своим личным паролем. Подробнее о вариантах шифрования написано в документации.
Для наглядной демонстрации работы механизма дедупликации выполним бэкап каталога с логами ОС несколько раз с разницей в пару часов:
borg create --stats --list u6607@storage.u6607.na4u.ru:BorgBackup::'{hostname}-{now}' /var/log
В результате в репозитории окажется несколько архивов. Чтобы получить их список используется команда:
borg list u6607@storage.u6607.na4u.ru:BorgBackup
В данном примере список получился такой:
testvm-2023-11-15T11:22:49 Wed, 2023-11-15 11:22:50 [5a1cf...ecab5]
testvm-2023-11-15T13:25:29 Wed, 2023-11-15 13:25:30 [3ef3a...b3339]
testvm-2023-11-15T14:32:18 Wed, 2023-11-15 14:32:31 [f53c7...5934d]
testvm-2023-11-15T15:33:15 Wed, 2023-11-15 15:33:16 [0708d...fedb0]
Команда info
покажет суммарную информацию по репозиторию и, в том числе, позволит оценить эффективность дедупликации:
borg info u6607@storage.u6607.na4u.ru:BorgBackup
Repository ID: 838f7bcd130eee9979afa0d3eca81f8883a755eb816be806f25520f16d55fe96
Location: ssh://u6607@213.189.218.232/./BorgBackup
------------------------------------------------------------------------------
Original size Compressed size Deduplicated size
All archives: 1.12 GB 663.56 MB 331.81 MB
Unique chunks Total chunks
Chunk index: 419 831
Здесь видно, что в исходном виде все данные в репозитории занимают 1.12 Gb, в сжатом виде – 663 Mb, а с учетом дедупликации – всего 331 Mb.
По умолчанию BorgBackup использует алгоритм сжатия lz4. Он наиболее быстрый, но со слабой степенью сжатия. В рамках одного репозитория допустимо использовать разные алгоритмы (задается в команде create
через опцию --compression
).
Команда list
также позволяет получить список файлов в конкретном архиве. Например:
borg list u6607@storage.u6607.na4u.ru:BorgBackup::se-work-2023-11-15T14:33:15 /var/log/apt
2023-11-02 00:00:01 var/log/apt
2023-11-01 13:00:39 var/log/apt/eipp.log.xz
2023-11-02 00:00:01 var/log/apt/history.log
2023-11-02 00:00:01 var/log/apt/term.log
Работа с данными репозитория, для которого настроено шифрование, возможна только при наличии специального ключа. Следует учитывать этот момент, если восстановление запускается на хосте, отличном от того, где создавались резервные копии.
Есть два способа, как можно получить доступ к нужным файлам:
extract
.Первый вариант подходит в том случае, если точно известно какие файлы нужно восстановить и если нужно точь в точь восстановить все метаданные файла (флаги FS, ACL). Эта операция происходит быстрее и требует меньше ресурсов.
Второй вариант удобен когда заранее неизвестно в каких файлах содержится нужная информация, или когда требуется восстановить только содержимое файлов, а специальные флаги FS не важны.
install -d /tmp/restore && cd /tmp/restore
borg extract --list u6607@storage.u6607.na4u.ru:BorgBackup::se-work-2023-11-15T15:33:15 /var/log/apt /var/log/atop/atop_20231114
Эта команда извлечет из архива за 2023-11-15T15:33:15 каталог с логами apt и определенный файл с логами atop.
Команда extract
всегда восстанавливает файлы в текущий каталог. Поэтому прежде нужно создать каталог и перейти в него.
install -d /mnt/restore
borg mount u6607@storage.u6607.na4u.ru:BorgBackup::se-work-2023-11-15T15:33:15 /mnt/restore /var/log/apt
tree /mnt/restore
/mnt/restore
└── var
└── log
└── apt
├── eipp.log.xz
├── history.log
└── term.log
borg umount /mnt/restore
Команда prune
позволяет настроить автоматическое удаление старых бэкапов. Например, следующая команда оставит только две копии в репозитории с именем “BorgBackup”:
borg prune --list --show-rc --keep-daily 2 --glob-archives '{hostname}-*' u6607@storage.u6607.na4u.ru:BorgBackup
Опция --glob-archives
важна в том случае, если в один репозиторий делаются бэкапы из разных источников (например, с разных вирт.машин). По умолчанию команда prune
применяется ко всем архивам в репозитории.
Список архивов после очистки станет таким:
testvm-2023-11-15T11:22:49 Wed, 2023-11-15 11:22:50 [5a1cf...ecab5]
testvm-2023-11-15T15:33:15 Wed, 2023-11-15 15:33:16 [0708d...fedb0]
Удалены были 2023-11-15T13:25:29
и 2023-11-15T14:32:18
. А остались самая первая копия и самая последняя. Это особенность работы BorgBackup, которая появилась в версии 1.2.0.
Подробно схемы очистки описаны в документации.
После команды prune
требуется запуск команды compact
, чтобы неиспользуемые более фрагменты данных были удалены:
borg compact u6607@storage.u6607.na4u.ru:BorgBackup
При копировании файлов в хранилище, BorgBackup не имеет представления об их внутренней целостности или согласованности с какими-то другими. Он просто считывает и создает резервные копии каждого файла в том состоянии, в котором они находятся на момент времени, когда BorgBackup приступает к работе с ними.
Чтобы обеспечить консистентность данных внутри архивов существует несколько стандартных рекомендаций:
Представленный ниже скрипт можно использовать в качестве шаблона для настройки своей схемы резервного копирования. Предполагается, что скрипт запускается по cron’у настолько часто, насколько это требуется.
#!/bin/bash
# Setting this, so the repo does not need to be given on the commandline:
export BORG_REPO=ssh://<UserName>@<ServerName>:22/<BackupName>
# Some helpers and error handling:
info() {
printf "\n%s %s\n\n" "$( date )" "$*" >&2
}
trap 'echo $( date ) Backup interrupted >&2; exit 2' INT TERM
info "Starting backup"
# Backup the most important directories into an archive named after
# the machine this script is currently running on:
borg create \
--verbose \
--filter AME \
--list \
--stats \
--show-rc \
--compression lz4 \
--exclude-caches \
--exclude 'home/*/.cache/*' \
--exclude 'var/tmp/*' \
\
::'{hostname}-{now}' \
/etc \
/home \
/root \
/var
backup_exit=$?
info "Pruning repository"
# Use the `prune` subcommand to maintain 7 daily, 4 weekly and 6 monthly
# archives of THIS machine. The '{hostname}-*' matching is very important to
# limit prune's operation to this machine's archives and not apply to
# other machines' archives also:
borg prune \
--list \
--glob-archives '{hostname}-*' \
--show-rc \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6
prune_exit=$?
# actually free repo disk space by compacting segments
info "Compacting repository"
borg compact
compact_exit=$?
# Use highest exit code as global exit code
global_exit=$(( backup_exit > prune_exit ? backup_exit : prune_exit ))
global_exit=$(( compact_exit > global_exit ? compact_exit : global_exit ))
if [ ${global_exit} -eq 0 ]; then
info "Backup, Prune, and Compact finished successfully"
elif [ ${global_exit} -eq 1 ]; then
info "Backup, Prune, and/or Compact finished with warnings"
else
info "Backup, Prune, and/or Compact finished with errors"
fi
exit ${global_exit}