| |
IBM System x 系列服务器基于 Intel 和 AMD 的 x86 构架,支持 Windows 和 Linux 平台。
SLES(Suse Linux Enterprise Linux)是 Novell 公司开发的针对企业级应用的操作系统。可以运行在 IBM x, p ,z 系列服务器上。 Novell 于 2009 年 4 月发布了 SUSE Linux Enterprise 11,基于 Linux kernel 2.6.27,已经支持了 KVM,并且还收录了 KVM 的用户管理程序 kvm-qemu 。
KVM 是指基于 Linux 内核的虚拟机(Kernel-based Virtual Machine)。 2006 年 10 月,由以色列的 Qumranet 组织开发的一种新的“虚拟机”实现方案。 2007 年 2 月发布的 Linux 2.6.20 内核第一次包含了 KVM 。增加 KVM 到 Linux 内核是 Linux 发展的一个重要里程碑,这也是第一个整合到 Linux 主线内核的虚拟化技术。
KVM 在标准的 Linux 内核中增加了虚拟技术,从而我们可以通过优化的内核来使用虚拟技术。在 KVM 模型中,每一个虚拟机都是一个由 Linux 调度程序管理的标准进程,你可以在用户空间启动客户机操作系统。一个普通的 Linux 进程有两种运行模式:内核和用户。 KVM 增加了第三种模式:客户模式(有自己的内核和用户模式)。图 1 展示了 KVM 虚拟化的原理图。
一个典型的 KVM 安装包括以下部件:
运行 KVM,你需要一台运行 2.6.20 以上 Linux 内核的 Intel 处理器(含 VT 虚拟化技术)或 AMD 处理器(含 SVM 安全虚拟机技术的 AMD 处理器)。下面将详细介绍如何在装有 SLES11(kernel-2.6.27.19)的 IBM System x3550 上安装和配置基于 KVM 的虚拟机。
本文的实例中,硬件选用了 IBM System x3500,处理器是 Intel 至强 4 核 X5160,最高主频 3.00GHz,内存 16GB,存储为 8 块 73GB 高速硬盘,集成双千兆以太网卡。虚拟化可以使这些资源得到充分的利用。
machine type: 7977-99B4314 CPU : Intel(R) Xeon(R) CPU 5160 @ 3.00GHz x4 Memory: 16GB Hard disk: 73GB x8 Network: eth0 (dhcp) eth1 (static IP)9.123.99.193 |
Novell 于 2009 年 4 月发布了 SUSE Linux Enterprise 11,它可运行于各种领先的硬件平台,包括 x86-32、x86-64、IBM POWER 和 IBM System z 。 SUSE Linux Enterprise 11 基于 Linux kernel 2.6.27,已经支持了 KVM,并且还收录了 KVM 的用户管理程序 kvm-qemu 。
操作系统选用支持 KVM 的 SLES11: linux-gwsa:~ # uname -a Linux linux-gwsa 2.6.27.19-5-default #1 \n SMP 2009-02-28 04:40:21 +0100 x86_64 x86_64 x86_64 GNU/Linux 已经加载的 kvm 模块: linux-gwsa:/srv/ovs/images # lsmod | grep kvm kvm_intel 49104 1 kvm 172488 1 kvm_intel 用户空间的模拟器 qemu-kvm: linux-gwsa:~ # rpm -qa | grep kvm-78-13.8 kvm-78-13.8 KVM 在 SLES11 上的补丁: linux-gwsa:~ # rpm -qa | grep kvm-kmp-default-78_2.6.27.19_5-13.8 kvm-kmp-default-78_2.6.27.19_5-13.8 桥接客户机网络的工具包: linux-gwsa:~ # rpm -qa | grep bridge bridge-utils-1.4-23.16 |
使用 qemu-kvm 安装客户机之前,需要配置客户机的虚拟硬件参数:
qemu-kvm 参数 | 参数说明 | 参数实例 |
-mmegs | 分配给客户机的内存 (MB 为单位 ) | 0 |
-smpn | 模拟包含 n 个处理器的 SMP system(对称多处理器系统) | 4 |
-hdafile | 指定 file 文件作为客户机的存储镜像 hard disk 0 这里 file 可以是一个文件名,也可以是硬盘分区。区别见 Tips:调整客户机的镜像文件 | /home/kvm.img |
-net nic[,vlan=n][,macaddr=addr][,model=type] | 为客户机创建虚拟的 NIC(Netowrk Interface Card 网络接口设备), 设置 MAC 地址,虚拟网卡类型等 | model=e1000, macaddr=00:16:3e:51:fb:ce |
-net tap[,vlan=n][,fd=h][,ifname=name][,script=file] | 为客户机设置 TAP 网络连接,具体见 客户机网络设置 | -net tap |
-cdrom | 挂载 ISO 镜像到客户机,光盘启动客户机时必须加载 | /mnt/SLES10SP2.iso |
-boot [a|c|d|n] | 设置客户机的启动选项(软盘 a,硬盘 c,光盘 d,网络 n),默认从硬盘镜像启动 | d |
-vncdisplay | 通过 VNC 的方式远程安装 | 9.123.99.34:3 |
把上面的参数串在一起就是安装 KVM 虚拟机的命令,见清单 2 。
使用文件作为客户机存储,从光盘启动,使用默认的网络配置: linux-gwsa:~ # qemu-kvm -m 4096 -smp 4 -hda /home/kvm.img \n -cdrom /mnt/SLES10SP2.iso -boot d 使用硬盘分区作为客户机存储,从光盘启动,设置 TAP 网络,通过 VNC 远程安装: linux-gwsa:~ # qemu-kvm -m 4096 -smp 4 -hda /dev/sdb1 -net nic, model=e1000, \n macaddr=00:16:3e:51:fb:ce -net tap -cdrom /mnt/SLES10SP2.iso -boot d -vnc 9.123.99.34:3 |
在 xWindow 中输入清单 3 中的命令,或者通过 VNC 远程连接,显示图 2 中的客户机安装界面:
选择 3 从光盘启动,进入大家熟悉的 Linux 安装步骤。本例中添加了网络安装的参数,这样将从网络安装客户机。
从网络下载了安装程序后进入 YAST 安装界面,余下的步骤和在物理机上安装 SLES 一样。
第二台客户机的安装以第一台稍有不同,主要是网络上的设置和资源的分配。下节中将详细介绍客户机的网络设置。
客户机安装完成后,需要为其设置网络接口,以便和主机网络,客户机之间的网络通信。事实上,如果要在安装时使用网络通信,需要提前设置客户机的网络连接。
KVM 客户机网络连接有两种方式:
本文选用了虚拟网桥的网络连接方式,是客户机和子网里面的机器能够互相通信。
本例中 IBM System x3500 有两块千兆以太网卡,一块网卡连接外网的 9.123.99.x 网段,一块网卡连接内网 192.168.0.x 网段。本例采用虚拟网桥的连接方式使客户机能够同时自由访问两个网段。
编辑 /etc/sysconfig/network-scripts/ifcfg-eth0 文件 注释 BOOTPROTO 增加 BRIDGE=switch |
创建 /etc/sysconfig/network-scripts/ifcfg-br0 文件,内容如下: linux-gwsa:~ # cat /etc/sysconfig/network/ifcfg-br0 DEVICE=br0 TYPE=Bridge BOOTPROTO=dhcp NBOOT=yes 重新启动网络,激活网桥: /etc/init.d/network restart |
网桥 br0 应该获得 IP 地址(静态或 DHCP),同时物理的 eth0 必须不配置 IP 地址。重新启动网络后,主机的网络设备列表如清单 6 所示:
linux-gwsa:~ # ifconfig br0 Link encap:Ethernet HWaddr 00:1A:64:48:87:B6 inet addr:192.168.0.13 Bcast:192.168.0.255 Mask:255.255.255.0 inet6 addr: fe80::21a:64ff:fe48:87b6/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:669843 errors:0 dropped:0 overruns:0 frame.:0 TX packets:344910 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:113618306 (108.3 Mb) TX bytes:495318687 (472.3 Mb) eth0 Link encap:Ethernet HWaddr 00:1A:64:48:87:B6 inet6 addr: fe80::21a:64ff:fe48:87b6/64 Scope:Link UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1 RX packets:11681269 errors:0 dropped:0 overruns:0 frame.:0 TX packets:5505473 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:16627242146 (15856.9 Mb) TX bytes:485265358 (462.7 Mb) Interrupt:16 eth1 Link encap:Ethernet HWaddr 00:1A:64:48:87:B7 inet addr:9.123.99.193 Bcast:9.123.99.255 Mask:255.255.255.0 inet6 addr: fe80::21a:64ff:fe48:87b7/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:5481826 errors:0 dropped:0 overruns:0 frame.:0 TX packets:5453113 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:5100133488 (4863.8 Mb) TX bytes:4753271194 (4533.0 Mb) Interrupt:17 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:187412 errors:0 dropped:0 overruns:0 frame.:0 TX packets:187412 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:801868898 (764.7 Mb) TX bytes:801868898 (764.7 Mb) linux-gwsa:~ # brctl show bridge name bridge id STP enabled interfaces br0 8000.001a644887b6 no eth0 |
此外,需要一个包含如下内容的 qemu-ifup 脚本,作为客户机的网络配置脚本。/etc/qemu-ifup
是默认的客户机网络配置文件,如果使用其他名字或拷贝到其他位置,请用script=file
参数指定。
linux-gwsa:~ # cat /etc/qemu-ifup #!/bin/sh echo 'config qemu network with bridge for ' $* bridge=br0 # Exit if $bridge is not a bridge. Exit with 0 status # so qemu-dm process is not terminated. No networking in # vm is bad but not catastrophic. The vm could still run # cpu and disk IO workloads. # Include an useful error message in qemu-dm log file. if [ ! -e "/sys/class/net/${bridge}/bridge" ] then echo "WARNING! ${bridge} is not a bridge. qemu-ifup exiting. \n VM may not have a functioning networking stack." exit 0 fi ifconfig $1 0.0.0.0 up brctl addif $bridge $1 || true |
主机上如果有多台客户机使用网络,每个客户机必须有不同的 MAC 地址,所以需要在网络参数中为每个客户机指定不同的 MAC 地址。以下脚本可以自动生成 MAC 地址(执行 python 脚本需要系统安装了 python 解释器)。
linux-gwsa:~ # cat macgen.py #!/usr/bin/python # macgen.py script. to generate a MAC address for Red Hat Virtualization guests # import random # def randomMAC(): mac = [ 0x00, 0x16, 0x3e, random.randint(0x00, 0x7f), random.randint(0x00, 0xff), random.randint(0x00, 0xff) ] return ':'.join(map(lambda x: "%02x" % x, mac)) # print randomMAC() 生成 MAC 地址的示例: linux-gwsa:~ # ./macgen.py 00:16:3e:51:fb:ce |
linux-gwsa:~ # qemu-kvm -m 8192 -smp 4 -hda /dev/sdb1 -net \n nic,model=e1000,macaddr=00:16:3e:51:fb:ce -net tap 参数说明 -net nic,model=e1000,macaddr=00:16:3e:51:fb:ce 设置虚拟网卡类型为 e1000,设置 MAC 地址。 -net tap 使用 tap 网络模式,默认的配置脚本是 /etc//etc/qemu-ifup ( 见 qemu-kvm 的 manpage) 。 |
在 xWindow 中运行启动客户机的命令后,选择从硬盘启动。看到如图 6 的 grub 选项。
登陆客户机的 xWindow,测试网络连接状况。从图 7 看出,客户机获得了 IP 地址 192.168.0.158,识别了 qemu-kvm 虚拟的千兆网卡 Intel e1000 网络模块。为了测试网络速度,从外网的一台机器上用 scp 下载文件,下载速度平均为 5.1 MB/s 。
启动一台客户机后,主机上多出了一个 tap0 虚拟网络设备,这就是 qemu-kvm 为客户机虚拟的 TAP 网络设备。查看网桥可以看出 tap0 加入了网桥 br0 。客户机就是通过网桥访问的外网。
linux-gwsa:~ # ifconfig tap0 tap0 Link encap:Ethernet HWaddr EA:FC:99:17:F3:A5 inet6 addr: fe80::e8fc:99ff:fe17:f3a5/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:220322 errors:0 dropped:0 overruns:0 frame.:0 TX packets:342093 errors:0 dropped:0 overruns:11 carrier:0 collisions:0 txqueuelen:500 RX bytes:21559069 (20.5 Mb) TX bytes:479156726 (456.9 Mb) linux-gwsa:~ # brctl show bridge name bridge id STP enabled interfaces br0 8000.001a644887b6 no eth0 tap0 |
有了第一台客户机的安装经验,我们很容易安装更多的客户机在同一主机上,当然要在硬件资源足够的情况下。安装多台客户机时,需要注意以下几点:
由于我们在安装第一台客户机时,使用了虚拟网桥,而且在客户机的网络配置脚本/etc/qemu-ifup
具有可扩展性,所以安装第二台客户机时不用改动任何脚本,只需要配置不同的存储镜像和 MAC 地址。
使用硬盘分区作为客户机存储,从光盘启动,设置 TAP 网络,通过 VNC 远程安装: linux-gwsa:~ # qemu-kvm -m 4096 -smp 4 -hda /dev/sdc1 -net nic,model=virtio, \n macaddr=00:16:3e:55:83:c3 -net tap -cdrom /mnt/SLES11.iso -boot d -vnc 9.123.99.34:5 启动第二台客户机 linux-gwsa:~ # qemu-kvm -m 8192 -smp 4 -hda /dev/sdc1 -net nic,model=virtio, \n macaddr=00:16:3e:55:83:c3 -net tap -vnc 9.123.99.34:5 |
安装完成并启动第二台客户机,我们可以查看它的网络状况,如图 8 。
可以看出,客户机获得了 IP 地址 192.168.0.181,识别并加载了 qemu-kvm 虚拟的网卡模块 virtio 。为了测试网络速度,从外网的一台机器上用 scp 下载文件,下载速度平均为 11.1 MB/s 。速度几乎与物理网卡一样。细心的读者可能发现了两台客户机的网络性能有着巨大的差异,请参见下一节:调整客户机的网络性能。
这时主机上同时运行着两台虚拟机,他们的网络结构正如图 5 所示。在主机上的网络设备列表如清单 12 。
l inux-gwsa:~ # ifconfig -s Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg br0 1500 0 703127 0 0 0 346383 0 0 0 BMRU eth0 1500 012819806 0 0 0 7691669 0 0 0 BMPRU eth1 1500 0 5532987 0 0 0 5500852 0 0 0 BMRU lo 16436 0 187413 0 0 0 187413 0 0 0 LRU tap0 1500 0 2288413 0 0 0 1235382 0 0 11 BMRU tap1 1500 0 56615 0 0 0 125450 0 0 0 BMRU linux-gwsa:~ # brctl show bridge name bridge id STP enabled interfaces br0 8000.001a644887b6 no eth0 tap0 tap1 |
后面的 tapX 是不同的虚拟机的接口,这里可以看出,所有的虚拟接口和 eth0 加入到了网桥。这样客户机就能够通过桥接访问主机上的网络。
KVM 作为内核虚拟机,利用了处理器的硬件虚拟功能,性能上已经比其他的虚拟机高很多。但是 qemu-kvm 有复杂的参数,仔细调整这些参数可以使客户机的性能更上一层楼。
安装客户机时,存储镜像默认基于文件。在主机上看来就是一个很大的镜像文件。文件的方式容易设置而且比较灵活,可以存放在主机文件系统之上。 但是如果客户机上进行高负荷的磁盘操作,映射到主机上这个单独的镜像文件时,性能必然受到很大影响。存储镜像的另外一个选择就是直接分配硬盘分区给客户 机。如果资源允许,单独分配一块物理硬盘给每个客户机。一是客户机的磁盘操作不需要经过主机的文件系统,减少了主机文件系统的性能损耗;二是单独的硬盘分 区 I/O 性能必定比单独的文件高。
本文的示例中,两台客户机都选者了使用单独的硬盘作为存储。
从 manpage 可知,qemu-kvm 支持多种虚拟的网络设备模块。
Network options: -net nic[,vlan=n][,macaddr=addr][,model=type] Create a new Network Interface Card and connect it to VLAN n (n = 0 is the default). The NIC is an rtl8139 by default on the PC target. Optionally, the MAC address can be changed. If no -net option is specified, a single NIC is created. Qemu can emulate several different models of network card. Valid values for type are "i82551", "i82557b", "i82559er", "ne2k_pci", "ne2k_isa", "pcnet", "rtl8139", "e1000", "smc91c111", "lance" and "mcf_fec". Not all devices are supported on all targets. Use -net nic,model=? for a list of available devices for your target. |
本文实例中,如果不指定虚拟网络设备模块时,默认的客户机网络模块是 rtl8029 。这是一块老式的 10M 全双工网卡。客户机上网络连接不稳定,从千兆网络通过 scp 下载速度最高才 300KB/s 。
第一台客户机上,我为其配置了常见的 intel e1000 千兆网络模块作为虚拟网络设备。客户机的网络非常稳定,从千兆网络通过 scp 下载速度最高达到 5.4MB/s(见图 7)。但是距离实际千兆网卡的性能还有一定差距。
第二台客户机上,我为其配置了 VirtIO Paravirtual 虚拟设备。客户机的网络非常稳定,从千兆网络通过 scp 下载速度最高达到 11MB/s(见图 8),几乎与千兆物理网卡的性能一样。
虚拟网络模块 | 网络传输速度(ssh) | 客户机操作系统 | 网络状态 |
rtl8029 | 200-300KB/s | SLES10SP2 (kernel 2.6.16-60) | 不稳定 |
e1000 | 4.8-5.4MB/s | SLES10SP2 (kernel 2.6.16-60) | 稳定 |
virtio | 10.6-11.1MB/s | SLES11 (kernel 2.6.27-19) | 稳定 |
VirtIO paravirtual 是 Linux 虚拟机平台上统一的虚拟 IO 接口驱动。通常主机为了让客户机像在真实环境中一样运行,需要为客户机创建各式各样的虚拟设备,如磁盘,网卡,显卡,时钟,USB 等。这些虚拟设备大大降低了客户机的性能。如果客户机不关注这些硬件设备,就可以用统一的虚拟设备代替他们,这样可以大大提高虚拟机的性能。这个统一的标 准化接口在 Linux 上就是 VirtIO 。需要注意的是 VirtIO 运行在 kernel 2.6.24 以上的版本中才能发挥它的性能优势。另外 KVM 项目组也发布了 Windows 平台上的 VirtIO 驱动,这样 windows 客户机的网络性能也可以大大提高了。
本文介绍了在装有 SLES11 的 IBM System x 服务器上安装 KVM 虚拟机的方法。并且初步尝试了如何提高虚拟机的性能。 KVM 虚拟机同其他虚拟技术相比,如 Xen,VMware,VirtualBox 相比,结构更加精简、代码量更小,占用内存很少,与内核集成,性能更胜一筹。
KVM 是一个全虚拟化的解决方案。可以在 x86 架构的计算机上实现虚拟化功能。但 KVM 需要 CPU 中虚拟化功能的支持,只可在具有虚拟化支持的 CPU 上运行,即具有 VT 功能的 Intel CPU 和具有 AMD-V 功能的 AMD CPU 。