Резервное копирование подтомов Btrfs при помощи Btrbk

Обновлено 13 апреля 2021

Введение

Btrbk - это инструмент резервного копирования для подтомов Btrfs, использующий специальные возможности этой файловой системы для создания атомарных моментальных снимков и передачи их в хранилище резервных копий. Исходное и целевое местоположения указываются в файле конфигурации, что позволяет легко настраивать как простые сценарии резервного копирования, такие как "резервная копия на USB HDD", так и сложные "сервер, получающий резервные копии с нескольких хостов по SSH, с разной политикой хранения".

Определения
  • Снапшот - мгновенный снимок состояния подраздела Btrfs, находящийся в той же самой файловой системе, что и сам подраздел.
  • Резервная копия - резервная копия подраздела Btrfs, выполняемая со снапшота. Может находиться как в этой же файловой системе, так и на другом диске, или хосте.
  • Первичная резервная копия - полная копия снимка подраздела, содержащая все данные оригинала.
    Для создания первичной резервной копии в Btrfs используется подход send/receive: btrfs send формирует поток данных, которые btrfs receive преобразует в раздел с данными.
  • Инкрементальная резервная копия - копия содержащая только изменения от первичной резервной копии или от другой инкрементальной копии.
    Для передачи данных инкрементальной резервной копии для btrfs send необходимо указать между какими снапшотами будут сформированы изменения (базовой и конечный). При этом раздел с резервными копиями должен уже содержать данные базового снапшота.
  • Архив - дополнительная резервная копия снимков, может выполняться либо с резервной копии либо со снапшотов. В отличии от связки хранилища снапшотов и резервных копий, может терять общий базовой снимок, в результате чего будет выполнена полная передача подраздела.

Btrbk берет на себя организацию хранения, снапшотов, определение параметров создания инкрементального архива, удаление устаревших снапшотов согласно политики хранилища, передачу данных между хостами. Необходимо только указать политику хранения копий, создать необходимые каталоги и указать места хранения снапшотов и копий.

Установка

Установите пакет Btrbk:

emerge -a app-backup/btrbk

Базовая настройка

Выполните настройку общих параметров для резервных копий:

/etc/btrbk/btrbk.conf

# директория со снапшотами в сохраняемом разделе
snapshot_dir               .btrbk_snap

# названия для снапшотов <имя>.YYYYmmddTHHMM
timestamp_format           long

# использование zstd-сжатия при передаче резервной копии
stream_compress            zstd

# путь к логу
transaction_log            /var/log/btrbk.log

# размер буфера потока отправки
stream_buffer              256m

Политика хранения копий

Укажите следующую общую политику хранения резервных копий и снапшотов:

/etc/btrbk/btrbk.conf

# ежедневной копией считается первая после полуночи
preserve_hour_of_day       0

# считать началом недели понедельник
preserve_day_of_week       monday

# сохранять все промежуточные снапошоты как минимум один день
snapshot_preserve_min      1d

# хранить 14 ближайших ежедневных снапшотов, 8 еженедельных, 6 ежемесячных, 1 ежегодный
snapshot_preserve          14d 8w 6m 1y

# не хранить промежуточные резервные копии
target_preserve_min        no

# хранить 6 ближайших ежедневных снапшотов, 4 еженедельных, 6 ежемесячных, 1 ежегодный
target_preserve            6d 4w 6m 1y

# хранить все архивы
archive_preserve_min       all
Временные интервалы
  • Копия часа - первая резервная копия в указанном часе. Таким образом если есть резервные копии от 20210323T0102, 20210323T0503, 20210323T2320, то часовой копией будет считаться 20210323T0503, а две другие будет удалены по прошествии минимального периода хранения.
  • Копия дня - первая копия с начала суток (или после часа указанного в preserve_hour_of_day). Остальные копии сделанные в этот день считаются часовыми или промежуточными.
  • Копия недели - ближайшая к понедельнику дневная копия (или дня недели указанного в preserve_day_of_week). Таким образом если есть копия от понедельника, то она считается копией недели. Если от понедельника нет, но есть от среды, то копия от среды будет считаться копией недели.
  • Копия месяца - ближайшая к первому числу копия недели. Таким образом ежемесячные копии будут закрепляться за днями недели, а не первыми числами.
  • Копия года - самая ранняя в году ежемесячная копия.

Общий формат политики хранения описывается следующим образом:

[<hourly>h] [<daily>d] [<weekly>w] [<monthly>m] [<yearly>y]

Где: hourly, daily, weekly, monthly и yearly определяет сколько копий должно храниться соответственно в интервалах часов, дней, недель, месяцев или лет.

Пример

Пример применения политики 2d 2w 2m на 30 июля 2021, с минимальным хранением копий 1d:

Дата время День недели Описание копии Комментарий
2021/07/3023:20 пятница последняя копия будет удалена 1 августа: по истечению минимального времени хранения копии
2021/07/3021:20 пятница промежуточная копия будет удалена 1 августа: по истечению минимального времени хранения копии
2021/07/3020:20 пятница копия текущего дня хранится так как указано хранение ежедневных копий
2021/07/2920:20 четверг копия день назад хранится так как указано 2d
2021/07/2820:20 среда копия два дня назад хранится так как указано 2d
2021/07/2620:20 понедельник копия текущей недели хранится так как указано хранение еженедельных копий
2021/07/2122:15 среда копия прошлой недели хранится так как указано 2w, среда - если не было копий от понедельника и вторника
2021/07/1220:20 понедельник копия позапрошлой недели хранится так как указано 2w
2021/07/0520:20 понедельник копия текущего месяца хранится так как указано хренение ежемесячных копий
2021/06/0720:20 понедельник копия прошлого месяца хранится так как указано 2m
2021/05/0320:20 понедельник копия позапрошлого месяца хранится так как указано 2m

Политика хранения снапшотов и резервных копий может различаться. Например снапшоты могут храниться только за 5 дней, а резервные копии делаться раз в месяц. В этом случае для поддержки инкрементальных архивов принудительно будет оставлен снапшот соответствующей последней резервной копии.

Все эти параметры могут быть указаны как глобально для всех резервных копий, так и переопределены для раздела Btrfs или подразделов подлежащих резервному копированию.

Резервное копирование в пределах одной машины

В примере ниже описано создание резервных копий корневого раздела / и раздела данных /var/calculate/ для текущей машины на отдельный диск подключенный к /mnt/backup/.

Настройка путей

Создайте каталоги для снапшотов в корневом разделе / и /var/calculate/:

mkdir /.btrbk_snap /var/calculate/.btrbk_snap

Добавьте описание создания резервных копий в конец файла:

/etc/btrbk/btrbk.conf

# корневой раздел
volume /
  # резервные копии помещать на /mnt/backup/
  target /mnt/backup
  # создавать снапшоты основного раздела
  subvolume .
    # название раздела в снапшоте rootfs
    snapshot_name rootfs

# раздел /var/calculate
volume /var/calculate
  # резервные копии помещать на /mnt/backup/
  target /mnt/backup
  # создавать снапшоты основного раздела
  subvolume .
    # название раздела в снапшоте calculate
    snapshot_name calculate

Снапшоты корневого раздела будут создаваться в /.btrbk_snap/, раздела данных в /var/calculate/.btrbk_snap/, их резервные копии в /mnt/backup/.

Создание резервной копии

Для запуска полного цикла (создание снапшотов, резервных копий, удаление устаревших копий) выполните:

btrbk run
--------------------------------------------------------------------------------
Backup Summary (btrbk command line client, version 0.31.1)

    Date:   Wed Mar 24 16:18:55 2021
    Config: /etc/btrbk/btrbk.conf

Legend:
    ===  up-to-date subvolume (source snapshot)
    +++  created subvolume (source snapshot)
    ---  deleted subvolume
    ***  received subvolume (non-incremental)
    >>>  received subvolume (incremental)
--------------------------------------------------------------------------------
/.
+++ /.btrbk_snap/rootfs.20210324T1618
*** /mnt/backup/rootfs.20210324T1618

/var/calculate/.
+++ /var/calculate/.btrbk_snap/calculate.20210324T1618
*** /mnt/backup/calculate.20210324T1618

В отчёте выполнения видно, что были созданы два снапшота (/.btrbk_snap/rootfs.20210324T1618/, /var/calculate/.btrbk_snap/calculate.20210324T1618/) и снапшоты были отправлены в виде полной резервной копии (***) в /mnt/backup/.

Повторный запуск цикла создаст только снапшоты, так как согласно политики хранения промежуточные резервные копии не хранятся. Запустите холостой цикл:

btrbk --dry-run run
--------------------------------------------------------------------------------
Backup Summary (btrbk command line client, version 0.31.1)

    Date:   Wed Mar 24 16:24:27 2021
    Config: /etc/btrbk/btrbk.conf
    Dryrun: YES

Legend:
    ===  up-to-date subvolume (source snapshot)
    +++  created subvolume (source snapshot)
    ---  deleted subvolume
    ***  received subvolume (non-incremental)
    >>>  received subvolume (incremental)
--------------------------------------------------------------------------------
/.
+++ /.btrbk_snap/rootfs.20210324T1624

/var/calculate/.
+++ /var/calculate/.btrbk_snap/calculate.20210324T1624

NOTE: Dryrun was active, none of the operations above were actually executed!

Запуск на другой день создаст как снапшоты, так и резервные копии, причём инкрементальным способом:

btrbk run
--------------------------------------------------------------------------------
Backup Summary (btrbk command line client, version 0.31.1)

    Date:   Thu Mar 25 14:04:36 2021
    Config: /etc/btrbk/btrbk.conf

Legend:
    ===  up-to-date subvolume (source snapshot)
    +++  created subvolume (source snapshot)
    ---  deleted subvolume
    ***  received subvolume (non-incremental)
    >>>  received subvolume (incremental)
--------------------------------------------------------------------------------
/.
+++ /.btrbk_snap/rootfs.20210325T1404
>>> /mnt/backup/rootfs.20210325T1404

