Központosított mentés rsync- kel

Feladat:
Központosított mentési kiszolgáló kialakítása
Elvárások:

  • Rsync- ken alapul és a mentési helyek hozzáadása, eltávolítása könnyen módosítható.
  • A napi mentésről email értesítést küldjön a megadott email címre.
  • A mentés módja az alábbiak szerint működjön:
  • Minden hónap 1- én szinkronizálja a helyi és a távoli adatokat (teljes mentés, a mentési helyen törölje azokat az adatokat, amik már nem elérhetők a távoli szerveren)
  • Minden vasárnap az előző vasárnap óta történt változásokat mentse (teljes mentés)
  • Minden héten hétfőtől szombatig inkrementális mentést készítsen külön könyvtárba
  • Csak az elmúlt két hét mentését tárolja, a régebbit törölje

A fent felsorolt feladatok mindegyikére alkalmas az rsync alkalmazás.
A következőkben először a mentendő kiszolgáló beállításait mutatom be, majd a mentést végző szerver működését.

Mentendő szervereken elvégzendő beállítások:

  • Rsync csomag telepítése
  • /etc/default/rsync fájl szerkesztése, az alábbi tartalom beállítása:

RSYNC_ENABLE=true


RSYNC_CONFIG_FILE=/etc/rsyncd.conf


  • /etc/rsyncd.conf létrehozása. Ez tartalmazza a beállításokat:

use chroot = yes


max connections = 1


uid = root


gid = root


timeout = 600


read only = yes


host allow = backupserver


ignore nonreadable = yes


refuse options = checksum



[etc]


    path = /etc



[boot]


    path = /boot



[varwww]


    path = /var/www

A konfiguráció két jól elkülönülő részből áll. A felső rész a globális beállításokat tartalmazza, ezek minden, az alsó szakaszban beállított elérésekre érvényesek, viszont ha a path alatti sorokba más opciót írunk, akkor az adott szakaszra az itt megadott beállítások lesznek érvényesek.

Például ha azt szeretnénk, hogy a /data könyvtárba rsync-kel is lehessen adatot írni, akkor a következőket kell beállítani:

[data]


   path = /data


   read only = no

Az rsync daemon elindítását (/etc/init.d/rsync start)követően a mentendő szerver beállításaival elkészültünk.

Backup server beállításai

Rsync segítségével teljes biztonsági mentést pl a következő paranccsal végzek:

rsync -avz --size-only szerver1::etc /backup/szerver1/etc

Teljes mentés, a backup szerveren töröljük azokat a fájlokat, amik a mentendő helyen már nem elérhetők:

rsync -avz --size-only --delete szerver1::etc /backup/szerver1/etc

Inkrementális mentés rsync- kel:

rsync -avzm --size-only  --compare-dest=/backup/szerver1/etc  szerver1::etc /backup/szerver1/diff/etc

Kapcsolók jelentése:
-a archiv mód, ami a következőket tartalmazza: rekurzív (r), symlinket symlinkként másol (l), megtartja a jogokat (p), létrehozási időt megtartja (t), a tulajdonos csoport megtartása (g), tulajdonos csoport megtartása (o), ...
-v bőbeszédű mód
-z tömöríti az adatokat a hálózati forgalmazás során
-m törli az üres könyvtárszerkezeteket. Ezt sajnos nem teljesen teszi meg, így ahogy a késöbbiekben is látható, a következő karanccsal törlöm az üres könyvtárakat: find ${DIFF_KONYVTAR[$i]}/ -depth -type d -empty -exec rmdir {} \;
--size-only csak a fájlok méretét veszi alapul, nem a tartalmát - lényegesen meggyorsítja a mentés folyamatát
--delete törli a célhelyen azokat a fájlokat, könyvtárakat, amik nem elérhetők a forrás helyen
--compare-dest az itt megadott helyet veszi etalonnak az inkrementális mentés során
--exclude-from a megadott fájlban soronként felsoroltakra illeszkedő könyvtárakat, fájlokat nem menti

Létrehoztam egy bash shell script- et, ami a fent leírt feladatot elvégzi. A script elején adatokat deklarálok:


TAVOLI_KONYVTAR[1]=szerver1::boot


HELYI_KONYVTAR[1]=/backup/szerver1/boot


DIFF_KONYVTAR[1]=/backup/szerver1/diff/boot


EXCLUDE[1]=""


LOG_FAJL[1]=/backup/log/szerver1.log



TAVOLI_KONYVTAR[2]=szerver1::samba


HELYI_KONYVTAR[2]=/backup/szerver1/samba


DIFF_KONYVTAR[2]=/backup/szerver1/diff/samba


EXCLUDE[2]=/etc/scripts/exclude-szerver1


LOG_FAJL[2]=/backup/log/szerver1.log

