如何使用 virsh 命令创建、还原和删除 KVM 虚拟机快照
在虚拟化平台上进行系统管理工作时，经常需要在开始重大操作比如部署补丁和代码前先设置一个虚拟机 快照 snapshot 。虚拟机快照是特定时间点的虚拟机磁盘的副本。换句话说，快照保存了给定的时间点虚拟机的状态和数据。我们可以在哪里使用虚拟机快照？如果你在使用基于 KVM 的 虚拟机管理程序 （ hypervisor ） ，那么可以使用 virsh 命令获取虚拟机或域快照。快照在一种情况下变得非常有用，当你已经在虚拟机上安装或应用了最新的补丁，但是由于某些原因，虚拟机上的程序变得不稳定，开发团队想要还原所有的更改和补丁。如果你在应用补丁之前设置了虚拟机的快照，那么可以使用快照将虚拟机恢复到之前的状态。注意：我们只能对磁盘格式为 Qcow2 的虚拟机的进行快照，并且 kvm 的 virsh 命令不支持 raw 磁盘格式，请使用以下命令将原始磁盘格式转换为 qcow2。# qemu-img convert -f raw -O qcow2 image-name.img image-name.qcow2 创建 KVM 虚拟机（域）快照我假设 KVM 管理程序已经在 CentOS 7 / RHEL 7 机器上配置好了，并且有虚拟机正在运行。我们可以使用下面的 virsh 命令列出虚拟机管理程序中的所有虚拟机，[root@kvm-hypervisor ~]# virsh list --all Id Name State ---------------------------------------------------- 94 centos7.0 running 101 overcloud-controller running 102 overcloud-compute2 running 103 overcloud-compute1 running 114 webserver running 115 Test-MTN running 假设我们想创建 webserver 虚拟机的快照，运行下面的命令，语法：# virsh snapshot-create-as –domain {vm_name} –name {snapshot_name} –description “enter description here” [root@kvm-hypervisor ~]# virsh snapshot-create-as --domain webserver --name webserver_snap --description "snap before patch on 4Feb2018" Domain snapshot webserver_snap created 创建快照后，我们可以使用下面的命令列出与虚拟机相关的快照：[root@kvm-hypervisor ~]# virsh snapshot-list webserver Name Creation Time State ------------------------------------------------------------ webserver_snap 2018-02-04 15:05:05 +0530 running [root@kvm-hypervisor ~]# 要列出虚拟机快照的详细信息，请运行下面的 virsh 命令：[root@kvm-hypervisor ~]# virsh snapshot-info --domain webserver --snapshotname webserver_snap Name: webserver_snap Domain: webserver Current: yes State: running Location: internal Parent: - Children: 0 Descendants: 0 Metadata: yes 我们可以使用下面的 qemu-img 命令查看快照的大小：[root@kvm-hypervisor ~]# qemu-img info /var/lib/libvirt/images/snaptestvm.img 还原 KVM 虚拟机快照假设我们想要将 webserver 虚拟机还原到我们在上述步骤中创建的快照。使用下面的 virsh 命令将 Webserver 虚拟机恢复到其快照 webserver\_snap 时。语法：# virsh snapshot-revert {vm_name} {snapshot_name} [root@kvm-hypervisor ~]# virsh snapshot-revert webserver webserver_snap 删除 KVM 虚拟机快照要删除 KVM 虚拟机快照，首先使用 virsh snapshot-list 命令获取虚拟机的快照详细信息，然后使用 virsh snapshot-delete 命令删除快照。如下示例所示：[root@kvm-hypervisor ~]# virsh snapshot-list --domain webserver Name Creation Time State ------------------------------------------------------------ webserver_snap 2018-02-04 15:05:05 +0530 running [root@kvm-hypervisor ~]# virsh snapshot-delete --domain webserver --snapshotname webserver_snap Domain snapshot webserver_snap deleted 这就是本文的全部内容，我希望你们能够了解如何使用 virsh 命令来管理 KVM 虚拟机快照。请分享你的反馈，并不要犹豫地分享给你的技术朋友
有很多不同的方式去管理运行在 KVM 管理程序上的虚拟机。例如，virt-manager 就是一个流行的基于图形界面的前端虚拟机管理工具。然而，如果你想要在没有图形窗口的服务器环境下使用 KVM ，那么基于图形界面的解决方案显然是行不通的。事实上，你可以单纯使用包装了 kvm 命令行脚本的命令行来管理 KVM 虚拟机。作为替代方案，你可以使用 virsh 这个容易使用的命令行程序来管理客户虚拟机。在 virsh 中，它通过和 libvirtd 服务通信来达到控制虚拟机的目的，而 libvirtd 可以控制多个不同的虚拟机管理器，包括 KVM，Xen，QEMU，LXC 和 OpenVZ。当你想要对虚拟机的前期准备和后期管理实现自动化操作时，像 virsh 这样的命令行管理工具是非常有用的。同样，virsh 支持多个管理器也就意味着你可以通过相同的 virsh 接口去管理不同的虚拟机管理器。在这篇文章中，我会示范怎样在 ubuntu 和 debian 上通过使用 virsh 命令行去运行 KVM。第一步：确认你的硬件平台支持虚拟化第一步，首先要确认你的 CPU 支持硬件虚拟化扩展（e.g.，Intel VT 或者 AMD-V)，这是 KVM 对硬件的要求。下面的命令可以检查硬件是否支持虚拟化。$ egrep '(vmx|svm)' --color /proc/cpuinfo 如果在输出中不包含 vmx 或者 svm 标识，那么就意味着你的 cpu 不支持硬件虚拟化。因此你不能在你的机器上使用 KVM 。确认了 cpu 支持 vmx 或者 svm 之后，接下来开始安装 KVM。对于 KVM 来说，它不要求运行在拥有 64 位内核系统的主机上，但是通常我们会推荐在 64 位系统的主机上面运行 KVM。第二步：安装KVM使用 apt-get 安装 KVM 和相关的用户空间工具。$ sudo apt-get install qemu-kvm libvirt-bin 安装期间，libvirtd 用户组（在 debian 上是 libvirtd-qemu 用户组）将会被创建，并且你的用户 id 将会被自动添加到该组中。这样做的目的是让你可以以一个普通用户而不是 root 用户的身份去管理虚拟机。你可以使用 id 命令来确认这一点，下面将会告诉你怎么去显示你的组 id：$ id <your-userID> 如果因为某些原因，libvirt（在 debian 中是 libvirt-qemu）没有在你的组 id 中被找到，你也可以手动将你自己添加到对应的组中，如下所示：在 ubuntu 上：$ sudo adduser [youruserID] libvirtd 在 debian 上：$ sudo adduser [youruserID] libvirt-qemu 按照如下命令重新载入更新后的组成员关系。如果要求输入密码，那么输入你的登陆密码即可。$ exec su -l $USER 这时，你应该可以以普通用户的身份去执行 virsh 了。做一个如下所示的测试，这个命令将会以列表的形式列出可用的虚拟机（当前的列表是空的）。如果你没有遇到权限问题，那意味着到目前为止一切都是正常的。$ virsh list Id Name State 第三步：配置桥接网络为了使 KVM 虚拟机能够访问外部网络，一种方法是通过在 KVM 宿主机上创建 Linux 桥来实现。创建之后的桥能够将虚拟机的虚拟网卡和宿主机的物理网卡连接起来，因此，虚拟机能够发送和接收由物理网卡传输的数据包。这种方式叫做网络桥接。下面将告诉你如何创建并且配置网桥，我们创建一个网桥称它为 br0。首先，安装一个必需的包，然后用命令行创建一个网桥。$ sudo apt-get install bridge-utils $ sudo brctl addbr br0 下一步就是配置已经创建好的网桥，即修改位于 /etc/network/interfaces 的配置文件。我们需要将该桥接网卡设置成开机启动。为了修改该配置文件，你需要关闭你的操作系统上的网络管理器（如果你在使用它的话）。跟随操作指南的说明去关闭网络管理器。关闭网络管理器之后，接下来就是通过修改配置文件来配置网桥了。#auto eth0 #iface eth0 inet dhcp auto br0 iface br0 inet dhcp bridge_ports eth0 bridge_stp off bridge_fd 0 bridge_maxwait 0 在上面的配置中，我假设 eth0 是主要网卡，它也是连接到外网的网卡，同样，我假设 eth0 将会通过 DHCP 协议自动获取 ip 地址。注意，之前在 /etc/network/interfaces 中还没有对 eth0 进行任何配置。桥接网卡 br0 引用了 eth0 的配置，而 eth0 也会受到 br0 的制约。重启网络服务，并确认网桥已经被成功的配置好。如果成功的话，br0 的 ip 地址将会是 eth0 自动分配的 ip 地址，而且 eth0 不会被分配任何 ip 地址。$ sudo /etc/init.d/networking restart $ ifconfig 如果因为某些原因，eth0 仍然保留了之前分配给了 br0 的 ip 地址，那么你可能必须手动删除 eth0 的 ip 地址。第四步：用命令行创建一个虚拟机对于虚拟机来说，它的配置信息被存储在它对应的xml文件中。因此，创建一个虚拟机的第一步就是准备一个与虚拟机对应的 xml 文件。下面是一个示例 xml 文件，你可以根据需要手动修改它。 alice f5b8c05b-9c7a-3211-49b9-2bd635f7e2aa 1048576 1048576 1 hvm <boot dev='cdrom'/> <acpi/> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>destroy</on_crash> /usr/bin/kvm <driver name="qemu" type="raw"/> <target dev="vda" bus="virtio"/> <driver name="qemu" type="raw"/> <target dev="hdc" bus="ide"/> <readonly/> <mac address="00:00:A3:B0:56:10"/> <graphics type='vnc' port='-1' autoport="yes" listen='0.0.0.0'/> <target port='0'/> 上面的主机xml配置文件定义了如下的虚拟机内容。1GB内存，一个虚拟cpu和一个硬件驱动磁盘镜像：/home/dev/images/alice.img从 CD-ROM 引导（/home/dev/iso/CentOS-6.5-x86_64-minomal.iso）网络：一个桥接到 br0 的虚拟网卡通过 VNC 远程访问 中的 UUID 字符串可以随机生成。为了得到一个随机的 uuid 字符串，你可能需要使用 uuid 命令行工具。$ sudo apt-get install uuid $ uuid 生成一个主机 xml 配置文件的方式就是通过一个已经存在的虚拟机来导出它的 xml 配置文件。如下所示。$ virsh dumpxml alice > bob.xml 第五步：使用命令行启动虚拟机在启动虚拟机之前，我们需要创建它的初始磁盘镜像。为此，你需要使用 qemu-img 命令来生成一个 qemu-kvm 镜像。下面的命令将会创建 10 GB 大小的空磁盘，并且它是 qcow2 格式的。$ qemu-img create -f qcow2 /home/dev/images/alice.img 10G 使用 qcow2 格式的磁盘镜像的好处就是它在创建之初并不会给它分配全部大小磁盘容量（这里是 10 GB），而是随着虚拟机中文件的增加而逐渐增大。因此，它对空间的使用更加有效。现在，你可以通过使用之前创建的 xml 配置文件启动你的虚拟机了。下面的命令将会创建一个虚拟机，然后自动启动它。$ virsh create alice.xml Domain alice created from alice.xml 注意: 如果你对一个已经存在的虚拟机执行了了上面的命令，那么这个操作将会在没有任何警告的情况下抹去那个已经存在的虚拟机的全部信息。如果你已经创建了一个虚拟机，你可能会使用下面的命令来启动虚拟机。$ virsh start alice.xml 使用如下命令确认一个新的虚拟机已经被创建并成功的被启动。$ virsh list Id Name State ---------------------------------------------------- 3 alice running 同样，使用如下命令确认你的虚拟机的虚拟网卡已经被成功的添加到了你先前创建的 br0 网桥中。$ sudo brctl show 远程连接虚拟机为了远程访问一个正在运行的虚拟机的控制台，你可以使用VNC客户端。首先，你需要使用如下命令找出用于虚拟机的VNC端口号。$ sudo netstat -nap | egrep '(kvm|qemu)' 在这个例子中，用于 alice 虚拟机的 VNC 端口号是 5900。 然后启动一个VNC客户端，连接到一个端口号为5900的VNC服务器。在我们的例子中，虚拟机支持由CentOS光盘文件启动。使用 virsh 管理虚拟机下面列出了 virsh 命令的常规用法：创建客户机并且启动虚拟机：$ virsh create alice.xml 停止虚拟机并且删除客户机：$ virsh destroy alice 关闭虚拟机（不用删除它）：$ virsh shutdown alice 暂停虚拟机：$ virsh suspend alice 恢复虚拟机：$ virsh resume alice 访问正在运行的虚拟机的控制台：$ virsh console alice 设置虚拟机开机启动：$ virsh autostart alice 查看虚拟机的详细信息：$ virsh dominfo alice 编辑虚拟机的配置文件：$ virsh edit alice 上面的这个命令将会使用一个默认的编辑器来调用主机配置文件。该配置文件中的任何改变都将自动被libvirt验证其正确性。你也可以在一个virsh会话中管理虚拟机。下面的命令会创建并进入到一个virsh会话中：$ virsh 在 virsh 提示中，你可以使用任何 virsh 命令。问题处理我在创建虚拟机的时候遇到了一个错误：error: internal error: no supported architecture for os type 'hvm'如果你的硬件不支持虚拟化的话你可能就会遇到这个错误。（例如，Intel VT或者AMD-V），这是运行KVM所必需的。如果你遇到了这个错误，而你的cpu支持虚拟化，那么这里可以给你一些可用的解决方案：首先，检查你的内核模块是否丢失。$ lsmod | grep kvm 如果内核模块没有加载，你必须按照如下方式加载它。$ sudo modprobe kvm_intel (for Intel processor) $ sudo modprobe kvm_amd (for AMD processor) 第二个解决方案就是添加 --connect qemu:///system 参数到 virsh 命令中，如下所示。当你正在你的硬件平台上使用超过一个虚拟机管理器的时候就需要添加这个参数（例如，VirtualBox，VMware）。$ virsh --connect qemu:///system create alice.xml 当我试着访问我的虚拟机的登陆控制台的时候遇到了错误： $ virsh console alice error: internal error: cannot find character device <null> 这个错误发生的原因是你没有在你的虚拟机配置文件中定义控制台设备。在 xml 文件中加上下面的内部设备部分即可。 <target port='0'/> via: http://xmodulo.com/use-kvm-command-line-debian-ubuntu.html作者：Dan Nanni 译者：kylepeng93 校对：Ezio本文由 LCTT 原创编译，Linux中国 荣誉推出
如何在Linux中用命令行工具管理KVM虚拟环境
在我们KVM系列专题的第四部分，我们将会一起讨论下在命令行界面下来管理KVM环境。我们分别用‘virt-install’和virsh命令行工具来创建并配置虚拟机和存储池，用qemu-img命令行工具来创建并管理磁盘映像。Linux系统的KVM管理在这篇文章里没有什么新的概念，我们只是用命令行工具重复之前所做过的事情，也没有什么前提条件，都是相同的过程，之前的文章我们都讨论过。第一步: 配置存储池Virsh命令行工具是一款管理virsh客户域的用户界面。virsh程序能在命令行中运行所给的命令以及它的参数。本节中，我们要用它给我们的KVM环境创建存储池。想知道关于这个工具的更多信息，用以下这条命令。# man virsh 1. 用virsh带pool-define-as的命令来定义新的存储池，你需要指定名字、类型和类型参数。本例中，我们将名字取为Spool1，类型为目录。默认情况下你可以提供五个参数给该类型：source-hostsource-pathsource-devsource-nametarget对于目录类型，我们需要用最后一个参数“target”来指定存储池的路径，其它参数项我们可以用“-”来填充。# virsh pool-define-as Spool1 dir - - - - "/mnt/personal-data/SPool1/" 创建新存储池2. 查看环境中我们所有的存储池，用以下命令。# virsh pool-list --all 列出所有存储池3. 现在我们来构造存储池了，用以下命令来构造我们刚才定义的存储池。# virsh pool-build Spool1 构造存储池4. 用带pool-start参数的virsh命令来激活并启动我们刚才创建并构造完成的存储池。# virsh pool-start Spool1 激活存储池5. 查看环境中存储池的状态，用以下命令。# virsh pool-list --all 查看存储池状态你会发现Spool1的状态变成了已激活。6. 对Spool1进行配置，让它每次都能被libvirtd服务自启动。# virsh pool-autostart Spool1 配置KVM存储池7. 最后来看看我们新的存储池的信息吧。# virsh pool-info Spool1 查看KVM存储池信息恭喜你，Spool1已经准备好待命，接下来我们试着创建存储卷来使用它。第二步: 配置存储卷/磁盘映像现在轮到磁盘映像了，用qemu-img命令在Spool1中创建一个新磁盘映像。获取更多细节信息，可以查看man手册。# man qemu-img 8. 我们应该在qemu-img命令之后指定“create, check,…”等等操作、磁盘映像格式、你想要创建的磁盘映像的路径和大小。# qemu-img create -f raw /mnt/personal-data/SPool1/SVol1.img 10G 创建存储卷9. 通过使用带info的qemu-img命令，你可以获取到你的新磁盘映像的一些信息。查看存储卷信息警告: 不要用qemu-img命令来修改被运行中的虚拟机或任何其它进程所正在使用的映像，那样映像会被破坏。现在是时候来创建虚拟机了。第三步: 创建虚拟机10. 现在到最后一个环节了，在最后一步中，我们将用virt-install命令来创建虚拟机。virt-install是一个用来创建新的KVM虚拟机命令行工具，它使用“libvirt”管理程序库。想获取更多细节，同样可以查看man手册。# man virt-install 要创建新的KVM虚拟机，你需要用到带以下所有信息的命令。Name: 虚拟机的名字。Disk Location: 磁盘映像的位置。Graphics : 怎样连接VM，通常是SPICE。vcpu : 虚拟CPU的数量。ram : 以兆字节计算的已分配内存大小。Location : 指定安装源路径。Network : 指定虚拟网络，通常是virbr0网桥。virt-install --name=rhel7 --disk path=/mnt/personal-data/SPool1/SVol1.img --graphics spice --vcpu=1 --ram=1024 --location=/run/media/dos/9e6f605a-f502-4e98-826e-e6376caea288/rhel-server-7.0-x86_64-dvd.iso --network bridge=virbr0创建新的虚拟机11. 你会看到弹出一个virt-vierwer窗口，像是在通过它在与虚拟机通信。虚拟机启动程式虚拟机安装过程结论以上就是我们KVM教程的最后一部分了，当然我们还没有完全覆盖到全部，我们只是打了个擦边球，所以现在该轮到你来好好地利用这些丰富的资源来做自己想做的事了。KVM Getting Started GuideKVM Virtualization Deployment and Administration Guidevia: http://www.tecmint.com/kvm-management-tools-to-manage-virtual-machines/作者：Mohammad Dosoukey 译者：ZTinoZ 校对：wxy本文由 LCTT 原创翻译，Linux中国 荣誉推出
Linux 有问必答：如何修复“hda-duplex not supported in this QEMU binary”
提问： 当我尝试在虚拟机中安装一个新的Linux时，虚拟机不能启动且报了下面这个错误："unsupported configuration: hda-duplex not supported in this QEMU binary."（“不支持的配置：hda-duplex在此QEMU文件中不支持。”） 我该如何修复？这个错误可能来自一个当默认声卡型号不能被识别时的一个qemu bug。无法完成安装：‘不支持的配置：hda-duplex在此QEMU文件中不支持’ 要解决这个问题，按照下面的做。方案一: virt-manager在virt-manager中，打开虚拟机的虚拟硬件详细菜单，进入声卡选项，改变默认的设备型号为ac97。点击“应用”按钮并保存设置。看一下虚拟机现在是否可以启动了。方案二: Virsh如果你使用的是virsh 而不是virt-manager， 你可以编辑VM相应的配置文件。在节点中查找sound节点，并按照下面的默认声卡型号改成ac97。<devices> . . . . . . </device> via: http://ask.xmodulo.com/hda-duplex-not-supported-in-this-qemu-binary.html译者：geekpi 校对：wxy本文由 LCTT 原创翻译，Linux中国 荣誉推出
提问： 我使用libvirt和virt-manager在我的Linux系统上创建虚拟机。我注意到虚拟机镜像位于/var/lib/libvirt/images目录。有没有办法改变虚拟机镜像的默认路径？libvirt和它的GUI前端virt-manager可以使用不同的虚拟机管理程序创建和管理VM，例如LVM和Xen。默认上所有的虚拟机镜像通过libvirt创建到/var/lib/libvirt/images目录。然而，这有时并不是我们希望的。比如 /var/lib/libvirt/images 此处的磁盘分区大小有限。或者你想要存储所有的虚拟机镜像到一个特定的用于管理的仓库中。实际上，你可以非常容易地改变libvirt镜像的默认目录，或者称之为“存储池”。有两种方法可以改变默认存储池。方法一: Virt-Manager GUI如果你正在使用virt-manager GUI程序，改变默认存储池非常容易。进入virt-manager的菜单GUI “编辑” -> "连接细节"。你可以看到如下所是的默认存储池。在窗口的左下角，点击叉形按钮，将会停止默认的存储池。存储池一旦停止后，点击右边的垃圾桶，将会删除存储池。注意这个动作不会删除池中的镜像。现在点击左边的加号增加一个新的存储池。输入新的存储池的名字（比如：default），并且选择存储池的类型。本例中，因为我们只是改变存储池目录所以选择“文件系统目录”。输入新的存储池路径（比如，/storage）。这时，新的存储池应该启动了，并且自动在你创建一个新的虚拟机的时候使用。方法二: Virsh 命令行另外一个改变默认存储池目录的方法是使用来自libvirt包的virsh 命令行工具。首先，运行下面的命令来导出默认存储池的XML定义。 $ virsh pool-dumpxml default > pool.xml 用文本编辑器打开XML文件，并且改变节点中的/var/lib/libvirt/images改成新的地址。 default 0ec0e393-28a2-e975-feec-0c7356f38d08 975762788352 530052247552 445710540800 /var/lib/libvirt/images 0711 -1 -1 移除现在的默认池。$ virsh pool-destroy default Pool default destroyed 现在创建一个基于更新后的XML文件的新存储池。$ virsh pool-create pool.xml Pool default created from pool.xml 这时，默认池已经改变到新的地址了，并且可以使用了。via: http://ask.xmodulo.com/change-default-location-libvirt-vm-images.html译者：geekpi 校对：wxy本文由 LCTT 原创翻译，Linux中国 荣誉推出