/var/calculate/.
+++ /var/calculate/.btrbk_snap/calculate.20210325T1404
>>> /mnt/backup/calculate.20210325T1404

Для создания только снапшотов выполните:

btrbk snapshot

Для синхронизации снапшотов с хранилищем резервных копий, а так же удалении устаревших копий выполните:

btrbk resume

Чтобы выполнить только удаление устаревших снапшотов и резервных копий выполните:

btrbk prune

Настройка выполнения резервных копий по расписанию

Для настройки выполнения резервных копий по расписанию добавьте в cron ежедневный запуск btrbk:

/etc/cron.d/btrbk

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
HOME=/

# run btrbk
0 0 * * *   root    /usr/bin/btrbk run &>/dev/null

Настройка резервной копии для удалённого узла

Настройка Backup сервера

На Backup сервере сгенерируйте ssh-ключ для подключения к удалённой машине:

ssh-keygen -b 4096 -f /root/.ssh/btrbk.key
Generating public/private rsa key pair.
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/btrbk.key
Your public key has been saved in /root/.ssh/btrbk.key.pub
The key fingerprint is:
SHA256:MhrRRsoUfCnbm/e2Sdw5sH6y+bp1nq48UVLE9sjpgxs root@backup
The key randomart image is:
+---[RSA 4096]----+
|   .o...     o.  |
|   oo+o       +  |
|    +=o      + + |
|    .o.     . = .|
|    . ooS .  =   |
|     ooo.. +E.o  |
|    .  . .+ =+.. |
|         o+=++ . |
|         .OO+++  |
+----[SHA256]-----+

Важно

Не задавайте пароль на закрытый ключ, иначе вы не сможете автоматически подключаться к сервису

Добавьте в начало строки открытого ключа команду запуска и параметры:

echo -e 'command="/var/calculate/bin/ssh_filter_btrbk.sh --source --delete --info",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding' $(cat /root/.ssh/btrbk.key.pub) > /root/.ssh/btrbk.key.pub

Укажите использование ключа, при доступе через SSH:

/etc/btrbk/btrbk.conf

# Specify SSH private key for "ssh://" volumes / targets:
ssh_identity               /root/.ssh/btrbk.key

Добавьте описание создания резервных копий с удалённой машины в конец файла:

/etc/btrbk/btrbk.conf

# корневой раздел удалённой машины
volume ssh://host1.example.org/
  # резервные копии помещать на /mnt/backup
  target /mnt/backup/host1.example.org
  # создавать снапшоты основного раздела
  subvolume .
    # название раздела в снапшоте rootfs
    snapshot_name rootfs

# раздел /var/calculate/
volume ssh://host1.example.org/var/calculate
  # резервные копии помещать на /mnt/backup
  target /mnt/backup/host1.example.org
  # создавать снапшоты основного раздела
  subvolume .
    # название раздела в снапшоте calculate
    snapshot_name calculate
  # создавать снапшоты LXC контейнера calculate
  subvolume lxc/calculate/rootfs
    # связать создание копии lxc/calculate/rootfs с группой lxc
    group lxc
    # название раздела в снапшоте
    snapshot_name lxc.calculate.rootfs

где:

  • host1.example.org - сетевое имя машины с которой будут делаться резервные копии
  • /, /var/calculate/, /var/calculate/lxc/calculate/rootfs/ подразделы с которых будут создаваться резервные копии
  • group lxc - произвольное название группы, для запуска создания резервных копий по группам

Настройка клиента

На удалённой машине host1 создайте каталоги для снапшотов:

mkdir /.btrbk_snap /var/calculate/.btrbk_snap

Скопируйте на удалённую машину host1, к которой будет осуществляться доступ, скрипт для запуска ограниченного набора команд, необходимых только для создания резервных копий:

scp /usr/share/btrbk/scripts/ssh_filter_btrbk.sh root@host1:/var/calculate/bin/

Перенесите на удалённую машину сформированный ранее открытый ключ сервера:

ssh-copy-id -i /root/.ssh/btrbk.key.pub host1

Выполнение резервной копии

На Backup сервере запустите полный цикл:

btrbk run

Для запуска цикла только для хоста host1.example.org, выполните:

btrbk run host1.example.org

Для запуска цикла только для /var/calculate/ с хоста host1.example.org, выполните:

btrbk run host1.example.org:/var/calculate

Для запуска цикла только для группы lxc выполните:

btrbk run lxc

Прочее

По умолчанию Btrbk старается использовать инкрементальные резервные копии, но если цепочка (базовая-инкрементальная копия) будет нарушена (например в результате ручного удаления лишних копий), то резервная копия будет выполнена полная. Это может быть излишне, если первичные резервные копии уже созданы, а подразделы содержат большое количество данных. Выполните настройку использования только инкрементальных резервных копий:

/etc/btrbk/btrbk.conf

# Perform incremental backups (set to "strict" if you want to prevent
# creation of non-incremental backups if no parent is found).
incremental                strict

Важно

Обратите внимание, что использование только инкрементальных резервных копий должно быть указано после создания первичных резервных копий, в противном случае Btrbk не сможет их создать.