Az itt megadott adatok alapján fog a script menteni. Látható, hogy az adatokat tömbökbe vesszük fel. Fontos, hogy a tömb minden indexéhez legyen érték rendelve!
Ezeket az adatokat lehetne valamilyen adatbázisban tárolni és szükség esetén onnan lekérdezni...
Szükség esetén az EXCLUDE változónak is adhatunk értéket, ami egy szöveges fájlra mutat. Az ebben a fájlban soronként felsorolt szövegrészekre illeszked ő fájlokat, könyvtárakat az rsync ki fogja hagyni.
Például ha azt szeretnénk, hogy a log fájlokat és a cache könyvtárat ne mentse, akkor a /etc/scripts/exclude-szerver1 fájlt az alábbi tartalommal kell létrehozni:

*.log


cache

Fontos, hogy felesleges szóközök és egyéb karakterek ne legyenek a fájlban, mert befolyásolják a mentést.
Az adatok beállítását követő rész a script lényegi része, ami a mentést végzi.
A saját szkriptek és konfigurációs fájlok tárolására a /etc/scripts könyvtárat szoktam létrehozni, mert egy kiszolgáló mentésekor jellemzően a /etc könyvtárat mentem és ezekről a saját készítésű dolgokról is célszerű mentést végezni, hiszen alkalmanként sok munkába kerülnek.
Tehát az EXCLUDE adatokat és magát a scriptet is a /etc/scripts- ben tárolom.

Következzen maga mentést végző szkript:

cat /etc/scripts/rsync.sh


#!/bin/bash



TAVOLI_KONYVTAR[0]=szerver1::etc


HELYI_KONYVTAR[0]=/backup/szerver1/etc


DIFF_KONYVTAR[0]=/backup/szerver1/diff/etc


EXCLUDE[0]=""


LOG_FAJL[0]=/backup/log/szerver1.log



TAVOLI_KONYVTAR[1]=szerver1::boot


HELYI_KONYVTAR[1]=/backup/szerver1/boot


DIFF_KONYVTAR[1]=/backup/szerver1/diff/boot


EXCLUDE[1]=""


LOG_FAJL[1]=/backup/log/szerver1.log




TAVOLI_KONYVTAR[2]=szerver1::samba


HELYI_KONYVTAR[2]=/backup/szerver1/samba


DIFF_KONYVTAR[2]=/backup/szerver1/diff/samba


EXCLUDE[2]=/etc/scripts/exclude-szerver1


LOG_FAJL[2]=/backup/log/szerver1.log



TAVOLI_KONYVTAR[3]=szerver1::home


HELYI_KONYVTAR[3]=/backup/szerver1/imap


DIFF_KONYVTAR[3]=/backup/szerver1/diff/imap


EXCLUDE[3]=/etc/scripts/exclude-szerver1


LOG_FAJL[3]=/backup/log/szerver1.log



TAVOLI_KONYVTAR[4]=szerver2::etc


HELYI_KONYVTAR[4]=/backup/szerver2/etc


DIFF_KONYVTAR[4]=/backup/szerver2/diff/etc


EXCLUDE[4]=""


LOG_FAJL[4]=/backup/log/szerver2.log



TAVOLI_KONYVTAR[5]=szerver2::boot


HELYI_KONYVTAR[5]=/backup/szerver2/boot


DIFF_KONYVTAR[5]=/backup/szerver2/diff/boot


EXCLUDE[5]=""


LOG_FAJL[5]=/backup/log/szerver2.log



TAVOLI_KONYVTAR[6]=szerver2::samba


HELYI_KONYVTAR[6]=/backup/szerver2/samba


DIFF_KONYVTAR[6]=/backup/szerver2/diff/samba


EXCLUDE[6]=/etc/scripts/exclude-szerver2


LOG_FAJL[6]=/backup/log/szerver2.log



UTOLSO_MENTES_NAP=14


REGINAP=`date --date="$UTOLSO_MENTES_NAP day ago" +%Y%m%d`


MAINAP=`date +%Y%m%d`


LOGFAJL="/backup/log/rsync.log"


NAPSZAM=`date +%u`


DATUM_NAP=`date +%d`


ADMIN_EMAIL=info@linuxadm.hu



# A meg futo mentest megallitjuk:


pkill 'rsync -azv'



df -h /backup > $LOGFAJL



echo -e "\n`date` ============== Rsync Start ==============" >> $LOGFAJL



if [ $NAPSZAM -eq 7 ] && [ $DATUM_NAP -ne 01 ]


then



#Vasarnap van, nem elseje -> Teljes mentes



    echo "`date` ============== Teljes mentes " >> $LOGFAJL


    for  ((i=0; i<${#TAVOLI_KONYVTAR[*]}; i++ )) do


        SZAMLALO=$((i+1))


        echo "`date` $SZAMLALO / ${#TAVOLI_KONYVTAR[*]} ============== ${TAVOLI_KONYVTAR[$i]}" >> $LOGFAJL


            echo "`date` ============== ${TAVOLI_KONYVTAR[$i]}" >> ${LOG_FAJL[$i]}


        if [ ${#EXCLUDE[$i]} -eq 0 ]


        then


            EXCLUDE_STRING=""


        else


            EXCLUDE_STRING="--exclude-from=${EXCLUDE[$i]}"


        fi


                rsync -azv --size-only $EXCLUDE_STRING= ${TAVOLI_KONYVTAR[$i]} ${HELYI_KONYVTAR[$i]} >> ${LOG_FAJL[$i]}


    done


else


    if [ $DATUM_NAP -eq 01 ]


    then



#Elseje van -> Teljes mentes, torlessel



                echo "`date` ============== Teljes mentes torlessel " >> $LOGFAJL


        for  ((i=0; i<${#TAVOLI_KONYVTAR[*]}; i++ )) do


            SZAMLALO=$((i+1))


                        echo "`date` $SZAMLALO / ${#TAVOLI_KONYVTAR[*]} ============== ${TAVOLI_KONYVTAR[$i]}" >> $LOGFAJL


                    echo "`date` ============== ${TAVOLI_KONYVTAR[$i]}" >> ${LOG_FAJL[$i]}


                        #============== Regi mentes torlese


                        rm -rf ${DIFF_KONYVTAR[$i]}/$REGINAP


                    if [ ${#EXCLUDE[$i]} -eq 0 ]


                    then


                    EXCLUDE_STRING=""


                    else


                            EXCLUDE_STRING="--exclude-from=${EXCLUDE[$i]}"


                    fi


                        rsync -azv --size-only --delete $EXCLUDE_STRING ${TAVOLI_KONYVTAR[$i]} ${HELYI_KONYVTAR[$i]} >> ${LOG_FAJL[$i]}


    done


    else



#Hetfotol szombatig (nincs vasarnap, sem elseje ) -> Inkrementalis mentes



                echo "`date` ============== Inkrementalis mentes " >> $LOGFAJL


        for  ((i=0; i<${#TAVOLI_KONYVTAR[*]}; i++ )) do


            SZAMLALO=$((i+1))


            echo "`date` $SZAMLALO / ${#TAVOLI_KONYVTAR[*]} ============== ${TAVOLI_KONYVTAR[$i]}" >> $LOGFAJL


                        echo "`date` ============== ${TAVOLI_KONYVTAR[$i]}" >> ${LOG_FAJL[$i]}


            #============== Mai naphoz a konyvtar letrehozasa


            if [ ! -d "${DIFF_KONYVTAR[$i]}/$MAINAP" ]


            then


                mkdir -p ${DIFF_KONYVTAR[$i]}/$MAINAP


            fi


                        #============== Regi mentes torlese


                        if [  -d "${DIFF_KONYVTAR[$i]}/$REGINAP" ]


            then


                rm -rf ${DIFF_KONYVTAR[$i]}/$REGINAP


            fi


            #============== Mentunk


            if [ ${#EXCLUDE[$i]} -eq 0 ]


            then


                                EXCLUDE_STRING=""


                        else


                                EXCLUDE_STRING="--exclude-from=${EXCLUDE[$i]}"


            fi


            rsync -azvm --size-only $EXCLUDE_STRING --compare-dest=${HELYI_KONYVTAR[$i]}  ${TAVOLI_KONYVTAR[$i]} ${DIFF_KONYVTAR[$i]}/$MAINAP  >> ${LOG_FAJL[$i]} &&  find ${DIFF_KONYVTAR[$i]}/ -depth -type d -empty -exec rmdir {} \;


        done


    fi


fi



echo "`date` ============== Rsync Finished ==============" >> $LOGFAJL



echo "============== Mai mentes merete: ==============" >> $LOGFAJL


du -sh /backup/*/diff/*/$MAINAP/ | grep -v K >> $LOGFAJL


echo "============== Maradek hattertar : ==============" >> $LOGFAJL


df -h /backup >> $LOGFAJL



mail $ADMIN_EMAIL -s " Rsync mentes $MAINAP " < $LOGFAJL



# Logrotalas


mv $LOGFAJL $LOGFAJL.$MAINAP


rm $LOGFAJL.$REGINAP

A fenti shell script elvégzi a munkát, már csak a rendszeres futtatásról kell gondoskodni. Ehhez az alábbi sort kell beilleszteni a /etc/crontab- ba:
0 19    * * *    root    /etc/scripts/rsync.sh

Így a mentés minden nap 19:00- kor fog elindulni.

Innen letölthető, egy köszönöm, jólesik...