diff --git a/rpi_backup.md b/rpi_backup.md new file mode 100644 index 0000000..1fe251a --- /dev/null +++ b/rpi_backup.md @@ -0,0 +1,236 @@ +# Описание процесса создания резервной копии Raspberry Pi 4 + +Существует множество способов создания резервных копий системы, среди которых - использование специализированного ПО, самописные скрипты, которые выполняют копирование/архивирование выбранных директорий, ручное копирование, создание образов дисков и разделов и т.д. + +Создать резервную копию мало, необходимо также быть уверенным в том, что в случае необходимости, с ранее созданной резервной копии можно восстановиться. Ведь в процессе создания резервной копии, исходные данные могут изменяться - происходит чтение/запись, таким образом, есть вероятность, что в резервную копию попадут не консистентные данные и восстановиться с такой резервной копии будет невозможно. Чтобы избежать подобных проблем, необходимо исключить возможность изменения исходных данных в процессе создания резервных копий. Например, при создании образа системы, необходимо, чтобы раздел, резервную копию которого будем выполнять, не был смонтирован. Этого легко добиться, если это не загрузочный раздел. + +Но как быть, если нужно создать резервную копию (образ) загрузочного раздела или всего диска? - Необходимо выполнить загрузку с какого-нибудь live-cd и средствами этого самого live-cd создать образ системы. С Raspberry Pi 4 ситуация немного проще, достаточно извлечь SD-карту, создать её образ и сохрать этот образ в надёжном месте. Всё это ручная работа, которая требует времени. + +## Один из способов автоматизации создания образа системы Raspberry Pi 4 описан ниже. + +Raspberry Pi 4, 400 и Compute Module 4 используют EEPROM для загрузки системы. Все остальные модели Raspberry Pi используют bootcode.bin файл, расположенный в загрузочной файловой системе. + +Если не углубляться в детали ([BOOT ORDER](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#BOOT_ORDER)), EEPROM позволяет выполнять загрузку c SD карты, USB, сети. Такую возможность добавили в одном из обновлений, необходимо убедиться, что используется последняя версия EEPROM. + +Таким образом, выполнить создание образа SD-карты RPI можно если: + +- записать образ системы на USB накопитель, подойдёт Raspberry Pi OS lite (); +- переключить EEPROM в режим загрузки с USB; +- выполнить загрузку с USB; +- создать образ SD-карты и передать его в надёжное сетевое хранилище; +- вернуть EEPROM в режим загрузки с SD-карты; +- перезагрузить RPI. + +Ничего сложного, осталось найти способ автоматического переключения способов загрузки в EEPROM. И такой способо существует - утилита `rpi-eeprom-config` + +Нам достаточно двух ключей: + +-a, --apply +-o, --out + +сохранить текущие настройки загрузчика во внешний файл + +```bash +pi@sdboot:~ $ sudo rpi-eeprom-config -o ~/eeprom.conf +``` + +применить конфигурацию загрузчика из файла + +```bash +pi@sdboot:~ $ sudo rpi-eeprom-config -a ~/eeprom.conf +``` + +Осталось окончательно сформировать архитектуру нашего решения по созданию образа. + +**На системе с SD** + +1. Необходимо создать конфигурационный файл EEPROM, который установит загрузку на USB + +```bash +pi@sdboot:~ $ cat usb_eeprom.conf +[all] +BOOT_UART=0 +WAKE_ON_GPIO=1 +POWER_OFF_ON_HALT=0 +BOOT_ORDER=0xf4 +``` + +2. Создать скрипт, который будет выполнять обновление конфигурации EEPROM + +```bash +#!/bin/bash + +################################################################################################### + +# Скрипт выполняет обновление конфигурации EEPROM Raspberry PI для загрузки с USB. +# В директории с этим скриптом должен находится конфигурационный файл EEPROM - $eeprom_conf + +# Для корректной работы скрипта, EEPROM RPI должен поддерживать режим переключения загрузки SD<=>USB. + +################################################################################################### + +# Убедиться, что запуск происходит от root +if [ "$EUID" -ne 0 ] + then echo "Скрипт необходимо запускать от администратора" + exit +fi + +# Необходимо убедиться, что в папке присутствует конфиг EEPROM для изменения порядка загрузки +eeprom_conf="usb_eeprom.conf" + +if [ ! -e "./$eeprom_conf" ]; then + echo Файл настроек EEPROM $eeprom_conf не найден > log 2>&1 + exit +fi + +# Необходимо переключить EEPROM на загрузку с USB +rpi-eeprom-config -a ./$eeprom_conf + +# Перезагрузка +reboot +``` + +3. Выполнить настройку запуска скрипта по расписанию. + +*т.к. обновление конфигурации EEPROM необходимо выполнять с привилегиями root, настраивать расписание нужно также пользователя root, чтобы скрипт запускался с повышенными привилегиями.* + +```bash +pi@sdboot:~ $ sudo crontab -e +``` + +например, для запуска скрипта каждую среду в 2 часа ночи, необходимо добавить строку + +```bash +0 2 * * 3 /opt/scripts/rpi_usb_boot.sh +``` + +**На системе с USB** + +4. Обеспечить подключение к хранилищу по SSH на основе ключа + +```bash +pi@usbboot:~ $ ssh-keygen +pi@usbboot:~ $ ssh-copy-id user@nas +``` + +5. Создать конфигурационный файл EEPROM, который вернёт загрузку на SD + +```bash +pi@usbboot:~ $ cat sd_eeprom.conf +[all] +BOOT_UART=0 +WAKE_ON_GPIO=1 +POWER_OFF_ON_HALT=0 +BOOT_ORDER=0xf1 +``` + +6. Подготовить основной скрипт, который выполнит создание образа SD-карты и передаст его по SSH в сетевое хранилище + +```bash +#!/bin/bash + +################################################################################################### + +# Скрипт создаёт образ SD-карты Raspberry PI и отправляет его на удалённый сервер по SSH, +# при этом на удалённом сервере происходит сжатие образа для экономии места. +# Сжатие происходит на удалённом сервере, чтобы минимизировать операции записи на Flash память, +# с которой произведена загрузка RPI. +# После создания образа, происходит обновление конфигурации EEPROM Raspberry PI для загрузки с SD карты. +# В директории с этим скриптом должен находится конфигурационный файл EEPROM - $eeprom_conf + +# Для корректной работы скрипта, EEPROM RPI должен поддерживать режим переключения загрузки SD<=>USB. + +################################################################################################### + +# Убедиться, что запуск происходит от root +if [ "$EUID" -ne 0 ] + then echo "Скрипт необходимо запускать от администратора" + exit +fi + +# Удалённый сервер. Необходимо предварительно обеспечить доступ по ключам - ssh-keygen && ssh-sopy-id +server=user@nas + +# Путь сохранения на удалённом сервре +remote_path=/mnt/disk2/Backup/rpi + +# Необходимо убедиться, что в папке присутствует конфиг EEPROM для изменения порядка загрузки +eeprom_conf="sd_eeprom.conf" + +if [ ! -e "./$eeprom_conf" ]; then + ssh $server "echo Файл настроек EEPROM $eeprom_conf не найден" > $remote_path/lastlog 2>&1 + exit +fi + +# Имя образа +name=$(date +%Y-%m-%d)_rpi_image.img.gz + +# Имя диска, над которым будем работать. SD в RPI называется mmcblk0 +disk=/dev/mmcblk0 + +# запишем в переменную последний сектор последнего раздела диска +last_sector=$(fdisk -l -o end $disk | tail -1) + +# Считаем, что размер сектора составляет 512 Байт, тогда необходимо сохранить ($last_sector+1)*512 Байт. +# Или ($last_sector+1)*512/1024/1024 Мб. +count=$(($(($last_sector+1))*512/1024/1024)) + +# Команда создания образа +dd if=$disk bs=1M count=$count conv=noerror,sync | ssh $server "gzip -c > $remote_path/$name 2>> $remote_path/lastlog" && \ +ssh $server "echo `date +"%A, %d %B %Y"` - Образ создан успешно >> $remote_path/log" || \ +ssh $server "echo `date +"%A, %d %B %Y"` - При создании образа произошла ошибка >> $remote_path/log" + +# Необходимо хранить только последние 20 строк в файле log +echo "$(tail -20 log)" > log + +# Необходимо хранить только последние 3 резервные копии +count_copies=3 +find . -type f -name "*_rpi_image.img.gz" -printf "%T@ %p\n" | sort -n | cut -d' ' -f 2- | tail -n +$(($count_copies+1)) | xargs rm -f -- + +# Необходимо переключить EEPROM на загрузку с SD карты +rpi-eeprom-config -a ./$eeprom_conf + +# Перезагрузка +reboot +``` + +7. Обеспечить выполнение скрипта при загрузке с USB. Рассмотрим 3 способа. + +7.1. /etc/rc.d/rc.local + +Для выполнения пользовательского скрипта при загрузке, достаточно указать к нему полный путь в файле `/etc/rc.d/rc.local`. Затем необходимо добавить права на выполнение + +```bash +pi@usbboot:~ $ chmod +x /etc/rc.d/rc.local +``` + +7.2. crontab + +Добавить задание в crontab с параметром `@reboot` + +```bash +@reboot /opt/scripts/rpi_backup.sh +``` + +7.3. Systemd unit + +Для этого вам нужно создать скрипт запуска systemd и поместить его в каталог `/etc/systemd/system/`. + +```bash +pi@usbboot:~ $ vim /etc/systemd/system/rpi_backup.service +``` + +```bash +pi@usbboot:~ $ cat /etc/systemd/system/rpi_backup.service +[Unit] +Description=Run a Backup Script at Startup +After=default.target + +[Service] +ExecStart=/opt/scripts/rpi_backup.sh + +[Install] +WantedBy=default.target +``` + +***