До недавнего времени я делал бэкапы своих устройств на внешний HDD. Такой способ меня устраивал потому, что бэкапил данные редко - раз в неделю. Когда задумался о ежедневных бэкапах, понял, что бегать с внешним HDD будет непрактично. Хочу рассказать про удобное (по крайней мере для меня) решение для ежедневных бекапов без проводов.
restic
Для создания самих бэкапов я пользуюсь программой restic. Это простая CLI программа, работает на всех популярных ОС т.к написана на Go. Позволяет делать бэкапы локально, на внешние устройства и в облачные сервисы из коробки. Довольно эффективно сжимает файлы, например, бэкап моей домашней директории размером в ~111GB получился всего в 20GB. При первом запуске он делает полный снапшот указанной директории, при последующих уже бэкапит дельту и сохраняет отдельными снапшотами только изменения. Снапшот - это содержимое директории в определенный момент времени.
MinIO
Бэкапы нужно где-то хранить, я выбрал для этого S3 хранилище MinIO. Его довольно легко развернуть на своем сервере, в веб-интерфейсе несложно разобраться и вообще это production ready решение, его успешно используют во многих крупных проектах для хранения данных.
Установка и настройка
Скачать restic можно из github репозитория или с помощью пакетного менеджера вашей ОС.
В первую очередь инициализируем репозиторий:
restic -r RESTIC_REPOSITORY init
Репозиторием может быть директория или адрес облачного сервиса, например, если делать бэкап прямо на том же компьютере в папку backup-repo, то команда будет выглядеть так:
restic -r /home/backup-repo init enter password for new repository: enter password again:
restic попросить ввести пароль от репозитория, пароль терять нельзя, иначе доступ к данным будут утерян.
Команда для запуска процесса бэкапа выглядит следующим образом:
restic -r /home/backup-repo --verbose backup /documents
Флаг --verbose нужен для подробного вывода информации. Этой коммандой мы запустили бэкап директории documents в директорию backup-repo.
Восстановить данные из бэкапа можно следующей командой:
restic -r /home/backup-repo restore latest --target /restore_folder
latest - это самый последний снапшот, можно указать id нужного снапшота, если требуется. restic позволяет восстанавливать отдельные файлы и директории для этого после флага --path необходимо указать нужный путь.
Развернуть MinIO удобнее всего в docker контейнере на вашем сервере:
docker run \ -p 9000:9000 \ -p 9090:9090 \ --name minio \ -v /mnt/my-storage:/data \ -e "MINIO_ROOT_USER=ROOTNAME" \ -e "MINIO_ROOT_PASSWORD=CHANGEME123" \ quay.io/minio/minio server /data --console-address ":9090"
-pпробрасывает порты между контейнером и машиной на которой он запускается.9000порт самого сервиса,9090порт веб-интерфейса.-vуказание директории в которой будут храниться данные на хостовой машине, сервис будет зеркалировать данные в директорию/data.-eпеременные окружения, нужны для доступа к веб-интерфейсу.--console-addressадрес по которому будет доступен веб-интерфейс.
После установки MinIO нужно зайти в консоль и создать ключ доступа (access key), чтобы restic ��ог подключаться к хранилищу.
Теперь можно сделать бэкап в MinIO:
# задаем переменные окружения с ID и SECRET, созданными ранее в веб-интерфейсе export AWS_ACCESS_KEY_ID=my_key_id export AWS_SECRET_ACCESS_KEY=my_key_secret # создаем новый репозиторий и указываем пароль restic -r s3:http://localhost:9000/backup-repo init enter password for new repository: enter password again: # запускаем процесс бэкапа restic backup -r s3:http://localhost:9000/backup-repo --verbose /documents
Вместо http://localhost:9000 будет ваш адрес на котором поднят MinIO.
В целом так и работает резервное копирование с restic и MinIO, но каждый день делать бэкапы руками быстро надоест, поэтому этот процесс нужно автоматизировать, чтобы процесс бэкапа был полностью автономным.
systemd
Я использую систему инициализации sytstemd для этих целей, но вместо systemd можно использовать cron на Linux или планировщик заданий на Windows для запуска скрипта по расписанию.
В первую очередь нужно создать файл в котором будут переменные окружения для работы restic ~/.config/restic-backup.conf
# ID и SECRET MinIO AWS_ACCESS_KEY_ID=my_key_id AWS_SECRET_ACCESS_KEY=my_key_secret # адрес репозитория MinIO RESTIC_REPOSITORY=s3:http://localhost:9000/backup-repo # пароль от репозитория RESTIC_PASSWORD=restic_pass # путь к директории, которую бэкапим BACKUP_PATH="/documents" # за сколько дней нужно хранить бэкапы RETENTION_DAYS=7
И сам файл сервиса systemd ~/.config/systemd/user/restic-backup.service
[Unit] Description=Restic backup service [Service] Type=oneshot ExecStart=restic backup --verbose $BACKUP_PATH ExecStartPost=restic forget --verbose --keep-daily $RETENTION_DAYS EnvironmentFile=%h/.config/restic-backup.conf
Комманда forget нужна для удаления старых снапшотов, флаг --keep-daily позволяет настроить политику хранения снапшотов т.е. за последние n дней, которые имеют один или более снапшотов, сохранять только самый последний для каждого дня. forget удаляет только снапшоты, но не сами данные.
Для удаления данных сделаем другой сервис. Возможно возникнет вопрос, а почему не добавить prune в первый сервис, можно и так, но дело в том, что команды будут запускаться с разной периодичностью, поэтому они разделены на два сервиса.
Второй сервис ~/.config/systemd/user/restic-prune.service
[Unit] Description=Restic backup service (data pruning) [Service] Type=oneshot ExecStart=restic prune EnvironmentFile=%h/.config/restic-backup.conf
Команда prune будет очищать данные на которые ссылаются удаленные снапшоты.
Теперь сделаем таймеры для сервисов в той же директории.
~/.config/systemd/user/restic-backup.timer
[Unit] Description=Backup with restic daily [Timer] OnCalendar=daily Persistent=true [Install] WantedBy=timers.target
OnCalendar задает время запуска, у меня сервис запускается ежедневно в 12 ночи, поэтому стоит значение daily.
~/.config/systemd/user/restic-prune.timer
[Unit] Description=Prune data from the restic repository monthly [Timer] # This will run on the 1st of every month at 2AM OnCalendar=*-*-01 02:00:00 Persistent=true [Install] WantedBy=timers.target
Сервис для очистки будет запускаться раз в месяц, каждое первое число в 2 часа ночи . Я указал 2 часа ночи, чтобы не было конфликта у сервисов с доступом к репозиторию.
Для работы сервисов нужно перезапустить менджер systemd, чтобы они подхватились:
systemctl --user daemon-reload
И запустить таймеры:
systemctl --user enable --now restic-backup.timer systemctl --user enable --now restic-prune.timer
На этом этапе все настройки завершены и если все сделано правильно restic будет делать ежедневные бэкапы и очищать старые раз в месяц. Вместо MinIO можно использовать любое другое хранилище, список поддерживаемых restic'ом можно посмотреть здесь.
Полезные ссылки
Restic Documentation
MinIO docker install documentation
systemd service
systemd timer
