Я исхожу из того, что читатель данной статьи прочитал первую часть моего повествования «Бэкапы для самых маленьких» и знает о моих подходах к бэкапированию. В этой части(скорее всего заключительной) мы рассмотрим практическую реализацию бэкапов. Так как я использую Debian/Ubuntu GNU/Linux на серверах примеры команд пакетного менеджера будут расчитаны именно на данное семейство, при использовании иных дистрибутивов вместо apt install используйте аналоги(dnf install для CentOS, emerge для Gentoo и так далее).

У нас есть сервер с данными, которые нужно бэкапить. На сервере есть файлы и база данных MariaDB(MySQL, Percona). У нас есть внешнее хранилище для бэкапа и второй сервер, на который будет выполняться зеркалирование бэкапа. Так же необходимо отметить, что я исхожу из того, что внешнее хранилище, куда у нас выполняется бэкап у нас уже имеется и доступно по ftp(потому оставляю за пределами данного текста установку-настройку ftp-демона, если же вам он необходим, то рекомендую использовать pure-ftpd) и из того, что мы храним бэкапы на доверенных хранилищах, а потому нам не нужна криптация(я буду в duplicity использовать флаг –no-encryption, если вам необходима криптация бэкапа ознакомьтесь с тем, как это делает duplicity в официальной документации).

Устанавливаем duplicity(и его зависимости)

sudo apt -y install duplicity

Устанавливаем curlftpfs для монтирования ftp-хранилища в директорию нашего сервера

sudo apt -y install curlftpfs

Создаем директорию в которую будет монтироваться ftp-хранилище:

sudo mkdir /backup-ftpfs

Добавляем в /etc/fstab строчку для монтирования ftp-хранилища(что бы не было нужды монтировать руками, а монтировалось само при загрузке системы)

echo -e "curlftpfs#your.server.tld /backup-ftpfs fuse user=USER:PASSWORD,allow_other,default_permissions,umask=027,_netdev 0 0 \n"|sudo tee --append /etc/fstab

Где your.server.tld — имя или IP-адрес вашего фтп-хранилища, USER — пользователь и PASSWORD — пароль к фтпшнику. allow_other в параметрах монтирования нам необходимо, что бы можно было писать в хранилище без рута(если вы выполняете бэкапирование от рута — ваше право, можете убрать allow_other из строчки)

Монтируем наше фтп-хранилище к серверу

sudo mount /backup-ftps

Создаем на подмонтированном хранилище директории куда будет выполнятся бэкап

mkdir /backup-ftpfs/www /backup-ftps/etc /backup-ftps/mysql

Выполняем первичный бэкап, первый бэкап у нас делается полный, от него дальше будут строится инкременты (бэкап директории с сайтами)

duplicity full --no-encryption /srv/www/ file:///backup-ftpfs/www/

(бэкап /etc, выполняется от рута, потому что в /etc есть файлы недоступные для чтения простому пользователю)

sudo duplicity full --no-encryption /etc/ file:///backup-ftpfs/etc/

Проверяем, что у нас бэкап на месте есть: duplicity collection-status file:///backup-ftps/www Видим вывод со строками типа

Chain start time: Thu Jun 8 12:13:54 2017(когда у нас выполнен первый бэкап)
Full Thu Jun 8 12:13:54 2017 (а вот и он) 

Строк вида

Incremental Fri Jun 9 03:10:05 2017 

у нас пока еще нет, они появятся как только мы сделаем первый инкрементальный бэкап туда же Аналогично проверяем для /backup-ftpfs/etc

Ну что. Бэкап у нас есть, теперь надо настроить его регулярно по крону crontab -e и добавляем строчку типа

10 3 * * * /usr/bin/duplicity incremental --no-encryption /srv/www/ file:///backup-ftpfs/www/

То есть каждый день в 3:10 по времени сервера у нас будет выполняться инкрементальный бэкап. Если у вас в crontab не определена переменная указывающая куда отправлять почту о выполненных заданиях, то определите ее добавив в начале файла MAILTO=your@domain.tld(то есть ваш e-mail). Я надеюсь, что отправка почты на сервере у вас настроена без меня. При выполнении задания вам будет отправляться e-mail с выводом duplicity, что бы вы видели, что задача выполнились.

Добавляем в кронтаб руту бэкапирование /etc

sudo crontab -e

10 4 * * * /usr/bin/duplicity incremental --no-encryption /etc/ file:///backup-ftpfs/etc/

В 4:10 каждый день делаем инкрементальный бэкап /etc. Аналогично, если нет MAILTO, то добавляем. Ну что. Хорошо, у нас настроен автоматический бэкап директории с содержимым сайта и директории с конфигами сервера на внешнее хранилище. Но у нас же еще есть база данных. Для бэкапирования MariaDB(MySQL, Percona) можно взять мои скрипты и исправить в них /path/to/backup/ на /backup-ftpfs/mysql(в завивисимости от того бэкап каждой базы нужен полный или потабличный берите тот скрипт, который нужно). Скрипт расчитан на выполнение от рута, так как использует для доступа к базе данные из /etc/mysql/debian.cnf, можно от этого уйти прописав пользователя у которого будет достаточно прав в ~/.my.cnf локального юзера от которого он будет запускаться.

