Wednesday, September 12, 2018

System backup for virtual machine using USB storage

Introduction
My company is currently running several virtual machines and most of them are in production.
One of the host machines is running has a web server virtual machine and a database server virtual machine. These VMs OS need to be backup regularly. These VMs are connected to the host storage directly (raw), hence it is not possible to perform snapshots.

%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3Bhtml%3D1%3BentryX%3D0.5%3BentryY%3D0%3BentryPerimeter%3D0%3BendArrow%3Dnone%3BendFill%3D0%3BjettySize%3Dauto%3BorthogonalLoop%3D1%3B%22%20edge%3D%221%22%20source%3D%224%22%20target%3D%229%22%20parent%3D%221%22%3E%3CmxGeometry%20relative%3D%221%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%223%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3Bhtml%3D1%3BentryX%3D0.5%3BentryY%3D0%3BentryPerimeter%3D0%3BendArrow%3Dnone%3BendFill%3D0%3BjettySize%3Dauto%3BorthogonalLoop%3D1%3B%22%20edge%3D%221%22%20source%3D%224%22%20target%3D%228%22%20parent%3D%221%22%3E%3CmxGeometry%20relative%3D%221%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%224%22%20value%3D%22%22%20style%3D%22fontColor%3D%230066CC%3BverticalAlign%3Dtop%3BverticalLabelPosition%3Dbottom%3BlabelPosition%3Dcenter%3Balign%3Dcenter%3Bhtml%3D1%3BoutlineConnect%3D0%3BfillColor%3D%23CCCCCC%3BstrokeColor%3D%236881B3%3BgradientColor%3Dnone%3BgradientDirection%3Dnorth%3BstrokeWidth%3D2%3Bshape%3Dmxgraph.networks.virtual_server%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22387%22%20y%3D%2290%22%20width%3D%22110%22%20height%3D%22120%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%225%22%20value%3D%22KVM%20Host%20Machine%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22380%22%20y%3D%2250%22%20width%3D%22124%22%20height%3D%2220%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%226%22%20value%3D%22Virtual%20Machine%20A%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22235.5%22%20y%3D%22347%22%20width%3D%22124%22%20height%3D%2220%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%227%22%20value%3D%22Virtual%20Machine%20B%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22513.5%22%20y%3D%22340%22%20width%3D%22124%22%20height%3D%2220%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%228%22%20value%3D%22%22%20style%3D%22fontColor%3D%230066CC%3BverticalAlign%3Dtop%3BverticalLabelPosition%3Dbottom%3BlabelPosition%3Dcenter%3Balign%3Dcenter%3Bhtml%3D1%3BoutlineConnect%3D0%3BfillColor%3D%23CCCCCC%3BstrokeColor%3D%236881B3%3BgradientColor%3Dnone%3BgradientDirection%3Dnorth%3BstrokeWidth%3D2%3Bshape%3Dmxgraph.networks.virtual_pc%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22240%22%20y%3D%22240%22%20width%3D%22115%22%20height%3D%2285%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%229%22%20value%3D%22%22%20style%3D%22fontColor%3D%230066CC%3BverticalAlign%3Dtop%3BverticalLabelPosition%3Dbottom%3BlabelPosition%3Dcenter%3Balign%3Dcenter%3Bhtml%3D1%3BoutlineConnect%3D0%3BfillColor%3D%23CCCCCC%3BstrokeColor%3D%236881B3%3BgradientColor%3Dnone%3BgradientDirection%3Dnorth%3BstrokeWidth%3D2%3Bshape%3Dmxgraph.networks.virtual_pc%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22518%22%20y%3D%22240%22%20width%3D%22115%22%20height%3D%2285%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2210%22%20value%3D%22%22%20style%3D%22edgeStyle%3DorthogonalEdgeStyle%3Brounded%3D0%3Bhtml%3D1%3BendArrow%3Dnone%3BendFill%3D0%3BjettySize%3Dauto%3BorthogonalLoop%3D1%3B%22%20edge%3D%221%22%20source%3D%2211%22%20target%3D%224%22%20parent%3D%221%22%3E%3CmxGeometry%20relative%3D%221%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2211%22%20value%3D%22%22%20style%3D%22fontColor%3D%230066CC%3BverticalAlign%3Dtop%3BverticalLabelPosition%3Dbottom%3BlabelPosition%3Dcenter%3Balign%3Dcenter%3Bhtml%3D1%3BoutlineConnect%3D0%3BfillColor%3D%23CCCCCC%3BstrokeColor%3D%236881B3%3BgradientColor%3Dnone%3BgradientDirection%3Dnorth%3BstrokeWidth%3D2%3Bshape%3Dmxgraph.networks.usb_stick%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22419.5%22%20y%3D%22240%22%20width%3D%2245%22%20height%3D%22100%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3CmxCell%20id%3D%2212%22%20value%3D%22USB%20Storage%22%20style%3D%22text%3Bhtml%3D1%3BstrokeColor%3Dnone%3BfillColor%3Dnone%3Balign%3Dcenter%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3B%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22387%22%20y%3D%22347%22%20width%3D%22124%22%20height%3D%2220%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E
System Configuration

