如何在 Debian 或 Ubuntu 上从命令行使用 KVM
有多种方法可以管理在 KVM 管理程序上运行的虚拟机 (VM)。例如,virt-manager
是一种流行的基于 GUI 的虚拟机管理前端。然而,如果您想在无头服务器上使用 KVM,基于 GUI 的解决方案将不是理想的选择。事实上,您可以使用 kvm
命令行包装脚本纯粹从命令行创建和管理 KVM 虚拟机。或者,您可以使用 virsh,这是一个更易于使用的命令行用户界面,用于管理来宾虚拟机。在 virsh 之下,它与 libvirtd 服务进行通信,该服务可以控制多个不同的虚拟机管理程序,包括 KVM、Xen、QEMU、LXC 和 OpenVZ。
当您想要自动配置和管理虚拟机时,virsh
等命令行管理界面也很有用。此外,virsh
支持多个虚拟机管理程序,这意味着您可以通过相同的 virsh
界面管理不同的虚拟机管理程序。
在本教程中,我将演示如何在 Debian 或 Ubuntu 上使用 virsh 从命令行运行 KVM。
第一步:验证硬件虚拟化支持
第一步,验证主机 CPU 是否配备了 KVM 所需的硬件虚拟化扩展(例如 Intel VT 或 AMD-V)。下面的命令就可以了。
$ egrep '(vmx|svm)' --color /proc/cpuinfo

如果输出不包含 vmx 或 svm 标志,则表示主机 CPU 不支持硬件虚拟化。因此您无法在主机上使用 KVM。验证主机CPU是否带有vmx
或svm
后,继续安装KVM。
对于KVM,不需要在KVM主机上运行64位内核,但通常建议这样做。
第二步:安装KVM
使用 apt-get 安装 KVM 和相关的用户空间工具。
$ sudo apt-get install qemu-kvm libvirt-bin
在安装过程中,将创建 libvirtd
组(或 Debian 上的 libvirt-qemu
),并且您的用户 ID 将自动添加到该组中。这将允许您以非 root 普通用户身份管理虚拟机。您可以使用 id
命令来验证这一点,该命令将显示您的组 ID:
$ id <your-userID>

如果由于某种原因,在您的 groupID 列表中找不到 libvirtd
(或 libvirt-qemu
),您可以手动将自己添加到组中,如下所示。
在Ubuntu上:
$ sudo adduser [youruserID] libvirtd
在 Debian 上:
$ sudo adduser [youruserID] libvirt-qemu
重新加载更新的组成员身份信息,如下所示。当要求输入密码时,输入您的登录密码。或者,您可以注销并重新登录。
$ exec su -l $USER
此时,您应该能够以普通用户身份运行 virsh。作为测试,请尝试以下命令,该命令将显示可用虚拟机的列表(当前没有)。如果您没有遇到权限错误,则意味着到目前为止一切正常。
$ virsh list
Id Name State
----------------------------------------------------
第三步:配置桥接网络
使 KVM 虚拟机能够访问外部网络的一种方法是通过在 KVM 主机上创建的 Linux 桥。桥接器将虚拟机的虚拟接口与主机的物理接口互连,以便虚拟机可以通过物理接口发送或接收流量。这称为桥接网络。
以下是如何创建和配置 Linux 桥 br0 以与 KVM 桥接网络。
首先,安装必要的软件包,并从命令行创建 Linux 桥。
$ sudo apt-get install bridge-utils
$ sudo brctl addbr br0
下一步是在 /etc/network/interfaces
中配置 Linux 网桥,以便在启动时自动配置网桥。要使用 /etc/network/interfaces
,您需要在系统上禁用网络管理器(如果您正在使用它)。
禁用网络管理器后,继续在 /etc/network/interfaces
中配置 Linux 网桥 br0
,如下所示。
#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
的 IP 配置。 Linux 网桥 br0
占用 eth0
的配置,因为 eth0
被从属于网桥 br0
。
重新启动网络服务,并验证Linux网桥是否配置成功。如果成功,应为 br0
分配 eth0
的 DHCP IP 地址,而 eth0
不应分配任何 IP 地址。
$ sudo /etc/init.d/networking restart
$ ifconfig
如果由于任何原因 eth0
仍然保留分配给 br0
的 IP 地址,您可能必须从 eth0
中显式删除该 IP 地址。

