notes/rpi_backup.md

275 lines
15 KiB
Markdown
Raw Normal View History

2022-08-09 17:07:20 +03:00
# Описание процесса создания резервной копии Raspberry Pi 4
Существует множество способов создания резервных копий системы, среди которых - использование специализированного ПО, самописные скрипты, которые выполняют копирование/архивирование выбранных директорий, ручное копирование, создание образов дисков и разделов и т.д.
Создать резервную копию мало, необходимо также быть уверенным в том, что в случае необходимости, с ранее созданной резервной копии можно восстановиться. Ведь в процессе создания резервной копии, исходные данные могут изменяться - происходит чтение/запись, таким образом, есть вероятность, что в резервную копию попадут не консистентные данные и восстановиться с такой резервной копии будет невозможно. Чтобы избежать подобных проблем, необходимо исключить возможность изменения исходных данных в процессе создания резервных копий. Например, при создании образа системы, необходимо, чтобы раздел, резервную копию которого будем выполнять, не был смонтирован. Этого легко добиться, если это не загрузочный раздел.
2022-08-09 17:28:01 +03:00
Но как быть, если нужно создать резервную копию (образ) загрузочного раздела или всего диска? - Необходимо выполнить загрузку с какого-нибудь live-cd и средствами этого самого live-cd создать образ системы. С Raspberry Pi 4 ситуация немного проще, достаточно извлечь SD-карту, создать её образ и сохранить этот образ в надёжном месте. Всё это ручная работа, которая требует времени.
2022-08-09 17:07:20 +03:00
2022-08-09 20:46:16 +03:00
## Один из способов автоматизации создания образа системы Raspberry Pi 4 описан ниже
2022-08-09 17:07:20 +03:00
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 (<https://www.raspberrypi.com/software/operating-systems/>);
2022-08-09 17:28:01 +03:00
- подключить USB накопитель к RPI;
2022-08-09 17:07:20 +03:00
- переключить EEPROM в режим загрузки с USB;
- выполнить загрузку с USB;
- создать образ SD-карты и передать его в надёжное сетевое хранилище;
- вернуть EEPROM в режим загрузки с SD-карты;
- перезагрузить RPI.
2022-08-09 17:28:01 +03:00
Ничего сложного, осталось найти способ автоматического переключения способов загрузки в EEPROM. И такой способ существует - утилита `rpi-eeprom-config`
2022-08-09 17:07:20 +03:00
Нам достаточно двух ключей:
2022-08-09 17:28:01 +03:00
-a, --apply
2022-08-09 17:07:20 +03:00
-o, --out
2022-08-09 17:28:01 +03:00
сохранить текущие настройки EEPROM во внешний файл
2022-08-09 17:07:20 +03:00
```bash
2022-08-09 20:00:28 +03:00
pi@host:~ $ sudo rpi-eeprom-config -o ~/eeprom.conf
2022-08-09 17:07:20 +03:00
```
2022-08-09 17:28:01 +03:00
применить конфигурацию EEPROM из файла
2022-08-09 17:07:20 +03:00
```bash
2022-08-09 20:00:28 +03:00
pi@host:~ $ sudo rpi-eeprom-config -a ~/eeprom.conf
2022-08-09 17:07:20 +03:00
```
2022-08-22 08:39:34 +03:00
### Осталось окончательно сформировать архитектуру нашего решения по созданию образа.
2022-08-09 17:07:20 +03:00
2022-08-09 17:28:01 +03:00
**На системе загруженной с SD**
2022-08-09 17:07:20 +03:00
1. Необходимо создать конфигурационный файл EEPROM, который установит загрузку на USB
```bash
2022-08-09 20:00:28 +03:00
pi@host:~ $ sudo mkdir /opt/backup_from_usb && sudo vim /opt/backup_from_usb/usb_eeprom.conf
```
```bash
pi@host:~ $ cat /opt/backup_from_usb/usb_eeprom.conf
2022-08-09 17:07:20 +03:00
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
BOOT_ORDER=0xf4
```
2. Создать скрипт, который будет выполнять обновление конфигурации EEPROM
2022-08-09 17:37:17 +03:00
```bash
2022-08-22 12:58:02 +03:00
pi@host:~ $ sudo vim /opt/backup_from_usb/rpi_usb_boot.sh
2022-08-09 17:37:17 +03:00
```
2022-08-09 17:07:20 +03:00
```bash
#!/bin/bash
###################################################################################################
# Скрипт выполняет обновление конфигурации EEPROM Raspberry PI для загрузки с USB.
# В директории с этим скриптом должен находится конфигурационный файл EEPROM - $eeprom_conf
# Для корректной работы скрипта, EEPROM RPI должен поддерживать режим переключения загрузки SD<=>USB.
###################################################################################################
# Убедиться, что запуск происходит от root
if [ "$EUID" -ne 0 ]
then echo "Скрипт необходимо запускать от администратора"
exit
fi
2022-08-22 08:39:34 +03:00
# Директория, в которой хранится конфигурационный файл EEPROM
eeprom_conf_path=/opt/backup_from_usb
# Перенаправить весь вывод и ошибки в файл
exec > $eeprom_conf_path/run_log 2>&1
2022-08-09 17:07:20 +03:00
# Необходимо убедиться, что в папке присутствует конфиг EEPROM для изменения порядка загрузки
eeprom_conf="usb_eeprom.conf"
2022-08-22 08:39:34 +03:00
if [ ! -e "$eeprom_conf_path/$eeprom_conf" ]; then
echo Файл настроек EEPROM $eeprom_conf не найден в директории $eeprom_conf_path > log 2>&1
2022-08-09 17:07:20 +03:00
exit
fi
# Необходимо переключить EEPROM на загрузку с USB
2022-08-22 08:39:34 +03:00
rpi-eeprom-config -a $eeprom_conf_path/$eeprom_conf
2022-08-09 17:07:20 +03:00
# Перезагрузка
/usr/sbin/reboot
2022-08-09 17:07:20 +03:00
```
2022-08-09 17:37:17 +03:00
Добавить права на выполнение
```bash
2022-08-22 12:58:02 +03:00
pi@host:~ $ sudo chmod +x /opt/backup_from_usb/rpi_usb_boot.sh
2022-08-09 17:37:17 +03:00
```
2022-08-09 17:07:20 +03:00
3. Выполнить настройку запуска скрипта по расписанию.
*т.к. обновление конфигурации EEPROM необходимо выполнять с привилегиями root, настраивать расписание нужно также пользователя root, чтобы скрипт запускался с повышенными привилегиями.*
```bash
2022-08-09 20:00:28 +03:00
pi@host:~ $ sudo crontab -e
2022-08-09 17:07:20 +03:00
```
например, для запуска скрипта каждую среду в 2 часа ночи, необходимо добавить строку
```bash
2022-08-09 20:00:28 +03:00
0 2 * * 3 /opt/backup_from_usb/rpi_usb_boot.sh
2022-08-09 17:07:20 +03:00
```
2022-08-09 17:28:01 +03:00
**На системе загруженной с USB**
2022-08-09 17:07:20 +03:00
2022-08-09 20:00:28 +03:00
*для этого нужно запустить скрипт `/opt/backup_from_usb/rpi_usb_boot.sh` от рута или вручную переопределить загрузочный носитель с помощью `sudo rpi-eeprom-config -a /opt/backup_from_usb/usb_eeprom.conf` и перезагрузиться*
2022-08-24 14:34:12 +03:00
4. Обеспечить подключение к хранилищу по SSH на основе ключа пользователю root, т.к. скрипт будет выполняться от его имени
2022-08-09 17:07:20 +03:00
```bash
2022-08-24 14:34:12 +03:00
root@host-usb:~ $ ssh-keygen
root@host-usb:~ $ ssh-copy-id da2001@nas.dav.lan
2022-08-09 17:07:20 +03:00
```
5. Создать конфигурационный файл EEPROM, который вернёт загрузку на SD
```bash
2022-08-22 12:58:02 +03:00
pi@host-usb:~ $ sudo mkdir /opt/backup_rpi && sudo vim /opt/backup_rpi/sd_eeprom.conf
2022-08-09 20:00:28 +03:00
```
```bash
pi@host-usb:~ $ cat /opt/backup_rpi/sd_eeprom.conf
2022-08-09 17:07:20 +03:00
[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
BOOT_ORDER=0xf1
```
6. Подготовить основной скрипт, который выполнит создание образа SD-карты и передаст его по SSH в сетевое хранилище
2022-08-09 20:00:28 +03:00
```bash
pi@host-usb:~ $ sudo vim /opt/backup_rpi/rpi_backup.sh
```
2022-08-09 17:07:20 +03:00
```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
2022-08-24 14:34:12 +03:00
# Удалённый сервер. Необходимо предварительно обеспечить доступ по ключам - ssh-keygen && ssh-sopy-id user@server
server=da2001@nas.dav.lan
2022-08-09 17:07:20 +03:00
# Путь сохранения на удалённом сервре
2022-08-24 20:56:36 +03:00
remote_path=/mnt/main/data/Backup/bastion_rpi
2022-08-09 17:07:20 +03:00
2022-08-22 08:39:34 +03:00
# Директория, в которой хранится конфигурационный файл EEPROM
eeprom_conf_path=/opt/backup_rpi
2022-08-09 17:07:20 +03:00
# Необходимо убедиться, что в папке присутствует конфиг EEPROM для изменения порядка загрузки
eeprom_conf="sd_eeprom.conf"
2022-08-22 08:39:34 +03:00
if [ ! -e "$eeprom_conf_path/$eeprom_conf" ]; then
2022-08-09 17:07:20 +03:00
ssh $server "echo Файл настроек EEPROM $eeprom_conf не найден" > $remote_path/lastlog 2>&1
exit
fi
# Необходимо синхронизировать время, т.к. сейчас оно отстаёт на неделю.
# Для этого используем утилиту ntpdate, Её необходимо заранее установить sudo apt install ntpdate.
ntpdate ntp1.vniiftri.ru
2022-08-09 17:07:20 +03:00
# Имя образа
2022-08-09 20:00:28 +03:00
name=$(echo $(date +%Y-%m-%d)_${HOSTNAME}_image.img.gz | sed 's/-usb//')
2022-08-09 17:07:20 +03:00
# Имя диска, над которым будем работать. 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
2022-08-24 20:56:36 +03:00
ssh $server 'echo "$(tail -5 $remote_path/log)" > $remote_path/log'
2022-08-09 17:07:20 +03:00
# Необходимо хранить только последние 3 резервные копии
count_copies=3
2022-08-09 21:01:08 +03:00
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 --"
2022-08-09 17:07:20 +03:00
# Необходимо переключить EEPROM на загрузку с SD карты
2022-08-22 08:39:34 +03:00
rpi-eeprom-config -a $eeprom_conf_path/$eeprom_conf
2022-08-09 17:07:20 +03:00
# Перезагрузка
/usr/sbin/reboot
2022-08-24 14:34:12 +03:00
2022-08-09 17:07:20 +03:00
```
2022-08-09 20:00:28 +03:00
Добавить права на выполнение
```bash
pi@host-usb:~ $ sudo chmod +x /opt/backup_rpi/rpi_backup.sh
```
2022-08-24 20:56:36 +03:00
7. Обеспечить выполнение скрипта при загрузке с USB. Сервис systemd
2022-08-09 17:07:20 +03:00
Для этого вам нужно создать скрипт запуска systemd и поместить его в каталог `/etc/systemd/system/`.
```bash
2022-08-24 14:52:32 +03:00
pi@host-usb:~ $ sudo vim /etc/systemd/system/rpi_backup.service
2022-08-09 17:07:20 +03:00
```
```bash
2022-08-09 20:00:28 +03:00
pi@host-usb:~ $ cat /etc/systemd/system/rpi_backup.service
2022-08-09 17:07:20 +03:00
[Unit]
Description=Run a Backup Script at Startup
After=default.target
[Service]
2022-08-24 20:56:36 +03:00
ExecStart=/opt/backup_rpi/rpi_backup.sh
2022-08-09 17:07:20 +03:00
[Install]
WantedBy=default.target
```
2022-08-24 20:56:36 +03:00
Перечитать скрипты и активировать созданный сервис
```bash
pi@host-usb:~ $ sudo systemctl daemon-reload
pi@host-usb:~ $ sudo systemctl enable rpi_backup.service
```
2022-08-24 14:52:32 +03:00
2022-08-09 17:07:20 +03:00
***
2022-08-09 20:46:16 +03:00
<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>