Pull to refresh

Пишем клиент-серверную систему Backup-ов под *NIX OS

Reading time 4 min
Views 1.7K
Всем добрый день.
Как говориться сисадмины деляться на тех кто делает бэкапы и тех кто их еще не делает.
Собственно снова о бэкапах.
Возникла ситуация, когда нужно было иметь под рукой всегда свежий бэкап с большого количества
удаленных хостов. Причем система должна быть клиент-сервер.
Конечно существует, очень большое количество свободного ПО, которое обеспечит функционалом выше крыши, но оно либо слишком навороченное, либо не совсем то, что нужно в конечном итоге. В общем решено было создать свою систему бэкапирования на основе fsbackup.
Итак, мы имеем сервер и клиентские хосты.
ОС на всех freebsd 8.2, но это не важно, работать будет на любой версии.

Приступаем к установке (только на клиентских хостах, сервер не трогаем):

[root@server/usr/ports/sysutils/fsbackup]# make install clean

Далее переходим в папку с установленным fsbackup и создаем файл fsbackup.conf с таким
содержимым:
$cfg_backup_name = "host1";
$cfg_cache_dir= "/usr/local/fsbackup/cache";
$prog_md5sum    = "md5sum -b";
$prog_tar       = "/usr/bin/tar";
$prog_ssh       = "/usr/bin/ssh";
$prog_rm        = "/bin/rm";
$prog_gzip      = "/usr/bin/gzip";
$prog_pgp       = "";
$cfg_checksum = "timesize";
$cfg_backup_style = "sync";   # Метод backup-a , создается дерево файлов для синхронизации
$cfg_save_old_backup = 1;
$cfg_type = "local";
$cfg_local_path = "/home/back/backup_data";  # путь где будет сохраняться бэкап.
$cfg_time_limit = 0;
$cfg_size_limit = 0;
$cfg_maximum_archive_size = 0;
$cfg_root_path = "/";
$cfg_verbose = 2;
$cfg_stopdir_prune=0;
1;            
__DATA__      # что бэкапим
/usr/local/etc
/etc
!/usr/local/etc/share  #Исключение
f!\.core$
f!^core$
f!\.o$
f!\.log$

Подробно, что есть что, можно посмотреть в стандартном конфиге.
Далее нужно поправить файл create_backup.sh
добавляем в начало такую строчку:
#!/bin/sh
HASH=`find /usr/home/back/backup_data -name *hash -mtime -1`

а в самый конец файла строки:
#проверяем были ли изменены файлы и если да то создаем архив
 if [ -n "${HASH}" ]; then
     (
     tar -cf /usr/home/back/backup_tar/arcamart.tar /usr/home/back/backup_data
     )
 else
    printf "===>>> not new backup\t" > backup_err.log | err_msg
 fi
    exit 0

Так же не забываем в этом файле поправить строчку config_files=«fsbackup.conf», указываем имя своего конфига.
И добавляем этот скрипт в крон (обязательно в крон рута).
Таким образом скрипт будет проводить синхронизацию дерева и при каких либо изменениях дополнительно создавать архив.
Теперь нам нужно дабавить пользователя back,
sudo pw useradd back -m -G back

Переходим в домашнюю директорию back и создаем нужные для работы папки
mkdir backup_tar # для архива синхронизированного дерева
mkdir .ssh # для авторизации по ключу (об этом далее)

На клиенте действия закончили, не считая создания ключика для авторизации по ssh
Теперь о настройке серверной части:
Значит нам нужно, что бы серверная часть, удаленно подключалась по очереди к каждому клиенту, проверяла на наличие нового бэкапа и копировала в случае успеха себе.
Кроме этого серверная сторона должна уметь делать проверку на доступность хостов, а также писать логи.
Начнем:
Создаем также пользователя back. (небольшое уточнение, у меня на серверной стороне папка home имеет отличный путь от хостов, например на хосте /usr/home/back, а на сервере /usr/local/home/back, будьте внимательны)
[root@server /usr/local/home/back]mkdir .ssh

