将 kvm/qemu VM 克隆到不同的服务器

将 kvm/qemu VM 克隆到不同的服务器

如果两台服务器之间没有共享存储(因此无法进行标准迁移),那么将虚拟机从一台服务器克隆到另一台服务器的最简单/最快的方法是什么?

我在一台服务器上安装了一台可用于生产的虚拟机,我想将其克隆到另一台系统上。两台主机之间没有共享存储,但我已在两台主机之间复制了磁盘映像并为其添加了配置(virsh 已定义)。但是,当我尝试启动它时,它没有执行:

# 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

我在 RHEL6 上使用 KVM。以下是重复的配置

<!--
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>

答案1

以下是我所做的操作,其中 $VM 是 VM 名称,DEST 是目标虚拟机管理程序主机名。它在使用 dd 和快照 LVM 磁盘的运行 VM 上执行此操作(假设 LVM 组称为 HypGroup00)。

我只是把它们放在一起,所以它不一定是最漂亮的,但可以完成工作,我正在用它将一些虚拟机从 CentOS 5.9 虚拟机管理程序迁移到 CentOS 6,同时最大限度地减少停机时间。

这是针对 CentOS 5.9 的,已针对 CentOS 5 和 6 作为目标进行了测试。

VM=webserver
DEST=hyp5

确定要复制哪些磁盘,因为我们的大多数 VM 磁盘都是通过 /dev/mapper/ 路径而不是 /dev/volgroup/volname 路径引用的。所以我们需要在两者之间进行转换。

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

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

复制虚拟机定义并注册

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

现在在远程服务器上创建 LV

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

现在创建快照 LV 并开始复制数据

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

复制磁盘

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

上述内容的更复杂版本在需要时从 dd 显示进度,由于 /tmp/pid,不适合多个副本,但如果您愿意,可以更改为包含 $$。

(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

清理

for lv in $LVS; do
  lvremove --force $lv-snapshot
done

答案2

好吧,我这样做确实很好。问题是我没有足够的资源来运行该虚拟机。所以只是为了回答我自己的问题...以下是我如何在没有共享磁盘的情况下跨不同服务器进行虚拟机复制的详细信息。

由于您没有共享磁盘,因此您无法执行典型的“克隆”然后“迁移”。相反,您可以执行典型的克隆

  1. 这是执行克隆的命令(/本地/虚拟机/是虚拟机映像的路径,通常/var/某物/):

    virt-clone --original=要克隆的虚拟机 --name=cloned-vm -f /local/vm/cloned-vm.img --mac=xx:xx:xx:xx:xx:xx

  2. 现在将该 img 文件从一台服务器复制到另一台服务器...我的服务器无法直接相互通信,因此我使用这个小型 SSH 重定向来完成此操作:

    ssh -n 服务器1'(cd /local/vm/; cat cloned-vm.img)' | ssh 服务器2'(cd /local/vm/; cat > cloned-vm.img)'

  3. 然后复制该虚拟机的配置:

    ssh -n 服务器1'(cd /etc/libvirt/qemu/; cat cloned-vm.xml)' | ssh 服务器2'(cd /etc/libvirt/qemu/; cat > cloned-vm.xml)'

  4. 更新配置以适应任何新的更改。就我的情况而言(这也是导致我出现问题的原因),我需要降低“memory”和“currentMemory”属性。

  5. 将新的 VM 添加到 libvirt:

    virsh 定义 /etc/libvirt/qemu/cloned-vm.xml

  6. 运行:

    virsh 创建 /etc/libvirt/qemu/cloned-vm.xml

相关内容