Ao trabalhar com virtualizações conseguimos otimizar muitas tarefas, uma delas é o backup a quente de máquinas virtuais. Este tipo de backup, significa que podemos realizar uma cópia de segurança de uma ou várias virtualizações sem a necessidade de desliga-la. Neste artigo será demonstrado como realizar o backup a quente de múltiplas virtualizações no Xen Server 7, através de um script de backup otimizado.
CONSIDERAÇÕES
Estamos considerando que você já possua um servidor hospedeiro Xen Server instalado e em funcionamento. Também iremos considerá que já possua entendimento básico da ferramenta e noções avançadas de Linux. A versão utilizada no servidor hospedeiro é o XenServer 7.0, a mais atual no momento da elaboração deste artigo. Também disponibilizei um artigo referente a backups de vms de forma individual, caso tenha interesse acesse: “Script de Backup a quente VM’s XenServer 6.5, 7.x“
PEGA A VISÃO
Se você conhece pouco de Xen Server e necessita aprofundar-se no assunto, que tal aceitar minha dica? Assista a aula de apresentação.
Agora se seu foco e ir além do Xen Server, então você precisará conhecer o Xen Desktop. Assista a aula de apresentação.
Mas se seu foco é migração de Hypervisor, também tenho uma indicação especial para você. Já ouviu falar do Proxmox? Assista a aula de apresentação.
1) COLHENDO INFORMAÇÕES PERTINENTES
Para que possamos criar nosso script, antes precisamos colher uma informação de nosso Xen Server a ser backupeado. Para isso, utilize a ferramenta XenCenter, selecione seu servidor, e na aba console, acesse o shell conforme ilustrado abaixo.
Nota: Também é possível realizar o acesso ao console do servidor utilizando o protocolo SSH. Utilize uma ferramenta de acesso para isto, por exemplo o putty.
A informação que precisamos obter é o “Storage-Repository-UUID” de nosso servidor. Para isso, utilize o comando conforme ilustrado abaixo no console do Xen Server.
xe sr-list
Após executar o comando, teremos em mãos a informação necessária para criar um novo arquivo de script capaz de realizar backups de VM’s “a quente”, totalmente automatizado. Crie um arquivo chamado “bkpvms.sh” em “/etc/init.d/” ou onde preferir e adicione o código ilustrado abaixo.
Nota: O nome e local foi definido neste artigo para fins didáticos, eles podem ser definidos de acordo com suas necessidades. A alteração não afeta o funcionamento do script.
#!/bin/bash # Script de backup das VM's Xen-Server (VM's a QUENTE) #################################################################################### # Criado por: Rafael Oliveira # # Fone:(27) 99981-4409 # # e-mail: faelolivei@gmail.com # #################################################################################### # Variaveis ######################################################################## storagebkp="9aee4ad3-9db2-315b-1bc6-401fea6ba74a" # Seu Storage. dataarq=`date +%d-%m-%Y` # data para numenclatura do arquivo de log. datain2=`date +%s` # data usada para subtracao de tempo final da execução do script bkpdestino=/mnt/backup/bkpvms # Caminho para armazenamento do backup # Cria o diretorio que armazena o log caso não exista ############################## if test -d /var/log/backup/vms; then echo ""; else mkdir -p /var/log/backup/vms; fi; # Definicao de array ############################################################### echo "==============================================================================" > /var/log/backup/vms/bkpvms-${dataarq}.log arrayvms=(Ubuntu1 Ubuntu2 WinServer2008R2) echo "Servidores a serem backupeados: ${arrayvms[*]}." >> /var/log/backup/vms/bkpvms-${dataarq}.log # For de backup #################################################################### for vmname in ${arrayvms[*]} do { dhvm=`date +%d-%m-%Y_%H-%M-%S` # data completa de informacao de cada etapa. datain=`date +%s` # data usada para subtracao de tempo de cada vm. sleep 60 # Aguarda 1 minuto antes de iniciar o bkp. echo "==============================================================================" >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "Iniciando backup da vm ${vmname} em ${dhvm}" >> /var/log/backup/vms/bkpvms-${dataarq}.log data=`date +%c` # Data e hora atual. echo "1) Cria snapshot da maquina em ${data}." >> /var/log/backup/vms/bkpvms-${dataarq}.log idvm=`xe vm-snapshot vm=${vmname} new-name-label=${vmname}_snapshot` &> /var/log/backup/vms/bkpvms-${dataarq}.log if [ $? -eq 0 ]; then { echo "Id Snapshot criado: ${idvm}" >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "Executou com sucesso." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "------------------------------------------------------------------------------" >> /var/log/backup/vms/bkpvms-${dataarq}.log } else { echo "Problemas na execução, verifique o arquivo de log." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "==============================================================================" >> /var/log/backup/vms/bkpvms-${dataarq}.log exit 1 } fi; data=`date +%c` # Data e hora atual. echo "2)Convertendo o snapshot criado em template em ${data}." >> /var/log/backup/vms/bkpvms-${dataarq}.log xe template-param-set is-a-template=false uuid=${idvm} &> /var/log/backup/vms/bkpvms-${dataarq}.log if [ $? -eq 0 ]; then { echo "Executou com sucesso." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "------------------------------------------------------------------------------" >> /var/log/backup/vms/bkpvms-${dataarq}.log } else { echo "Problemas na execução, verifique o arquivo de log." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "==============================================================================" >> /var/log/backup/vms/bkpvms-${dataarq}.log exit 1 } fi; data=`date +%c` # Data e hora atual. echo "3)Convertendo o template em VM em ${data}" >> /var/log/backup/vms/bkpvms-${dataarq}.log cvvm=`xe vm-copy vm=${vmname}_snapshot sr-uuid=${storagebkp} new-name-label=${vmname}_${dhvm}` &> /var/log/backup/vms/bkpvms-${dataarq}.log if [ $? -eq 0 ]; then { echo "Executou com sucesso." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "------------------------------------------------------------------------------" >> /var/log/backup/vms/bkpvms-${dataarq}.log } else { echo "Problemas na execução, verifique o arquivo de log." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "==============================================================================" >> /var/log/backup/vms/bkpvms-${dataarq}.log exit 1 } fi; data=`date +%c` # Data e hora atual. echo "4)Exportando VM criada para o HD externo em ${data}." >> /var/log/backup/vms/bkpvms-${dataarq}.log if test -d ${bkpdestino}/${vmname}; then { # Se existir o diretorio xe vm-export vm=${cvvm} filename="${bkpdestino}/${vmname}/${vmname}_${dhvm}.xva" &> /var/log/backup/vms/bkpvms-${dataarq}.log } else { # Se não existir o diretorio, cria um. mkdir -p ${bkpdestino}/${vmname} echo "Criando diretorio ${bkpdestino}/${vmname}" xe vm-export vm=${cvvm} filename="${bkpdestino}/${vmname}/${vmname}_${dhvm}.xva" &> /var/log/backup/vms/bkpvms-${dataarq}.log } fi; if [ $? -eq 0 ]; then { echo "Executou com sucesso." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "------------------------------------------------------------------------------" >> /var/log/backup/vms/bkpvms-${dataarq}.log } else { echo "Problemas na execução, verifique o arquivo de log." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "==============================================================================" >> /var/log/backup/vms/bkpvms-${dataarq}.log exit 1 } fi; data=`date +%c` # Data e hora atual. echo "5)Deletando VM e seu VDI criado em ${data}." >> /var/log/backup/vms/bkpvms-${dataarq}.log xe vm-uninstall vm=${cvvm} force=true &> /var/log/backup/vms/bkpvms-${dataarq}.log if [ $? -eq 0 ]; then { echo "Executou com sucesso." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "------------------------------------------------------------------------------" >> /var/log/backup/vms/bkpvms-${dataarq}.log } else { echo "Problemas na execução, verifique o arquivo de log." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "==============================================================================" >> /var/log/backup/vms/bkpvms-${dataarq}.log exit 1 } fi; data=`date +%c` # Data e hora atual. echo "6)Deletando Snapshot criado em ${data}." >> /var/log/backup/vms/bkpvms-${dataarq}.log xe vm-uninstall --force uuid=${idvm} &> /var/log/backup/vms/bkpvms-${dataarq}.log if [ $? -eq 0 ]; then { echo "Executou com sucesso." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "------------------------------------------------------------------------------" >> /var/log/backup/vms/bkpvms-${dataarq}.log } else { echo "Problemas na execução, verifique o arquivo de log." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "==============================================================================" >> /var/log/backup/vms/bkpvms-${dataarq}.log exit 1 } fi; data=`date +%c` # Data e hora atual. echo "7)Excluindo backups duplicados em ${data}" >> /var/log/backup/vms/bkpvms-${dataarq}.log ls -td1 ${bkpdestino}/${vmname}/* | sed -e '1,2d' | xargs -d '\n' rm -rif &> /var/log/backup/vms/bkpvms-${dataarq}.log if [ $? -eq 0 ]; then { echo "Executou com sucesso." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "------------------------------------------------------------------------------" >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "Backup VM ${vmname} concluido em ${data}." >> /var/log/backup/vms/bkpvms-${dataarq}.log } else { echo "Problemas na execução, verifique o arquivo de log." >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "==============================================================================" >> /var/log/backup/vms/bkpvms-${dataarq}.log exit 1 } fi; dataoud=`date +%s` #data final de execução seg=$((${dataoud} - ${datain})) min=$((${seg}/60)) seg=$((${seg}-${min}*60)) hor=$((${min}/60)) min=$((${min}-${hor}*60)) echo "Tempo estimado: ${hor}:${min}:${seg}" >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "==============================================================================" >> /var/log/backup/vms/bkpvms-${dataarq}.log } done; dataoud=`date +%s` #data final de execução seg=$((${dataoud} - ${datain2})) min=$((${seg}/60)) seg=$((${seg}-${min}*60)) hor=$((${min}/60)) min=$((${min}-${hor}*60)) echo "Tempo Total Estimado: ${hor}:${min}:${seg}" >> /var/log/backup/vms/bkpvms-${dataarq}.log echo "==============================================================================" >> /var/log/backup/vms/bkpvms-${dataarq}.log exit 0
Você também pode baixar o código:
Link: Script
Chave: !SZthjRhOxWw0QRzE9rFibaewKBTQR3ySbNPdBxqNYFg
2) CONFIGURAÇÃO DO SCRIPT
Pensando em facilitar a utilização deste script em diversos ambientes, foi definido algumas variáveis de inicialização que devem ser alteradas de acordo com o ambiente proposto. Estas variáveis encontram-se no inicio do script à saber:
arrayvms – Array que armazena o nome das vm’s que serão backapeadas.
storagebkp – Responsável por armazenar o UUID do Storage que consta as VM’s a serem backapeadas.
bkpdestino – Caminho no qual irá armazenar o backup da máquina virtual. Pode ser um HD Externo, ambiente de rede ou qualquer outro tipo de armazenamento que preferir. Basta estar montado corretamente no XenServer.
Realize as alterações conforme seu ambiente, salve o arquivo, de permissão de execução para o mesmo, e execute o backup.
Nota: Uma forma inteligente de realizar o backup e acompanhar seus logs é executa-lo em segundo plano, para isso realize a execução do script conforme ilustrado abaixo.
/etc/init.d/bkpvms.sh &
Em seguida acesse o arquivo de log utilizando o comando “tail -f” para visualizar em tempo real o registro de logs do script, conforme também ilustrado abaixo.
tail -f /var/log/backup/vms/bkpvms-dd-mm-yyyy.log
3) AGENDANDO SCRIPT
Podemos utilizar o agendador “CRONTAB” para agendarmos nosso script. Para isso, edite o arquivo “/etc/crontab” com o editor de texto de sua preferência, e adicionar o agendamento desejado conforme ilustrado abaixo.
SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root # For details see man 4 crontabs # Example of job definition: # .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr ... # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * user-name command to be executed 48 14 * * * root sh /etc/init.d/bkpvms.sh
4) EXPLICAÇÃO DO SCRIPT
O script está dividido em 7 (sete) etapas, estas etapas foram definidas para melhor entendimento de todo o processo. O próprio script já é auto explicativo, porém, vou definir em poucas palavras o funcionamento do mesmo.
I) Cria snapshot da máquina definida pela variável de inicialização “VMNAME” baseada na array “ARRAYNAME” e adiciona a informação ao log. Se o comando foi bem sucedido passa para próxima etapa, caso contrário pula para a próxima VM a ser backupeada.
II) Converte o snapshot criado em template e adiciona a informação ao log. Se o comando foi bem sucedido passa para próxima etapa,caso contrário pula para a proxima VM a ser backupeada.
III) Converte o template em VM e adiciona a informação ao log. Se o comando foi bem sucedido passa para próxima etapa, caso contrário pula para a próxima VM a ser backupeada.
IV) Exporta a VM criada para o HD externo e adiciona a informação ao log. Se o comando foi bem sucedido passa para próxima etapa, caso contrário pula para a próxima VM a ser backupeada.
V) Deleta a VM e seu VDI criado e adiciona a informação ao log. Se o comando foi bem sucedido passa para próxima etapa, caso contrário pula para a próxima VM a ser backupeada.
VI) Deleta o snapshot criado e adiciona a informação ao log. Se o comando foi bem sucedido passa para próxima etapa, caso contrário pula para a próxima VM a ser backupeada.
VII) Exclui os backups duplicados mais antigos, mantendo somente duas cópias da VM no diretório definido e adiciona a informação ao log. Se o comando foi bem sucedido finaliza o script registrando o tempo de duração do backup, caso contrário pula para a próxima VM a ser backupeada.
CONCLUSÃO
Através deste artigo conseguimos expor de maneira simples uma solução personalizada para realizar backups “a quente” de múltiplas máquinas virtuais no Xen Server.
Se você gostou deste post e através dele pude lhe ajudar, o que acha de aproximarmos nosso contato? Siga meu blog e me adicione no Linkedin, aproveite para classificar algumas das minhas competências/recomendações, este simples gesto faz toda a diferença.
Até a próxima!
Rafael Oliveira
SysAdmin
49 respostas
Recebo erro Error: Multiple matches VMs found. Operation can only be performed on one VM at a time
boa tarde , estou traballhando em cima do seu script para realizar o bkp , só que meu Xenserver não possui espaço suficiente para armazenar os arquivos, então adatptei o seu scripit ,antes de executar o scripit de bkp executei esse:
mount -t cifs -o “username=domain\adm.gillen,password=XXXXX” “//192.168.1.5/backup_diario/XENSERVER” /mnt/backup/bkpvms
aonde montei a pasta compartilhada do windows para que ele possa salvar direto nessa pasta.
com isso me apresenta um erro
There was an SR backend failure.
status: non-zero exit
stdout:
stderr: Traceback (most recent call last):
File “/opt/xensource/sm/LVMSR”, line 2130, in ?
SRCommand.run(LVHDSR, DRIVER_INFO)
File “/opt/xensource/sm/SRCommand.py”, line 345, in run
ret = cmd.run(sr)
File “/opt/xensource/sm/SRCommand.py”, line 110, in run
return self._run_locked(sr)
File “/opt/xensource/sm/SRCommand.py”, line 159, in _run_locked
rv = self._run(sr, target)
File “/opt/xensource/sm/SRCommand.py”, line 249, in _run
return target.snapshot(self.params[‘sr_uuid’], self.vdi_uuid)
File “/opt/xensource/sm/LVMSR”, line 1553, in snapshot
return self._do_snapshot(sr_uuid, vdi_uuid, snapType, secondary=secondary)
File “/opt/xensource/sm/LVMSR”, line 1631, in _do_snapshot
raise e1
IndexError: list index out of range
[1]+ Exit 1 /etc/init.d/bkpvms.sh
Bom dia Gillen, realmente para utilizar esse script vc precisa ter um espaço no próprio storage onde encontra-se a VM. Abr.
Rafael, agradeço muito por ter dedicado seu tempo e ter compartilhado conosco este script muito bem elaborado e de fácil compreensão. Excelente trabalho! Parabéns
Vlw Marcos, que bom que pude ser útil, precisando estamos a disposição, Abr. 🙂
te enviei um mail da uma olhada
Blz
a vm ta instalada no servidor coloquei o id do hd onde esta esta instalado certo ?
Vc precisa informar o uuid do storage e o nome da VM, conforme explicado no artigo.
obrigado pela ajuda, e o ajuste no script para rodar em versão 6.5
Eu que agradeço Diogo, que bom que pude contribuir com algo, precisando estamos a disposição. Abr.
sim
Estranho, utilizo esse script para bkp aqui diariamente, vou verificar.
tem algo estranho mesmo erro
[root@xenserver-r710 ~]# ./scriptvms-mult.sh
./scriptvms-mult.sh: line 34: syntax error near unexpected token `>’
./scriptvms-mult.sh: line 34: ` idvm=`xe vm-snapshot vm=${vmname} new-name-label=${vmname}_snapshot` &>> /var/log/backup/vms/bkpvms-${dataarq}.log’
Você esta setando no script o seu Storage e o nome de suas VMs?
te dando trabalho a chave nao ta indo 🙂
Rs, É porque estamos fazendo em tempo real, to corrigindo e você baixando. Mas já corrigi a chave, testa agora. Abr.
aqui é em tempo real hahahaha valeu consegui vou testar obrigado pela paciência
.
mesma coisa
/bkp-VM: line 33: syntax error near unexpected token `>’
./bkp-VM: line 33: `idvm=`xe vm-snapshot vm=${vmname} new-name-label=${vmname}_snapshot` &>> /var/log/backup/vms/bkpvms-${dataarq}.log’
Realizei o teste aqui e esta normal. Irei disponibilizar o arquivo para download no post.
obrigado
estou tentando este erro
./backupvm.sh: line 46: syntax error near unexpected token `>’
./backupvm.sh: line 46: ` xe template-param-set is-a-template=false uuid=${idvm} &>> /var/log/backup/vms/bkpvms-${dataarq}.log’
Bom dia Diogo! Obrigado pela contribuição!
Na verdade o erro esta na sintaxe do WordPress que alterou os caracteres do Script, pode testar novamente. Abr.
pode enviar para o meu e-mail o script ?
O intuito é disponibilizar pelo blog, realize o teste, o intuito é fornecer um conteúdo de script correto para todos.
mas vc fez alguma alteração ? no scritp acima ?
Sim, o script que você copiou pela primeira vez estava com caracteres especiais no qual o WordPress tinha alterado. Copie o código novamente e teste. Também estarei corrigindo o código do outro Script.