怎样在 Linux 中导出和导入 KVM 虚拟机

在本文中,我将引导您完成导出 KVM 虚拟机磁盘和配置的步骤,然后将它们导入同一台机器或不同的机器。 我还将向您展示怎样使用 Bash 脚本导出和导入 KVM 虚拟机。

介绍

最近我把我的管理程序从 甲骨文 VirtualBox虚拟机 因为它的原生特性和性能。 据我测试,与 Virtualbox VM 相比,KVM 虚拟机运行得更快。

定期备份您的虚拟机总是很重要的。 因此,如果出现任何差异,您可以使用备份映像来恢复虚拟机。 导出和导入 KVM 虚拟机是一个两步过程。

  • 首先,您必须检查磁盘映像的存储位置并将磁盘映像复制到备份位置。
  • 其次,导出机器配置,以便以后用于创建域。

虚拟机定义

有两种方法可以获取虚拟机域信息。 要么你可以使用 “维尔什” 程序或使用 “虚拟经理”.

您可以从 Virt-manager 或运行以下命令获取 VM 的名称 virsh 命令。

$ virsh list --all
 Id   Name                State
------------------------------------
 -    Linux_Mint_20       shut off
 -    mxlinux             shut off
 -    popos_21_10         shut off
 -    rocky_linux_8       shut off
 -    ubuntu20.04         shut off
 -    ubuntu20.04-clone   shut off

您可以运行以下命令来查看有关特定虚拟机的整个域信息(VM 配置)。 这将以 XML 格式显示结果。

$ virsh dumpxml vm_name | less
$ virsh dumpxml ubuntu20.04-clone | less

您还可以通过管道将特定的机器配置连接到 grep 命令。 假设您想查看内存分配,那么您可以运行以下命令。

$ virsh dumpxml ubuntu20.04-clone | grep -i "MEMORY"
  <memory unit="KiB">5632000</memory>
  <currentMemory unit="KiB">5632000</currentMemory>

如果您更喜欢 Virt-manager,那么您可以通过按 XML 选项卡 在“显示虚拟硬件”部分下。

在 Virt Manager 中显示域信息

虚拟机磁盘位置

虚拟机的磁盘是在 qcow2 格式。 默认情况下,虚拟机磁盘存储在 /var/lib/libvirt/images/ 目录,除非您将磁盘显式存储在单独的目录中。

运行以下命令获取磁盘目录路径。

$ virsh dumpxml ubuntu20.04-clone | grep -i "source"
      <source file="/var/lib/libvirt/images/ubuntu20.04-clone.qcow2"/>

来自 Virt-manager,在 概述 部分,检查 <disk> 部分。

磁盘位置

如果您使用不同的路径来存储磁盘映像并且希望了解所有 VM 磁盘路径,则可以从终端或 shell 脚本运行以下代码段。

VM_NAMES=($(virsh list --all| awk '(NR>2)' | awk '{ print $2 }'))

for VM in ${VM_NAMES[@]}; do
  DISK_PATH=$(virsh dumpxml ${VM} | grep -i "<source file")
  echo "${VM} ${DISK_PATH}"
done | column -t 
使用脚本显示 VM 磁盘路径 使用脚本显示 VM 磁盘路径

导出域信息并复制磁盘

现在您知道怎样获取磁盘路径和域信息,是时候导出 VM 的域信息并将磁盘映像复制到其他位置了。

要导出域信息,您可以运行以下命令“virsh dumpxml“并将输出存储在 XML 文件。

$ virsh dumpxml vm-name > /path/to/xm_file.xml
$ virsh dumpxml ubuntu20.04-clone > ~/Documents/ubuntu.xml

现在将磁盘映像复制到其他位置,以便以后使用。

$ sudo cp /var/lib/libvirt/images/ubuntu20.04-clone.qcow2 ~/Documents/

导出过程完成。 就是这么简单!

小心: 你应该使用 sudo 或复制磁盘 root 用户,因为磁盘归 root 用户所有。

显示所有者信息 显示所有者信息

导入 KVM 虚拟机

要导入 KVM 虚拟机,您必须通过运行以下命令从导出的 XML 文件中定义域。

$ virsh define --file <path-to-xml-file>
$ virsh define –file ~/Documents/ubuntu.xml

现在您可以检查 Virt-manager 或运行 virsh 命令,应该成功创建域。 您必须将磁盘映像复制到 XML 文件中定义的目录路径。 在我的情况下,它是默认位置 /var/lib/libvirt/images/.

$ sudo cp ~/Documents/ubuntu20.04-clone.qcow2 /var/lib/libvirt/images/

导入过程完成。 现在您可以启动虚拟机了。

用于导出和导入 KVM 虚拟机的 Bash 脚本

我创建了一个 bash 负责导出所有配置和磁盘映像的脚本。 如果你有兴趣,你可以看看我的这个脚本 GitHub存储库. 您对改进此脚本的建议将不胜感激。

#!/usr/bin/env bash

# ----------------------------------------------------------------------------------------------------
# AUTHOR   : KARTHICK S
# PURPOSE  : THIS SCRIPT WILL EXPORT/IMPORT THE CONFIG AND VM DISK. 
#
# usage: 
# export function will take care of exporting the necessary for all VM. Run as "<scriptname.sh> export"
# import function will take care of importing the necessary for all VM. Run as "<scriptname.sh> import"
#
# NOTE: Do not add trailing / for the directory when giving export and import path.
#------------------------------------------------------------------------------------------------------

# Trigger the script with root user or exit.
if [[ ${UID} -ne 0 ]]; then
  echo -e "[EXIT] - Run the script as root user or with sudo privilege..."
  exit
fi

function export_vm(){
  
  # Get the export location.
  read -p "Provide the directory path where disk and config files to be exported: " EXPORT_LOCATION

  # Create the destination directory if not exists.
  [[ -d ${EXPORT_LOCATION} ]] || mkdir -p ${EXPORT_LOCATION}

  # Exporting the config using virsh dumpxml command.
  VM_NAMES=($(virsh list --all| awk '(NR>2)' | awk '{ print $2 }'))
  for VM in ${VM_NAMES[@]}; do
    virsh dumpxml ${VM} > ${EXPORT_LOCATION}/${VM}.xml
  done

  # Using rsync copy the entire directory from default location.
  echo -e "n[ Copying disk images ]n" && sudo rsync -avxp --progress /var/lib/libvirt/images ${EXPORT_LOCATION}

  echo -e "n[ Exported Files ] n" && ls -lR ${EXPORT_LOCATION}

} 

function import_vm(){

  # Get the source location.
  read -p "Provide the directory path where disk and config files are stored: " SOURCE_LOCATION

  # Throws error if directory is not available and exit.
  [[ -d ${SOURCE_LOCATION} ]] || { echo "Directory not available"; exit 1 ; }

  # Copy all the files to default disk location.
  echo -e "[ Copying disk images ]n" && sudo rsync -avxp --progress ${SOURCE_LOCATION}/images /var/lib/libvirt/

  if [[ $? -eq 0 ]]; then
    # Define VM
    echo -e "n[ Defining VM ]n"
    for XML_FILE in ${SOURCE_LOCATION}/*.xml; do
      virsh define --file ${XML_FILE} 
    done
    echo -e "n[ Imported VM List ]n" && virsh list --all
  fi

}

case $1 in
 export ) export_vm ;;
 import ) import_vm ;;
 *) echo -e "USAGE : 
kvm_export_import.sh export - Export config and disk
kvm_export_import.sh import - Define VM and copy the disk"; exit 
esac

该脚本的用法如下。

您可以运行以下命令从 GitHub 克隆 gist。

$ git clone https://gist.github.com/d6c671597592fe5634a39b7974bc8029.git

该脚本执行备份(即导出)和恢复(即恢复)。

让我们使用如下脚本导出 KVM 虚拟机。

$ sudo bash kvm_export_import.sh export

您必须提供要复制/导出 XML 文件和磁盘映像的目录路径。 不要添加尾随 / 削减 给出导出目录时。 它将首先复制磁盘映像(.qcow2) 并运行”virsh dumpxml” 命令导出所有配置。

下图显示了导出的工作原理。

使用 Bash 脚本导出 KVM 虚拟机 使用 Bash 脚本导出 KVM 虚拟机

当你通过“import” 作为参数,它将首先将磁盘映像复制到默认位置 /var/lib/libvirt/ 并运行“virsh define” 针对所有导出 XML 文件的命令。

$ sudo bash kvm_export_import.sh import
使用 Bash 脚本导入 KVM 虚拟机 使用 Bash 脚本导入 KVM 虚拟机

结论

在本文中,我向您展示了怎样导出 KVM 虚拟机并将它们导入相同或不同的机器。 从头开始构建虚拟机是一项耗时的任务。 因此,要遵循适当的策略来保护图像不会因任何情况而丢失。 如果您对本文有任何技巧或提示,我们很乐意听取您的意见。

希望这可以帮助。