14 KiB
Описание процесса создания резервной копии 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), EEPROM позволяет выполнять загрузку c SD карты, USB, сети. Такую возможность добавили в одном из обновлений, необходимо убедиться, что используется последняя версия EEPROM.
Таким образом, выполнить создание образа SD-карты RPI можно если:
- записать образ системы на USB накопитель, подойдёт Raspberry Pi OS lite (https://www.raspberrypi.com/software/operating-systems/);
- подключить USB накопитель к RPI;
- переключить EEPROM в режим загрузки с USB;
- выполнить загрузку с USB;
- создать образ SD-карты и передать его в надёжное сетевое хранилище;
- вернуть EEPROM в режим загрузки с SD-карты;
- перезагрузить RPI.
Ничего сложного, осталось найти способ автоматического переключения способов загрузки в EEPROM. И такой способ существует - утилита rpi-eeprom-config
Нам достаточно двух ключей:
-a, --apply
-o, --out
сохранить текущие настройки EEPROM во внешний файл
pi@host:~ $ sudo rpi-eeprom-config -o ~/eeprom.conf
применить конфигурацию EEPROM из файла
pi@host:~ $ sudo rpi-eeprom-config -a ~/eeprom.conf
Осталось окончательно сформировать архитектуру нашего решения по созданию образа.
На системе загруженной с SD
- Необходимо создать конфигурационный файл EEPROM, который установит загрузку на USB
pi@host:~ $ sudo mkdir /opt/backup_from_usb && sudo vim /opt/backup_from_usb/usb_eeprom.conf
pi@host:~ $ cat /opt/backup_from_usb/usb_eeprom.conf
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
BOOT_ORDER=0xf4
- Создать скрипт, который будет выполнять обновление конфигурации EEPROM
pi@host:~ $ vim /opt/backup_from_usb/rpi_usb_boot.sh
#!/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
Добавить права на выполнение
pi@host:~ $ chmod +x /opt/backup_from_usb/rpi_usb_boot.sh
- Выполнить настройку запуска скрипта по расписанию.
т.к. обновление конфигурации EEPROM необходимо выполнять с привилегиями root, настраивать расписание нужно также пользователя root, чтобы скрипт запускался с повышенными привилегиями.
pi@host:~ $ sudo crontab -e
например, для запуска скрипта каждую среду в 2 часа ночи, необходимо добавить строку
0 2 * * 3 /opt/backup_from_usb/rpi_usb_boot.sh
На системе загруженной с USB
для этого нужно запустить скрипт /opt/backup_from_usb/rpi_usb_boot.sh
от рута или вручную переопределить загрузочный носитель с помощью sudo rpi-eeprom-config -a /opt/backup_from_usb/usb_eeprom.conf
и перезагрузиться
- Обеспечить подключение к хранилищу по SSH на основе ключа
pi@host-usb:~ $ ssh-keygen
pi@host-usb:~ $ ssh-copy-id user@nas
- Создать конфигурационный файл EEPROM, который вернёт загрузку на SD
pi@host-usb:~ $ sudo mkdir opt/backup_rpi && sudo vim /opt/backup_rpi/sd_eeprom.conf
pi@host-usb:~ $ cat /opt/backup_rpi/sd_eeprom.conf
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
BOOT_ORDER=0xf1
- Подготовить основной скрипт, который выполнит создание образа SD-карты и передаст его по SSH в сетевое хранилище
pi@host-usb:~ $ sudo vim /opt/backup_rpi/rpi_backup.sh
#!/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/main/data/Backup/bastion_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=$(echo $(date +%Y-%m-%d)_${HOSTNAME}_image.img.gz | sed 's/-usb//')
# Имя диска, над которым будем работать. 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
ssh $server "echo $(tail -20 log) > $remote_path/log"
# Необходимо хранить только последние 3 резервные копии
count_copies=3
ssh $server "find . -type f -name '*_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
Добавить права на выполнение
pi@host-usb:~ $ sudo chmod +x /opt/backup_rpi/rpi_backup.sh
- Обеспечить выполнение скрипта при загрузке с USB. Рассмотрим 3 способа.
7.1. /etc/rc.d/rc.local
Для выполнения пользовательского скрипта при загрузке, достаточно указать к нему полный путь в файле /etc/rc.d/rc.local
. Затем необходимо добавить права на выполнение
pi@host-usb:~ $ chmod +x /etc/rc.d/rc.local
7.2. crontab
Добавить задание в crontab с параметром @reboot
@reboot /opt/backup_rpi/rpi_backup.sh
7.3. Сервис systemd
Для этого вам нужно создать скрипт запуска systemd и поместить его в каталог /etc/systemd/system/
.
pi@host-usb:~ $ vim /etc/systemd/system/rpi_backup.service
pi@host-usb:~ $ 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
https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-4-bootloader-configuration
https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-4-boot-eeprom
https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#BOOT_ORDER