Clone kvm / qemu VM para um servidor diferente

6

Qual é a maneira mais fácil / rápida de clonar uma VM de um servidor para outro se você não tiver armazenamento compartilhado entre os dois servidores (para que não seja possível fazer uma migração padrão)?

Eu tenho uma VM pronta para produção instalada em um servidor e quero cloná-la em outro sistema. Eu não tenho armazenamento compartilhado entre os dois hosts, mas copiei a imagem do disco entre os dois hosts e adicionei uma configuração para ele (virsh definiu). Quando tento iniciá-lo, não é necessário:

# virsh create /etc/libvirt/qemu/cloned-vm.xml 
error: Failed to create domain from /etc/libvirt/qemu/cloned-vm.xml
error: Unable to read from monitor: Connection reset by peer

Estou usando o KVM no RHEL6. Aqui está a configuração duplicada

<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE 
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
  virsh edit 
or other application using the libvirt API.
-->

<domain type='kvm'>
  <name>cloned-vm</name>
  <uuid>NEW_UUID_HERE</uuid>
  <memory>15360000</memory>
  <currentMemory>15360000</currentMemory>
  <vcpu>7</vcpu>
  <os>
    <type arch='x86_64' machine='rhel6.2.0'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw' cache='none'/>
      <source file='/local/vm/cloned-vm.img'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </disk>
    <interface type='bridge'>
      <mac address='NE:W_:MA:C_:AD:DR'/>
      <source bridge='br2'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <input type='tablet' bus='usb'/>
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='-1' autoport='yes'/>
    <video>
      <model type='cirrus' vram='9216' heads='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </memballoon>
  </devices>
</domain>
    
por Andrew Case 18.06.2012 / 18:28

2 respostas

4

Ok, então a maneira que eu estava fazendo realmente funcionou muito bem. O problema é que eu não tinha recursos suficientes para executar essa VM. Então, só para responder a minha própria pergunta ... aqui estão os detalhes de como eu fiz a duplicação de VM em diferentes servidores sem disco compartilhado.

Como você não tem um disco compartilhado, não é possível fazer um 'clone' típico e, em seguida, 'migração'. Em vez disso, você faz um clone típico

  1. Aqui está o comando para fazer a clonagem ( / local / vm / é o caminho para suas imagens de VM, geralmente / var / something / ):

    virt-clone --original = vm-para-clone --name = clonado-vm -f /local/vm/cloned-vm.img --mac = xx: xx: xx: xx: xx: xx

  2. Agora copie esse arquivo img de um servidor para o outro ... meus servidores não podem falar diretamente um com o outro, então eu uso esse pequeno redirecionamento de SSH para fazer o truque:

    ssh -n server1 '(cd / local / vm /; cat clonado-vm.img)' | ssh server2 '(cd / local / vm /; cat > clonado-vm.img)'

  3. Copie a configuração dessa VM:

    ssh -n server1 '(cd / etc / libvirt / qemu /; cat clonado-vm.xml)' | ssh server2 '(cd / etc / libvirt / qemu /; cat > clonado-vm.xml)'

  4. Atualize a configuração com novas alterações. No meu caso (e isso foi o que estava causando o meu problema), eu precisava abaixar os atributos "memory" e "currentMemory".

  5. Adicione a nova VM ao libvirt:

    virsh define o /etc/libvirt/qemu/cloned-vm.xml

  6. Execute:

    virsh create /etc/libvirt/qemu/cloned-vm.xml

por 18.06.2012 / 19:43
5

E aqui está o que eu faço, onde $ VM é o nome da VM e DEST é o nome do host do hypervisor de destino. Ele faz isso em VMs em execução usando discos LVM dd e snapshots (está assumindo que o grupo LVM é chamado HypGroup00).

Eu só joguei isso junto, então não é necessariamente o mais bonito, mas funciona, eu estou usando para migrar algumas VMs de um hypervisor do CentOS 5.9 para o CentOS 6 com o mínimo de tempo de inatividade.

Isto é para o CentOS 5.9, testado em ir ao CentOS 5 e 6 como um destino.

VM=webserver
DEST=hyp5

Descobrir quais discos copiar, pois a maioria dos nossos discos VM são referenciados por meio do caminho / dev / mapper /, em vez do caminho / dev / volgroup / volname. Então, precisamos traduzir entre os dois.

DISKS='cat /etc/libvirt/qemu/$VM.xml |  grep HypGroup00 | sed "s|.*/\(HypGroup00-.*\)'/>||"'

LVS=""

for disk in $DISKS; do
  echo VM Disk $disk
  LV='lvdisplay /dev/mapper/$disk | grep "LV Name" | awk '{print $3}''
  LVS="$LVS $LV"
done

Copie a definição da VM e registre-a

virsh dumpxml $VM > /tmp/$VM.xml
scp /tmp/$VM.xml $DEST:/tmp/
ssh $DEST virsh undefine $VM > /dev/null 2>&1
ssh $DEST virsh define /tmp/$VM.xml

Agora crie o LV no servidor remoto

for lv in $LVS; do
  ssh $DEST lvremove --force $lv
  SIZE='lvdisplay $lv | grep "LV Size" | awk '{print $3}''
  SHORTNAME='basename $lv'
  ssh $DEST lvcreate -L"$SIZE"G -n$SHORTNAME HypGroup00
done

Agora crie os LVs de snapshot e comece a copiar os dados

virsh suspend $VM
for lv in $LVS; do
  lvcreate -L10G -s -n $lv-snapshot $lv
done
virsh resume $VM

Copie os discos em

for lv in $LVS; do
  echo Copying LV $lv, this will take a while...
  time dd bs=1M if=$lv-snapshot | gzip --fast | ssh $DEST "gzip -d | dd of=$lv"
done

Uma versão mais complexa do que foi mostrado acima, que mostra o progresso, se necessário, do dd, não é bom para várias cópias devido a / tmp / pid, mas você pode alterar para incluir $$, se desejar.

(dd bs=1M if=$lv-snapshot & echo $! >&3 ) 3>/tmp/pid  2> >(grep 'copied' 1>&2) | ssh $DEST "dd bs=1M of=$lv" &
# Need this sleep to give the above time to run
sleep 1
PID=$(</tmp/pid)

while kill -0 $PID; do
  kill -USR1 $PID
  sleep 5
done

Limpar

for lv in $LVS; do
  lvremove --force $lv-snapshot
done
    
por 30.07.2013 / 08:16