Host Machine Virtual Machine A Virtual Machine B
Operating System CentOS Linux 7 (Core) CentOS Linux 7 (Core) CentOS Linux 7 (Core)
Kernel Linux 3.10.0-327.10.1.el7.x86_64 Linux 3.10.0-327.10.1.el7.x86_64 Linux 3.10.0-327.10.1.el7.x86_64
Architecture x86-64 x86-64 x86-64
KVM qemu-kvm-1.5.3-105.el7_2.3.x86_64 NA NA
Commands to perform the above task:
Operating System status
#hostnamectl status
KVM Version
#rpm -qa qemu-kvm
To check if VMs configuration
#ls /etc/libvirt/qemu/
then open file of the specific vm

Design Phase:
1. Make sure USB has enough space. I bought a 2TB western digital.
2. Make a primary partition of the USB with ext4 filesystem
3. Create qcow2 image volume for VMs
4. Attach the volumes to VMs
5. Create File system and mount
6. Configure the backup script
7. Test and add to crontab

Feature of the backup script
  • On Monday run Full backup of following directories
    /srv /opt /bin /lib64 /lib /sbin /usr /boot /etc /home /root /var
  • Tue-Fri run Incremental backup of following directories
    /srv /opt /bin /lib64 /lib /sbin /usr /boot /etc /home /root /var
  • Keep only 14 days backup files
  • Send email notification of backup status.
Below is the script

 #!/bin/bash  
 # A UNIX / Linux shell script to backup vm system dirs to usb device.  
 # This script make both full and incremental backups.  
 # Each backup files will be named as Mon, Tue, Wed, Thu and Fri.  
 # The script must be run at low peak each day using cronjons.  
 # Script must run as root or configure permission via sudo.  
 # -------------------------------------------------------------------------  
 # Copyright (c) 2018 http://smnawaz.blogspot.com  
 # -------------------------------------------------------------------------  
 # -------------------------------------------------------------------------  
 # Last updated on : September-2018 - Script added to cron.  
 # -------------------------------------------------------------------------  
 LOGBASE=/backup/log  
 #Notification to responsible team  
 EMAIL="smnawaz@blogspot.com, example@google.com"  
 # Backup dirs; do not prefix /  
 BACKUP_ROOT_DIR="/srv /opt /bin /lib64 /lib /sbin /usr /boot /etc /home /root /var"  
 # Get todays day like Mon, Tue and so on  
 NOW=$(date +"%a")  
 # Backup location  
 USB_WD="/backup"  
 BACKUP_FILE=/$(date "+%Y-%m-%d-%a").backup  
 # Exclude file  
 TAR_ARGS=""  
 EXCLUDE_CONF=/root/scripts/.backup.exclude.conf  
 # Backup Log file  
 LOGFILE=$LOGBASE/$NOW.backup_system_usb.log  
 # Path to binaries  
 TAR=/bin/tar  
 MKDIR=/bin/mkdir
 #Delete backup files if greater than below days
 KEEP_FILES_DAYS=14
 # ------------------------------------------------------------------------  
 # Excluding files when using tar  
 # Create a file called $EXCLUDE_CONF using a text editor  
 # Add files matching patterns such as follows (regex allowed):  
 # home/shahn/iso  
 # home/shahn/*.cpp~  
 # ------------------------------------------------------------------------  
 [ -f $EXCLUDE_CONF ] && TAR_ARGS="-X $EXCLUDE_CONF"  
 #### Custom functions #####  
 backup_status(){  
  local s=$1  
 if [ $s -eq 0 ]  
 then  
    echo $(date "+%D %T") SYSTEM BACKUP SUCCESSFUL  
    echo -e "Backup Successfully done @ $(hostname)\n\nList the files:\n# tar tvf /backup/example.tar.gz\n\nExtract the entire archive into current directory:\n# tar xvpf /backup/example.tar.gz\n\nExtract only certain files or dirs into current directory. For example. Extract only home/shahn directory: \n# tar xvpf /backup/example.tar.gz home/shahn\n\nYou can also restore one file:\n# tar xvpf /backup/example.tar.gz home/shahn/example.txt" | mutt -s "Backup Done for $(hostname)" $EMAIL -a $LOGFILE  
 else  
    echo $(date "+%D %T") SYSTEM BACKUP FAILED  
    echo "Backup FAILED @ $(hostname)" | mutt -s "Backup Failed for $(hostname)" $EMAIL -a $LOGFILE  
 fi  
 }  
 # Make a full backup  
 full_backup(){  
  local old=$(pwd)  
  cd /  
  echo $(date "+%D %T") SYSTEM BACKUP STARTED  
  $TAR $TAR_ARGS -cvpf $USB_WD$BACKUP_FILE.full.tar.gz $BACKUP_ROOT_DIR  
  df -h $USB_WD  
  backup_status $?  
  cd $old  
 }  
 # Make a partial backup  
 partial_backup(){  
  local old=$(pwd)  
  cd /  
  echo $(date "+%D %T") SYSTEM BACKUP STARTED  
  $TAR $TAR_ARGS -cvpf $USB_WD$BACKUP_FILE.incre.tar.gz -N "$(date -d '1 day ago')" $BACKUP_ROOT_DIR  
  df -h $USB_WD  
  backup_status $?  
  cd $old  
 }  
 # Make sure all dirs exits  
 verify_backup_dirs(){  
  local s=0  
  for d in $BACKUP_ROOT_DIR  
  do  
  if [ ! -d $d ];  
  then  
  echo "Error : $d directory does not exits!"  
  s=1  
  fi  
  done  
  # if not; just die  
  [ $s -eq 1 ] && exit 1  
 }  
 #Delete old backup  
 delete_oldest_backup() {  
  if [[ $(find $USB_WD -mtime +$KEEP_FILES_DAYS -print) ]]  
  then  
  echo "Deleteing files greater $KEEP_FILES_DAYS days"  
  find $USB_WD -type d -mtime +$KEEP_FILES_DAYS -name '*.tar.gz' -exec rm -f {} \;  
  fi  
 }  
 #### Main logic ####  
 # Make sure log dir exits  
 [ ! -d $LOGBASE ] && $MKDIR -p $LOGBASE  
 # Verify dirs  
 verify_backup_dirs  
 #Clean old files  
 delete_oldest_backup  
 # Okay let us start backup procedure  
 # If it is monday make a full backup;  
 # For Tue to Fri make a partial backup  
 # Weekend no backups  
 case $NOW in  
  Mon) full_backup;;  
  Tue|Wed|Thu|Fri) partial_backup;;  
  *) ;;  
 esac > $LOGFILE 2>&1  