除了桥接网络之外,还有许多其他方式来互连虚拟机。另一种互连解决方案是使用Open vSwitch,它允许为虚拟机定义更灵活的转发和过滤策略。配置 Open vSwitch 超出了本教程的范围。
第四步:从命令行创建虚拟机
对于 KVM,VM 的配置存储在域 XML 文件中。因此,创建虚拟机的第一步是准备其域 XML 文件。
以下是 VM 的示例域 XML 文件。您可以根据需要对其进行自定义。
<domain type='kvm'>
<name>alice</name>
<uuid>f5b8c05b-9c7a-3211-49b9-2bd635f7e2aa</uuid>
<memory>1048576</memory>
<currentMemory>1048576</currentMemory>
<vcpu>1</vcpu>
<os>
<type>hvm</type>
<boot dev='cdrom'/>
</os>
<features>
<acpi/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/kvm</emulator>
<disk type="file" device="disk">
<driver name="qemu" type="raw"/>
<source file="/home/dev/images/alice.img"/>
<target dev="vda" bus="virtio"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x04" function="0x0"/>
</disk>
<disk type="file" device="cdrom">
<driver name="qemu" type="raw"/>
<source file="/home/dev/iso/CentOS-6.5-x86_64-minimal.iso"/>
<target dev="hdc" bus="ide"/>
<readonly/>
<address type="drive" controller="0" bus="1" target="0" unit="0"/>
</disk>
<interface type='bridge'>
<source bridge='br0'/>
<mac address="00:00:A3:B0:56:10"/>
</interface>
<controller type="ide" index="0">
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x1"/>
</controller>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='-1' autoport="yes" listen='0.0.0.0'/>
<console type='pty'>
<target port='0'/>
</console>
</devices>
</domain>
上述域 XML 文件定义了以下 VM。
1GB 内存、1 个 vCPU 和 1 个硬盘。
磁盘映像:
/home/dev/images/alice.img
。从 CD-ROM (
/home/dev/iso/CentOS-6.5-x86_64-minimal.iso
) 启动。网络:一个网络接口桥接到
br0
通过 VNC 进行远程访问。
uuid
命令行工具。
$ sudo apt-get install uuid
$ uuid
创建域 XML 文件的另一种方法是转储现有 VM 的域信息,如下所示。
$ virsh dumpxml alice > bob.xml

第五步:从命令行启动虚拟机
在启动虚拟机之前,您需要创建其初始磁盘映像。为此,您可以使用 qemu-img
命令,该命令随您安装的 qemu-kvm
软件包一起提供。以下命令创建 QCOW2 类型的 10GB 大小的空磁盘映像:
$ qemu-img create -f qcow2 /home/dev/images/alice.img 10G
使用 QCOW2
(相对于 RAW
)作为磁盘映像格式的优点是,QCOW2
类型的磁盘映像最初不会创建为完整大小 (10GB),而是随着磁盘填充而增长。因此它更节省空间。
现在您已准备好使用之前创建的域 XML 文件启动 VM。以下命令将创建一个虚拟机,并自动启动它。
$ virsh create alice.xml
Domain alice created from alice.xml
注意:如果您对已创建的虚拟机运行上述命令,则会在没有警告的情况下清除该虚拟机。如果您已经创建了 VM,则可以使用以下命令来启动 VM。
$ virsh start alice.xml
验证新域是否已创建并成功启动:
$ virsh list
Id Name State
----------------------------------------------------
3 alice running
此外,验证虚拟机的虚拟接口(例如,vnet0
)是否已成功添加到您之前创建的 Linux 网桥 br0
。
$ sudo brctl show

第六步:远程访问虚拟机
要远程访问正在运行的虚拟机的控制台,您可以使用任何 VNC 客户端。
首先,按如下所示找出虚拟机的 VNC 端口号。
$ sudo netstat -nap | egrep '(kvm|qemu)'

在此示例中,alice
VM 的 VNC 端口号为 5900
。
然后启动 VNC 客户端,并连接到在
运行的 VNC 服务器。在我们的示例中,虚拟机应该启动到 CentOS CD-ROM。

使用 virsh 管理虚拟机
下面列出了 virsh 命令的常见用法。
要创建新的来宾域并启动 VM:
$ virsh create alice.xml
要停止 VM 并销毁来宾域:
$ virsh destroy alice
关闭虚拟机(不破坏域):
$ virsh shutdown alice
暂停虚拟机:
$ virsh suspend alice
要恢复挂起的虚拟机:
$ virsh resume alice
要访问正在运行的虚拟机的登录控制台:
$ virsh console alice
要在主机启动时自动启动 VM:
$ virsh autostart alice
获取虚拟机的域信息:
$ virsh dominfo alice
编辑 VM 的域 XML:
$ virsh edit alice
上面将使用默认文本编辑器调用 VM 的域 XML 文件。 XML 中的任何更改都将由 libvirt
自动验证其正确性。
您还可以在 virsh
会话中管理虚拟机。要创建并进入新的 virsh 会话,只需运行:
$ virsh
在 virsh
提示符下,您可以使用任何 virsh
命令。

故障排除
1. 我在尝试创建虚拟机时收到错误:
error: internal error: no supported architecture for os type 'hvm'
如果您的硬件没有运行 KVM 所需的硬件虚拟化支持(例如 Intel VT 或 AMD-V),您可能会收到此错误。如果即使您的 CPU 配备 Intel VT 或 AMD-V,您仍收到此错误,以下是可能的解决方案:
首先,检查kvm
内核模块是否丢失。
$ lsmod | grep kvm
如果kvm
内核模块未加载,则必须按如下方式加载它。
$ sudo modprobe kvm_intel (for Intel processor)
$ sudo modprobe kvm_amd (for AMD processor)
第二种解决方案是将 --connect qemu:///system
参数添加到 virsh
命令中,如下所示。当您在服务器硬件上使用多个虚拟机管理程序(例如 VMware、VirtualBox)时,可能需要此参数。
$ virsh --connect qemu:///system create alice.xml
2. 我在尝试访问虚拟机的登录控制台时收到错误:
$ virsh console alice
error: internal error: cannot find character device <null>
出现此错误的原因是您没有在 VM 的 XML 文件中定义控制台设备。在 XML 文件的 device
部分中添加以下内容。
<console type='pty'>
<target port='0'/>
</console>