Скрипт копируем в /usr/local/bin и добавляем его в крон

crontab -e

или

sudo crontab -e

23 5 * * * /usr/local/bin/mysql_backup.sh

В 5:23 бэкапим базу данных Я специально разношу все бэкапы между собой по времени, что бы уменьшить нагрузку на сервер.

Казалось бы все? Нет! Мы же помним, что бэкап надо хранить не в одном месте.

В первой части статьи я обещал, что напишу про minio(это такое s3-совместимое хранилище, если что). Извините, не сегодня. Пусть про него будет отдельная статья. Сегодня мы будем отправлять на второй сервер наши бэкапы при помощи rsync over ssh, для этого вам ничего не придется дополнительно устанавливать на ваших серверах. Первое: генерируем беспарольный ключ для ssh с которым будем ходить на второй сервер

ssh-keygen

и трижды нажимаем Enter Второе: создаем на втором сервере пользователя, который хранит наши бэкапы, пусть его будут звать backupuser

sudo useradd -m backupuser

Создаем директорию в которой хранится публичная часть ssh-ключа у пользователя на втором сервере и ставим на нее нужные права и владельца

sudo mkdir /home/backupuser/.ssh && sudo chown backupuser:backupuser /home/backupuser/.ssh && sudo chmod 700 /home/backupuser/.ssh

Берем на первом сервере публичную часть ssh-ключа

cat ~/.ssh/id_rsa.pub

И на втором сервере записываем его в /home/backupuser/.ssh/authorized_keys

echo -e "тут содержимое ключа\n" |sudo tee --append /home/backupuser/.ssh/authorized_keys

Выставляем на файл с публичной частью ключа на втором сервере правильные права

sudo chmod 600 /home/backupuser/.ssh/authorized_keys && sudo chown backupuser:backupuser /home/backupuser/.ssh/authorized_keys

Создаем директории куда у нас будут зеркалироваться бэкапы:

sudo mkdir -p /home/backupuser/PROJECTNAME/www /home/backupuser/PROJECTNAME/etc /home/backupuser/PROJECTNAME/mysql && chown -R backupuser:backupuser /home/backupuser

Пробуем зайти с первого сервера на второй под backupuser, что бы у нас сохранился фингерпринт сервера и что бы проверить, что мы можем зайти по ssh на второй сервер используя ключ ssh backupuser@SECOND_SERVER_ADDRESS (где SECOND_SERVER_ADDRESS IP или ДНС-имя второго сервера). Все у нас получилось. Делаем руками rsync наших директорий с первого сервера на второй:

rsync -rav --progress /backup-ftpfs/www/ backupuser@SECOND_SERVER_ADDRESS:/home/backupuser/PROJECTNAME/www/

rsync -rav --progress /backup-ftpfs/etc/ backupuser@SECOND_SERVER_ADDRESS:/home/backupuser/PROJECTNAME/etc/

rsync -rav --progress /backup-ftpfs/mysql/ backupuser@SECOND_SERVER_ADDRESS:/home/backupuser/PROJECTNAME/mysql/

Проверяем(глазками и при помощи duplicity(для этого на второй сервер тоже поставьте duplicity) collection-status, что у нас все скопировалось корректно и бэкап отзеркалировался.

Добавляем в crontab rsync’и

crontab -e

0 6 * * * rsync -rav --progress /backup-ftpfs/www/ backupuser@SECOND_SERVER_ADDRESS:/home/backupuser/PROJECTNAME/www/
10 6 * * * rsync -rav --progress /backup-ftpfs/etc/ backupuser@SECOND_SERVER_ADDRESS:/home/backupuser/PROJECTNAME/etc/
20 6 * * * rsync -rav --progress /backup-ftpfs/mysql/ backupuser@SECOND_SERVER_ADDRESS:/home/backupuser/PROJECTNAME/mysql/

MAILTO мы раньше уже прописали в crontab’е, так что и об этом письма нам будут приходить, что бы мы видели, что зеркалирование бэкапов выполнилось.

Рекомендую так же на обоих серверах добавить в кронтаб проверку duplicity collection-status для бэкапируемых директорий, что бы еще приходили письма в которых бы вы видели, что с коллекцией все хорошо и она пополняется. В идеале это надо автоматизировать и возложить на мониторинг, но я вот пока этого не сделал у себя, если сделаю, то напишу отдельную заметку.

Мы получили бэкап сохраняемый в две точки. Аналогично rsync можно выполнять еще на пару серверов, если они есть, что бы копий бэкапа было больше.

Обращаю внимание коллег, что описанный вариант с отслеживанием писем хорош для админов-фрилансеров, у которых не так много постоянных клиентов и серверов, а потому можно следить и глазами за всеми письмами. В условиях большого парка серверов необходима большая автоматизация и мониторинг.

На этом я завершаю статью «Бэкапы для самых маленьких. Часть II». Третья часть все же будет, в ней я расскажу об использовании minio вместо rsync