Now its time to implement the script.
Remember we are going to implement the above design in live VM.

Step 1:
Plug the USB in the host machine and chek it
#lsblk

Step 2:
#create ext4 file system for the usb drive
fdisk /dev/sde (this was my usb)
delete ntfs partiition
create new primary partition
write partition
partprobe /dev/sde1
mkfs.ext4 /dev/sde1
mount /dev/sde1 /backup (create a directory)

Step 3:
#Create qcow2 image volumes of 300G for VM
qemu-img create -f qcow2 /backup/virtual-machine-A-300G.qcow2 300G
qemu-img create -f qcow2 /backup/virtual-machine-A--300G.qcow2 300G

Step 4:
Here I am attaching the image volume to target VMs as a virtual disk vdb
#attached image volume to VMs
#virsh attach-disk virtual-machine-A /backup/virtual-machine-A-300G.qcow2  --target vdb  --subdriver qcow2 --targetbus virtio --config --live

#virsh attach-disk virtual-machine-B /backup/virtual-machine-B-300G.qcow2  --target vdb  --subdriver qcow2 --targetbus virtio --config --live

Step5:
Go inside each VM and you can see the block disk:
lsblk
#create ext4 file system for of the new attached disk under VMs
fdisk /dev/vdb
create new primary partition
write partition
partprobe /dev/vbd1
mkfs.ext4 /dev/vdb1
mount /dev/vdb1 /backup

Step 6:
Now place the backup script in some safe place.
vim /root/scripts/backup_system

Step 7:
change the permission
chmod 700 /root/scripts/backup_system

Step 8:
#Add entry to crontab which  will be runing at low pick hour
crontab -e
00 01 * * * /root/scripts/backup_system >> /var/log/backup_system.log 2>&1

Step 9:
There is a exclution list which wont be backup. For that below steps are required.
#configure the exclution list
vim /root/scripts/.backup.exclude.conf
/var/run/*
/var/lock/*
/var/log/lastlog
/var/lost+found/*

Note: Above task was based on the change request that I had done. Need to do your own steps. This is just a reference.

Reference:
http://codeformatter.blogspot.com/
Share:

0 comments:

Post a Comment