Arch Linux. Система бекапов

Note

Слово бекап (англ. backup) использую в тексте потому, что оно короче и привычнее русского аналога “резервная копия”.

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

До этого уже занимался бекапами. В одной из версий использовал duplicity. Последняя была основана на rsync, а дельты упаковывались в tar, на Debian Testing у меня эта система работала регулярно по крону, а в Arch Linux использовал нерегулярно вручную, хотелось ее переделать.

К системе бекапов у меня есть ряд требований:
  • latest: набор самых важных файлов (/home, /etc, список установленных пакетов и рабочие директории), доступ к которым должен быть очень легким и естественным, то есть обычные команды типа: cp, ls, cat с этими фалами должны просто работать;
  • delta: набор изменений, их может быть много, доступ к ним может быть немного сложнее чем к latest (допускается tar), но желательно чтоб дельт плодилось не очень много, так как рассматривать их после месяца работы бекапов не очень хотелось (в последней версии бекапов у меня был этот недостаток);
  • full: почти все файлы системы, чтоб делать полный бекап с работающей системы, нужно предусмотрительно использовать Btrfs или LVM, которые могут делать снепшоты (англ. snapshots) файловой системы.

Перед тем как делать систему бекапов, опять стал смотреть на заточенные для этого инструменты. Внимательно смотрел на rdup, bup и obnam. Последние две используют свои репозитории, в которых реализуют дедупликацию файлов. У bup формат совместимый с git. Смотрел на них потому, что можно было отказаться от разделения на latest и delta, ведь они бы сами все красиво раскладывали. Проблема с нестандартными форматами репозиториев такая же как и для архивов, то что нельзя просто посмотреть ls. У bup есть даже своя FUSE файловая система, но в ней не видны атрибуты файлов (можно посмотреть список файлов, но дату изменения или владельца файла посмотреть нельзя). rdup можно было бы использовать, но все таки вернулся к старому способу с rsync. В свое время отказался от duplicity и от архивов в целом опять же из-за простоты доступа к файлам. Хоть с обычными архивами умеет прозрачно работать mc, но делать инкрементный бекап на архиве невозможно (ну или слишком сложно), а разархивирование нескольких гигов данных даже без компрессии - операция не самая быстрая.

Note

От шифрования и архивов отказался, потому что не храню бекапы в интернете.

К схеме с latest & delta пришел потому, что реально мне важно было сохранить последнее состояние системы, а дельта нужна была для возможности посмотреть на старые файлы, которые случайно удалил, или посмотреть на файлы с какой-то важной информацией, которой нет в последней версии. Мне чаще нужно посмотреть что изменилось в системе, и дельта тут тоже очень кстати, ведь если сохранять снимок всех данных, то нужно производить лишние действия, чтоб получить дельту . Еще заморозкой дельты решаю вопрос данных, которые хорошо бы сохранить и которые хочется почистить в текущей файловой системе (то есть удаляю файлы, а потом архивирую дельту с определенной меткой). В общем схема с latest & delta мне очень подходит.

Итак, что имеется на входе:
  • ноут ThinkPad X230 с SSD 128GB и любимым Arch Linux;
  • неттоп Zotac ZBOX ID83-BE с HDD 500GB (на него еще нужно накатить новый Arch);
  • внешний винчестер на 1TB с USB 3.0;
  • домашний WI-FI.
Схема следующая:
  • неттоп по имени Box, на нем делается регулярный бекап текущей системы локально в "box:/backups/box", плюс к нему подключен постоянно внешний винт по имени Sea через USB 3.0 и на него идет регулярный слив "box:/backups" в "sea:/backups";
  • ноут по имени Pad, на нем делается регулярный бекап, а если он находится в домашней сети, то идет слив на неттоп в "box:/backups/pad".

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

На внешний винчестер ставлю тоже Arch (называю его LiveHard, по аналогии с LiveCD), чтоб иметь под рукой загрузочный винт с привычно настроенным окружением. Кроме того у меня есть еще один внешний винчестер (более старый с USB 2.0), из него делаю тоже LiveHard, чтоб таскать с собой, ведь первый постоянно висит на неттопе.

Note

Все перечисленные ниже команды - это суть выполняемых команд, в реальности использую:
  • pkglist для генерации списка пакетов для бекапа и не только;
  • backup все действия над бекапами.

Для бекапа системы в первую очередь нужно сохранить правильный список пакетов. Обычный "pacman -Q" не подходит, потому что мне нужны пакеты установленные мной и не включая две базовые группы пакетов base и base-dev, потому что обе группы обычно ставятся в начале установки нового Arch. В принципе, с pacman это делается несложно:

$ comm -23 <(pacman -Qeq) <(pacman -Qgq base base-devel | sort) > /backup/pkglist.txt

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

Дальше нужно сохранить все важные файлы:

$ rsync -aAXHvh --delete \
>   --backup --backup-dir=/backup/delta/ \
>   -f '+ /boot/' -f '+ /etc/' -f '+ /home/' -f '- /**/*.pyc' -f '- /*' \
>   / /backup/latest/

Появляется latest & delta, при этом delta у меня не сохраняется каждый раз, а накапливается в одной папке. А tar архив создается отдельной командой, которая запускается реже, чем регулярный бекап:

$ cd /backup && tar -cvf $(date '+%Y-%m-%d').tar --directory=delta .

Или с меткой о каком-то намеренном удалении:

$ cd /backup && tar -cvf $(date '+%Y-%m-%d')--cleanup-home.tar --directory=delta .

Потом все перекидываем по SSH на неттоп:

$ rsync -aAXHvhx --delete /backup/ box:/backups/pad/

В целом это уже рабочая система бекапов. Вначале не думал про полный бекап и новую систему установил без LVM. Но потом решил, что полный бекап нужен, и выбрал снепшоты LVM, потому что Btrfs никогда не использовал и репутация у этой файловой системы не самая лучшая. Я скопировал через dd необходимые разделы и записал их на внешний винт, чтоб сделать новую разметку диска для LVM. Когда закончил с новой разметкой, то обнаружил, что главный раздел у меня не записался полностью o_O, не хватило места на винте, а на сообщение не обратил внимание. Но не все так плохо, у меня ведь был бекап, который как раз для подобных неожиданных случаев и создан.

Немного про разметку диска. Раньше любил выносить home на отдельный раздел, но по сути home у меня - это набор конфигурационных файлов, а downloads, music и рабочие директории выношу на отдельный большой раздел. В итоге схема следующая:

- /dev/sda1 EFI System /boot 100-200 MB
+ /dev/sda2 Linux LVM 128GB
  - /dev/pad/root /root 30GB
  - /dev/pad/arch /arch 50GB
  - остальное место для снепшотов или для увеличения разделов

Отдельный раздел для загрузки обязателен для UEFI загрузчика, а остальное отдается для LVM. Так как за ноутбуком обычно работаю, то 50GB на /arch раздел мне достаточно. Для мультимедия у меня есть неттоп с хорошим большим монитором и хорошими колонками.

Режим востановления из неполного бекапа следующий:

# гружусь с LiveHard
$ mount /dev/pad/root /mnt
$ mount -L P-BOOT /mnt/boot

# ставлю базовою систему
$ pacstrap -c /mnt base base-devel
$ cp /etc/pacman.conf /mnt/etc/

# переключаюсь на новый Arch и ставлю все нужные пакеты
$ arch-chroot /mnt
$ pacman -S $(cat /backups/pad/pkglist.txt)
$ yaourt -S $(cat /backups/pad/pkgaur.txt) --noconfirm

# восстанавливаю все важные файлы
$ rsync -aAXHvh /backups/pad/latest/ /

# выхожу из chroot, перегружаюсь

Система готова и находится в полном соответствии со старой. В принципе, шагов не много, но было бы проще и быстрее с полным бекапом.

Полный бекап делаю через LVM снепшот плюс опять же rsync:

$ lvcreate --size 10G --snapshot --name snap /dev/pad/root \
> && mount /dev/pad/snap /backups/mnt \
> && rsync -aAXHvhyx \
>   --exclude="{/dev/*,/proc/*,/sys/*,/tmp/*,/run/*,/mnt/*,/media/*,/lost+found}"
> && umount /backups/mnt
> && lvremove -f /dev/pad/snap

Для регулярного запуска бекапов использую асинхронный cron. Асинхронный потому, что хотя и работаю за ноутбуком регулярно, но работаю в разное время. fcron может запускать команды в зависимости от времени работы ноутбука, например каждые шесть часов работы. Обычный cron рассчитан на то, что машина все время работает.

Теперь если вспомнить про мой backup скрипт и добавить, что он был написан с оглядкой на крон и в нем реализовано логирование, то fcrontab будет выглядеть очень просто:

SHELL=/bin/zsh
PATH="/usr/bin:/root/bin"
BACKUP_LOG=1

@ 6h backup run && backup call pad_to_box
@ 2d1h backup tar
@ 2d2h backup full
@ 2d4h backup full

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

Кроме всего, полный бекап используется для разворачивания новых Arch Linux, например на неттопе и LiveHards. Теперь развернуть привычно настроенный Arch очень просто и быстро.

Материалы по теме: