The current backup policy is a two-step process. First, all hosts run a daily and/or weekly shell script in cron that creates one (or more) compressed tar files with the relevant content to be stored as backup in a temporary directory. Then, the backup server runs a rsync to gather all the backup files from hosts and delete them from their remote origin. At the end of each transference a sub-procedure is executed to perform the backup rotate. NOTE: The execution of the fetch procedure in the server must occur after the daily and weekly jobs of the hosts. This assures that the fetch function of the remote server will run just after the hosts backup procedures. 1.1. Distribution-based information Table 1-1. Backup host Scripts User User key Temporary backup location /etc/cron.weekly/backup backup /home/backup/.ssh/authorized_keys /mnt/backup Table 1-2. Backup server Server Script User User key Back-up location vroot03.planet-lab.eu /etc/backup_helper, /etc/cron.daily/backup, /etc/cron.daily/fetch-n-rotate-backup backup /home/backup/.ssh/id_rsa.* /home/backup 1.2. Installation 1.2.1. Server installation Create a backup user and group and generate a pair of keys for it: # groupadd backup # useradd -c "Backup System" -g backup -m backup # su backup 1
# ssh-keygen -t rsa Copy the following files on the backup server and make them executable (chmod +x): backup-helper # Fetch all backups from a server # $1: backup user # $2: hostname function fetch_n_remove { HDIR= echo $2 cut -d\. -f1 BDIR="/home/backup/$HDIR" echo -n "Fetch backups from $2..." su backup -c "mkdir -pv $BDIR" su backup -c "rsync --exclude="lost+found" -a $1@$2:/mnt/backup/ $BDIR" RES=$? if [ $RES -eq 0 ]; then echo " [OK]" else echo " [KO]" fi su backup -c "ssh $1@$2 rm -rf /mnt/backup/* " return 0 # Do the rotation of backups in local repository /home/backup # $1: backup file pattern # $2: day pattern (e.g. 1-2-7 means the day after, two days after and one week after) function rotate_backup { export FP=$1 export DAYS=$2 export DATE= date +%Y%m%d-%H%M export LS= ls -1 /home/backup/${fp* ## embedded perl for the hard part - bash and python sucks! sorry! perl << EOF use strict; use Time::Local; my $debug = 1; my %store; my $fp = $ENV{ FP ; my $date = $ENV{ DATE ; my $rotate_days = $ENV{ DAYS ; my $ls_cmd = join /\n/, $ENV{ LS ; my @ls_cmd = split /\s+/, $ls_cmd; my @rotate_days = split /-/, $rotate_days; if ($debug) {print "=========\n"; foreach my $bday (reverse @rotate_days) { if ($debug){ print "(bday $bday)\n"; while ( $_ = shift (@ls_cmd) ){ /(\d{4)(\d{2)(\d{2)/; my $bakdate = timelocal(0,0,0,$3,$2-1,$1)/(60*60*24); my $mydate = time/(60*60*24); my $age = int($mydate-$bakdate); if ( ($age > $bday) ($store{$bday) ){ 2
EOF else{ if ($debug) {print " rm -f $_ ; if ($debug) {print " $store{$bday=1; last; (age $age) Deleting $_\n"; (age $age) Keeping $_\n"; fetch-backup: add the entries for the fetch_and_remove and for the rotate_backup for each host (e.g. vroot01 and vroot02) fetch_n_remove backup vroot01.planet-lab.eu rotate_backup vroot01/vroot01-etc- 1-2-3-7-14-30-60-120 fetch_n_remove backup vroot02.planet-lab.eu rotate_backup vroot02/vroot02-etc- 1-2-3-7-14-30-60-120 1.2.2. Host installation (adding a new host) The specific scripts for the host installation depend on the backup policy and the host type (the applications it runs and the data it stores). Please see Chapter 16 Section 4 Backup policy documentation, for more information. In this section we present only an overview of the installation process. Its details and the decision of what is supposed to be stored is not part of the scope of this document. The host installation is a two-step procedure: the host-side configuration and the server-side configuration. 1.2.2.1. Host-side configuration And create the /mnt/backup directory owned by the backup user: # mkdir /mnt/backup # chown backup:backup /mnt/backup Create the user and group backup: # groupadd backup # useradd -c "Backup System" -g backup -m backup NOTE: If the user backup is already used by the system (usually in Debian distributions) create backup2 and remember to use it also in the server configuration process. 3
Create the following files and make them executable (chmod +x): /etc/cron.daily/backup (if necessary, a similar script could be placed in the /etc/cron.weekly for a weekly backup). This script will create the backup tar and database dump files and change the file permissions of the /mnt/backup/ directory. The functions of this script depends on the backup policies outlined in 16 Section 4. What we present below is a generic script: #!/bin/sh DATE= date +%Y%m%d-%H%M HOST= hostname -s (cd / ; tar czf /mnt/backup/$host-etc-$date.tgz etc) chown -R backup: /mnt/backup NOTE: The files in /mnt/backup/ directory must be writable by the backup user since they should be deleted from the remote backup server after the execution of rsync. The backup user s public key (which was generated in /home/backup/.ssh/authorized_keys during the installation of the server) 1.2.2.2. Server-side configuration On the backup server (currently vroot03), edit the file: /etc/cron.daily/fetch-n-rotate-backup: fetch_n_remove backup vroot02.planet-lab.eu rotate_backup vroot02/vroot02-etc- 1-7-14-30-60-120 Where the arguments for: fetch_n_remove are: the remote user used by rsync the host rotate_backup are: the filepath pattern (starting from /home/backup) the backup rotate days (in the example 1-7-14-30-60-120, the backup stores the previous day, week, fortnight and previous one, two and three months) 4
1.2.3. Backup scripts Here is a short explanation of the backup scripts: /etc/backup-helper defines functions to backup filesystems, databases and VServer instances. /etc/cron.daily/backup executes the tar procedures and databases (mysql and postgre) dump, when necessary. /etc/cron.daily/fetch-n-delete-backup retrieves backups from our servers via rsync and performs the rotate. We also have some scripts of specific use, for example: DB MySQL dump: shell> mysqldump --all-databases -u root -pxxxx > /tmp/backup/file.dump DB MySQL restore: shell> mysql --verbose --user=root --password=xx cacti < /tmp/backup/file.dump DB Postgre dump: shell> pg_dumpall -h $PGHOST -U $PGUSER > db.out DB Postgre restore: shell> psql -f db.out postgres 5