Теперь создаем ключи для авторизации
[root@server /usr/local/home/back/.ssh] ssh-keygen

Теперь, чтобы сервер мог авторизовываться на хостах без ввода пароля, нужно просто скопировать файл с public key в файл $home/.ssh/authorized_keys (тоесть на все ваши клиентские хосты)
Также не забываем выставить права и владельца на файл authorized_keys
sudo chmod 600 authorized_keys
sudo chown back:back authorized_keys

Итак, начинаем писать скрипт который будет делать то что нам нужно:
Для начала создаем файл if_routers который будет содержать список ваших хостов

Пример: ee if_routers:
octet=«192.168»
test="${octet}.0.1"
test2="${octet}.0.2"
test3="${octet}.0.3"
test4="${octet}.0.4"
test5="${octet}.0.5"


Создаем файл с любым название, пусть будет sbackup.sh
Содержимое:
#!/bin/sh
s_copy="/usr/local/bin/rsync -azv -e \"ssh -l back -o StrictHostKeyChecking=no\""
DST="/usr/local/home/back/backup_data"   #директория хранения бэкапов на сервере                                             
dir_1="/usr/home/back"                   #хоум директория удаленных хостов
dir_2="/usr/local/home/back"             #хоум директория сервера
dir_3="/usr/home/back/backup_tar"        #диектория архивов на удаленных хостах 
HOME_DIR="/usr/local/home"               #хоум 

#подключаем наш файлик со списком хостов
if [ -f ${dir_2}/if_routers ]; then
         . ${dir_2}/if_routers
           else
                echo "Procedure ${dir_1}/if_routers is not install" > ${dir_2}/backup.log 2>&1
                exit 1
fi
TIMESTAMP=`date +"%Y-%m-%d %R"`
#Функция для проверки доступности хостов методом ping 
get_alive ()
{
         check_host="/usr/local/sbin/fping -a"
         eval ${check_host} $1 > /dev/null 2>&1
}
err_msg ()
{
                   printf "DATE: $TIMESTAMP.\n" >> ${dir_2}/backup_err.log
}
#собственно тут все и происходит, проверка, копирование, вывод в лог, я думаю тут понятно, так как очень просто.
get_alive $TEST
 if [ $? -eq 0 ]; then
 BACKTEST=`ssh -i /usr/local/home/back/.ssh/id_dsa back@192.168.0.1 "find /usr/home/back/backup_tar -name *.tar -mtime -1 | sed -E 's/.*\///g'"`
       if [ -n "${BACKTEST}" ]; then
          (printf "===>>> Start remote backup:   ${TIMESTAMP}\n"
           printf " \n"
           printf "===================================\n"
           printf "$ts  ===>>>${dir_1}\n"
           printf "\n"
           eval ${s_copy} back@${TEST}:${dir_3}/${BACKTEST} ${DST}
           ) > ${dir_2}/backup.log 2>&1
       else
 printf "===>>> Host: $test is not new backup\t" > ${dir_2}/backup_err.log
       fi
      else
          printf "===>>> Host: $test is down\t" > ${dir_2}/backup_err.log | err_msg
          exit 1
    fi
#далее можно продолжать для каждой новой точки, начиная с get_alive $хост
exit 0

Сохраняем и создаем папку /usr/local/home/back/backup_data
Теперь можно запустить скрипт для проверки работоспособности. Не забываем ставить chmod +x
А также уточню, для того, чтобы скрипт нормально конектился с удаленными хостами, его нужно запускать от имени пользователя back
sudo su — back ./sbackup.sh
И добавляем в крон
sudo crontab -u back -e
Готово.
Итог имеем на сервере, всегда свежий бэкап, причем без лишнего копирования, тоесть только при изменении файлов.
Для восстановления, нужно всего лишь разархивировать нужный архив на тот хост который требуется восстановить.

Всем спасибо за внимание, надеюсь ничего не забыл.
Tags:
Hubs:
+2
Comments 0
Comments Leave a comment

Articles