Backup de Máquinas Virtuais

De Infraestrutura São Carlos
Ir para navegação Ir para pesquisar

Objetivo

Configuração dos scripts para backup das Máquinas Virtuais alocadas na Nuvem.

Requisitos de Software

Nuvem privada instalada com máquinas virtuais em produção.

Procedimentos

Montando a partição iSCSI

Será montado uma partição iSCSI para gravação dos arquivos de backup das MV.

  1. Para backup utilizaremos um volume iSCSI montada no diretório /backup_storage:
    Descobrir os compartilhamentos iSCSI:
    # iscsiadm -m discovery -t st -p 192.168.0.100
    Ver os nós capturados:
    # iscsiadm -m node
  2. Conectar o node desejado:
    # iscsiadm -m node --targetname "iqn.2001-05.com.equallogic:0-8a0906-dea03ab06-2c30000000c4d9df-xxxxx" --portal "192.168.0.100:3260" --login
  3. Verificar a partição criada:
    # fdisk -l
  4. Criar uma partição primaria ocupando todo o espaço:
    # fdisk /dev/sdc
  5. Formatar a partição criada:
    # mkfs.ext3 /dev/sdc1
  6. Criar o direrório /backup_storage.
  7. Montar a partição no diretório.

Automatizar a montagem da partição

Para deixar automático a montagem da partição, seguir os procedimentos:

  1. Editar o arquivo /etc/iscsi/iscsid.conf e configurar a opção node.startup para "automatic":
    node.startup = automatic
  2. Ligar o open-iscsi na inicialização:
    # chkconfig open-iscsi on

    Ou:

    # insserv open-iscsi
  3. Alterar a configuração do node para iniciar automaticamente:
    # iscsiadm -m node --targetname iqn.2001-05.com.equallogic:0-8a0906-dea03ab06-2c30000000c4d9df-xxxxx --portal 192.168.0.100:3260 -o update -n node.s
    tartup -v automatic
  4. Parar e inicializar o serviço iscsi:
    # /etc/init.d/open-iscsi stop
    # /etc/init.d/open-iscsi start
  5. Criar uma etiqueta(label) para a partição criada a partir do compartilhamento:
    # e2label /dev/sdd1 iscsi001
  6. Ediar o /etc/fstab e incluir a montagem do label para o diretório:
    LABEL=iscsi001 /backup_storage ext3 _netdev 0 0

Script de backup

O script foi escrito com base nas referências abaixo e alterado de acordo com a necessidade.

    O script a seguir faz backup completo das máquinas virtuais que compõem a nuvem. Tanto as que estão funcionando, quanto as paradas, suspensas, ou cópias. Foi utilizado o diretório /backup para conter o script.
  1. Criar o script backup.sh no diretório /backup:
    # vi backup.sh
  2. Exemplo de arquivo de backup:
    #!/bin/bash
    #Programa de criacao de backup de VMs
    #update: 23/12/2010
    echo "Programa de backup VM"
    echo " "
    
    dadosfull(){
    # diretorio que sera feito backup
    destino="/backup_storage/"
    # nome do arquivo
    nome_saida=" VM.xva"
    #data de inicio backup
    data=$(date +%d-%m-%Y-%H.%M)
    
    # Iniciando Log
    echo "Iniciando Backup das VMs: $data" >> /backup/live_backup_vm.log
    echo "------------------------------------------" >> /backup/live_backup_vm.log
    echo " " >> /backup/live_backup_vm.log
    }
    
    listavm(){
    # VMs para realizar Backup
    vm_backup_list=()
    vm_backup_list_count=${#vm_backup_list[@]}
    
    # Listando as Maquinas Virtuais
    vm_list_string=`xe vm-list is-control-domain=false power-state=running`
    #vm_list_string=`xe vm-list is-control-domain=false`
    IFS="
    "
    vm_list_array=($vm_list_string)
    vm_list_count=${#vm_list_array[@]}
    
    cont=0
    index=0
    for line in ${vm_list_array[@]}; do
     if [ ${line:0:4} = "uuid" ]; then
     uuid=`expr "$line" : '.*: \(.*\)$'`
     label=`expr "${vm_list_array[cont+1]}" : '.*: \(.*\)$'`
     echo "Adicionada ao backup: $label"
     let "index = $index+1"
     fi
     # Incrementa contador
     let "cont = $cont+1"
    done
    
    # Criando arrays para utilizacao
    vm_uuid_array=()
    vm_label_array=()
    }
    
    getvm(){
    # Pegando as VM da lista para exportacao
    echo "Analisando a lista de VMs..." >> /backup/live_backup_vm.log
    #Contador
    cont=0
    index=0
    for line in ${vm_list_array[@]}; do
     if [ ${line:0:4} = "uuid" ]; then
     uuid=`expr "$line" : '.*: \(.*\)$'`
     label=`expr "${vm_list_array[cont+1]}" : '.*: \(.*\)$'`
     vm_uuid_array[index]=$uuid
     vm_label_array[index]=$label
     echo "Added VM #$index: $uuid, $label" >> /backup/live_backup_vm.log
     let "index = $index+1"
     fi
     # Incrementa contador
     let "cont = $cont+1"
    done
    echo "Analise da Lista de VMs concluido..." >> /backup/live_backup_vm.log
    echo " " >> /backup/live_backup_vm.log
    }
    
    backupvm(){
    # Backup VMs
    echo "Backup VMs" >> /backup/live_backup_vm.log
    echo " " >> /backup/live_backup_vm.log
    
    #Contador
    cont=0
    
    for uuid in ${vm_uuid_array[@]}; do
     # Setando o estado da maquina
     backup_vm=false
     # Se a lista de Backups estiver vazia
     if [ $vm_backup_list_count = 0 ]; then
     # Faca backup de todas a Maquinas
     backup_vm=true
     # Senao, verifica se a maquina esta na lista de backups
     else
     for backup_uuid in ${vm_backup_list[@]}; do
     if [ $uuid = $backup_uuid ]; then
     backup_vm=true
     break
     fi
     done
     fi
    
     # Se o backup for para ser realizado
     if [ $backup_vm = true ]; then
     # O processo e iniciado
     echo "VM: $uuid" >> /backup/live_backup_vm.log
    
     # Label
     label=${vm_label_array[cont]}
    
     echo " "
     echo "Backup VM: $label"
     echo " "
    
     # Cria snapshot
     echo "Criando Snapshot..." >> /backup/live_backup_vm.log
     # Se contiver os drivers de VSS instalado
     snapshot=`xe vm-snapshot-with-quiesce vm=$uuid new-name-label="$label-backup-$data" &> /dev/null`
     log="Snapshot com quiesce"
     # Senao faz snapshot sem quiesce
     if [ $? -eq 0 ]; then
      snapshot=`xe vm-snapshot vm=$uuid new-name-label="$label-backup-$data"`
      log="Snapshot sem quiesce"
     fi
     echo $log
     echo $log >> /backup/live_backup_vm.log
     echo "Snapshot: $snapshot" >> /backup/live_backup_vm.log
    
     # Seta a VM para n?o ser um Template
     echo "Setando para nao ser um Template..." >> /backup/live_backup_vm.log
     snapshot_template=`xe template-param-set is-a-template=false uuid=$snapshot`
    
     # Deleta VM antiga
     echo "Deletando backup antigo..." >> /backup/live_backup_vm.log
     echo " "
     echo "Deletando backup antigo..."
     echo " "
     deletou=`rm -rf "$destino$label-backup.xva"`
    
     # Exporta
     echo "Exportando VM..." >> /backup/live_backup_vm.log
     echo "Exportando VM..." 
     echo
     #snapshot_export=`xe vm-export vm=$snapshot filename="$destino$label-$data$arq_saida"`
     snapshot_export=`xe vm-export vm=$snapshot filename="$destino$label-backup.xva"`
     echo "Exportado: $snapshot_export" >> /backup/live_backup_vm.log
     # Apaga snapshot
     echo "Deletando Snapshot..." >> /backup/live_backup_vm.log
     snapshot_delete=`xe vm-uninstall uuid=$snapshot force=true`
     echo "Deletado: $snapshot_delete" >> /backup/live_backup_vm.log
    
     # Se o backup nao for para ser realizado
     else
     # Log
     echo " " >> /backup/live_backup_vm.log
     echo "VM: $uuid" >> /backup/live_backup_vm.log
     echo "Backup de aquina Virtual Ignorado!" >> /backup/live_backup_vm.log
     fi
    
     # Incrementa contador
     let "cont = $cont+1"
    
    done
    
    echo " " >> /backup/live_backup_vm.log
    echo "Backup realizado com sucesso!!!" >> /backup/live_backup_vm.log
    echo "Backup realizado com sucesso!!!" 
    
    data=$(date +%d-%m-%Y-%H.%M)
    
    # Finalizando Log
    echo "Finalizando Backup das VMs: $data" >> /backup/live_backup_vm.log
    echo "--------------------------------------------" >> /backup/live_backup_vm.log
    echo " " >> /backup/live_backup_vm.log
    
    }
    
    enviaemail(){
    #Envia email
    tail -n 6 /backup/live_backup_vm.log | mail -r "backup@hc.ufpe.br" -s "Backup VM: $DATA" leandro.caetano@hc.ufpe.br
    }
    
    #Chamada das Funcoes
    dadosfull
    listavm
    getvm
    backupvm
    #enviaemail
    
    exit 0
    
  3. Para executar o script:
    # sh backup.sh
  4. Para executar diariamente inserir no agendamento:
    # crontab -e
    1 0 * * * sh /backup/backup.sh
  5. Serão criados arquivos de backup no diretório backup_storage. Para automação do script configura-lo no cron.

Ativando o servidor NFS no XenServer

Para facilitar o uso dos arquivos de backup em outros servidores (recuperação de backup por exemplo), vamos ativa o servidor de NFS que ja acompanha o XenServer.

Configurando o NFS

  1. Configurando o diretório /backup_storage para ser exportado:
    # vi /etc/exports
    Conteúdo:
    /backup_storage *(rw,async,no_root_squash) 
  2. Fixar as portas do NFS para não serem aleatórias e poderem ser tratadas pelo firewall. Alterar o arquivo /etc/sysconfig/nfs:
    LOCKD_TCPPORT=32803
    LOCKD_UDPPORT=32769
    MOUNTD_PORT=892
    RQUOTAD_PORT=875
    STATD_PORT=662
    STATD_OUTGOING_PORT=2020
    
  3. Inicializar os serviços na inicialização do sistema:
    # service portmap start
    # service nfs start
    # chkconfig portmap on
    # chkconfig nfs on
  4. Editar o arquivo /etc/rc.d/rc.sysinit e adicionar no final a seguinte linha:
    modprobe nfsd
  5. Listar as monstagens:
    # showmount -e localhost

    Se aparece a mensagem "RPC: Port mapper failure - RPC: Unable to receive" em vez do ponto de montagem editar o arquivo /etc/sysconfig/portmap conforme abaixo:

    PMAP_ARGS=""

Configurando o Firewall

  1. Adicionar as seguintes regras no arquivo /etc/sysconfig/iptables. Elas tem que ser inseridas após a regra "-A RH-Firewall-1-INPUT -p icmp --icmp-type any -j ACCEPT":
    -A RH-Firewall-1-INPUT -s 10.225.1.0/24 -m conntrack --ctstate NEW -p udp --dport 111 -j ACCEPT
    -A RH-Firewall-1-INPUT -s 10.225.1.0/24 -m conntrack --ctstate NEW -p tcp --dport 111 -j ACCEPT
    -A RH-Firewall-1-INPUT -s 10.225.1.0/24 -m conntrack --ctstate NEW -p tcp --dport 2049 -j ACCEPT
    -A RH-Firewall-1-INPUT -s 10.225.1.0/24 -m conntrack --ctstate NEW -p tcp --dport 32803 -j ACCEPT
    -A RH-Firewall-1-INPUT -s 10.225.1.0/24 -m conntrack --ctstate NEW -p udp --dport 32769 -j ACCEPT
    -A RH-Firewall-1-INPUT -s 10.225.1.0/24 -m conntrack --ctstate NEW -p tcp --dport 892 -j ACCEPT
    -A RH-Firewall-1-INPUT -s 10.225.1.0/24 -m conntrack --ctstate NEW -p udp --dport 892 -j ACCEPT
    -A RH-Firewall-1-INPUT -s 10.225.1.0/24 -m conntrack --ctstate NEW -p tcp --dport 875 -j ACCEPT
    -A RH-Firewall-1-INPUT -s 10.225.1.0/24 -m conntrack --ctstate NEW -p udp --dport 875 -j ACCEPT
    -A RH-Firewall-1-INPUT -s 10.225.1.0/24 -m conntrack --ctstate NEW -p tcp --dport 662 -j ACCEPT
    -A RH-Firewall-1-INPUT -s 10.225.1.0/24 -m conntrack --ctstate NEW -p udp --dport 662 -j ACCEPT
    
  2. Reiniciar o servidor para que o mesmo mude as portas do NFS, ative os serviçoes e o firewall

Restaurando Backups

  1. Colocar o volume online no storage
  2. No pool-master, montar a partição:
    # iscsiadm -m discovery -t st -p 192.168.0.100
    # iscsiadm -m node
    #  iscsiadm -m node --targetname "iqn.xxxxx" --portal "192.168.0.100:3260" --login
    # fdisk -l|grep Disk
    # mount /dev/sdx /mnt
  3. Entrar no diretório montado, e importar a VM com o seguinte comando:
    # xe vm-import filename="Nome do arquivo" sr-uuid="UUID do SR dos discos do pool"
  4. Após o término da cópia, desmontar o diretório e deslogar o iscsi:
    # umount /mnt
    # iscsiadm -m node --targetname "iqn.xxxxx" --portal "192.168.0.100:3260" --logout
  5. Terminado o processo, colocar o volume de backup offline de novo.

    Referências