1. 前言
在计算机技术中,虚拟化(Virtualization)是一种资源管理技术,它将计算机相关的各种资源(CPU、内存、磁盘、网络适配器等)进行抽象、转换后重新分配使用,大大增加了使用的灵活性。虚拟化有很多类别,包括硬件虚拟化、操作系统级虚拟化、应用虚拟化、服务虚拟化等。本文中所讨论的虚拟化环境指硬件虚拟化环境,即通过使用虚拟机监视器(Virtual Machine Monitor),隐藏底层硬件信息,虚拟出通用的计算环境(即虚拟机)。虚拟机中运行的操作系统称为客户机操作系统(Guest OS),虚拟机监视器(Virtual Machine Monitor)所在的操作系统成为宿主机操作系统(Host OS)。
当前硬件虚拟化技术有很多实现,包括VMware ESXi、XEN、QEMU/KVM、Microsoft Hyper-V、VirtualBox等。其中,QEMU/KVM由于KVM代码简洁,复用了Linux Kernel中的CPU和内存调度等功能,进入了Linux Kernel主干,因此最受欢迎。在笔者撰写此文时,AWS刚刚宣布放弃XEN,改用KVM作为其虚拟化引擎。本文在此也主要介绍QEMU/KVM虚拟化环境的搭建。
QEMU(Quick Emulator)是最早由Fabrice Bellard所编写的硬件虚拟化软件,通过对指令进行动态翻译来实现虚拟化;同时,还支持模拟多种设备。尽管QEMU的动态指令翻译已经做得很好了,然而还是不可避免的存在性能损失,而KVM和硬件辅助虚拟化技术解决了该问题。KVM(Kernel-based Virtual Machine)是Linux Kernel中的一个模块,它借助CPU的虚拟化特性,实现客户机和宿主机运行状态的切换。有了KVM,QEMU只需要负责模拟其他硬件,CPU和内存的虚拟化借助KVM即可完成,大大提高了虚拟化的性能。
2. 虚拟化环境安装
2.1 宿主机操作系统安装
灵跃桌面云选用CentOS 7 X86_64位版本作为宿主机操作系统进行安装和部署。从下载其发行版的ISO文件(初学者建议下载Everything ISO,其中包含了所需的所有软件包,省去了安装时联网下载过程)。宿主机操作系统建议安装在硬件(PC或者服务器)之上,若没有硬件环境,可在VMware Workstation中进行安装。在安装过程中“软件选择”时,请勾选“虚拟化主机”中的“虚拟化平台”、“GNOME桌面”中的“GNOME应用程序”与“传统X Windows系统的兼容性”,如图所示:
图 1 宿主机操作系统安装(1)
图 2 宿主机操作系统安装(2)
若在安装过程中没有创建新的系统用户,则在首次进入GNOME图形界面后会要求创建,待创建用户之后,即可开始使用。
2.1.1 QEMU/KVM安装
由于KVM是Linux Kernel的一个模块,因此在系统安装好后,KVM也安装完成;同时,对于KVM的版本号,由于KVM随着Linux Kernel一起发布,所谓KVM的版本就是Linux Kernel的版本。因为前文在系统安装时选择了“虚拟化平台”选项,因此QEMU也已经自动被安装。若读者需要在已有的CentOS系统中安装QEMU,灵跃桌面云建议使用以下命令手动安装(其他不同发行版的Linux操作系统,安装命令会有所不同):
[lingyuecloud@lingyuecloud ~]$ sudo yum install qemu-kvm 要检验是否已经安装QEMU,可以使用rpm命令查询,如下图所示: [lingyuecloud@lingyuecloud ~]$ sudo rpm -qa | grep qemu ipxe-roms-qemu-20170123-1.git4e85b27.el7.noarch libvirt-daemon-driver-qemu-3.2.0-14.el7.x86_64 qemu-img-1.5.3-141.el7.x86_64 qemu-kvm-1.5.3-141.el7.x86_64 qemu-kvm-common-1.5.3-141.el7.x86_64 qemu-guest-agent-2.8.0-2.el7.x86_64
2.1.2 virt-viewer安装
在启动虚拟机之后,可以使用远程桌面连接软件来交付虚拟机桌面。由于QEMU支持基于VNC和Spice的交付方式,这里使用支持上述两种交付模式的virt-viewer包中的remote-viewer程序作为连接的客户端,使用如下命令安装virt-viewer即可。
[lingyuecloud@lingyuecloud ~]$ sudo yum install virt-viewer
3. 创建虚拟机
3.1 镜像准备
灵跃桌面云建议初学者使用现有镜像来创建虚拟机,待熟悉之后再手动制作镜像。现有镜像可以从OpenStack官方网站上下载,推荐下载CirrOS镜像,其是体积非常小的Linux镜像,非常适合用于测试场景。
3.2 启动虚拟机
3.2.1 使用QEMU命令启动虚拟机
通过QEMU启动虚拟机的命令如下:
[lingyuecloud@lingyuecloud ~]$ /usr/libexec/qemu-kvm -hda cirros-0.3.5-x86_64-disk.img -m 256 -boot c -vnc :0 Could not access KVM kernel module: No such file or directory failed to initialize KVM: No such file ordirectory Back to tcg accelerator. 其中,后面三行打印日志是说当前环境下的KVM支持未启用,将采用指令翻译模式运行。针对该问题,若要启用KVM支持,则需要结合宿主主机操作系统所在的环境进行考虑:(1)若宿主机操作系统直接安装在物理硬件之上,则需要在BIOS中设置开启虚拟化支持;(2)若宿主机操作系统安装在VMware Workstation中,需要在VMware环境设置的“处理器设置”选项中勾选“虚拟化 Intel VT-x/EPT 或 AMD-V/RVI(V)”选项。 启动命令中各参数含义如下: ? “/usr/libexec/qemu-kvm”:QEMU二进制可执行文件完整路径; ? “-hdacirros-0.3.5-x86_64-disk.img”:使用下载的cirros镜像作为第1块虚拟硬盘; ? “-m 256”:内存设置为256MB; ? “-boot c”:设置为首先从硬盘启动; ? “-vnc :0”:在端口0(连接的时候使用5900)上开启vnc服务;
虚拟机运行之后,即可使用remote-viewer进行连接。在本地Linux环境下在shell中运行“remote-viewer”命令,然后输入连接地址“vnc://127.0.0.1:5900”即可连接到虚拟机,如图所示:
图 3 使用remote-viewer连接虚拟机(1)
图 4 使用remote-viewer连接虚拟机(2)
若要关闭虚拟机,可在虚拟机窗口中执行关机命令,或在执行QEMU命令的Shell窗口运行“Ctrl+C”命令(注意:此操作结束QEMU命令相当于对PC进行断电操作,会丢失Guest OS中未及时保存的数据)即可。
3.2.2 使用libvirt启动虚拟机
libvirt是为了更方便地管理虚拟化平台而设计的开源应用程序接口、守护进程和管理工具,不仅提供了对虚拟化客户机的管理,也提供了对虚拟化网络和存储的管理。libvirt支持多种底层虚拟化技术,屏蔽了底层细节,使得对虚拟机的管理更加方便。
默认情况下,CentOS并未安装libvirt,读者可使用如下命令进行安装:
[lingyuecloud@lingyuecloud ~]$ sudo yum install libvirt |
安装完成后,可使用如下命令查看libvirt版本。本文撰写时,CentOS官方libvirt已经更新到3.2.0版本。
[lingyuecloud@lingyuecloud ~]$ virsh --version 3.2.0 |
libvirt通过xml文件来对虚拟机的配置进行管理,在启动虚拟机之前,我们首先需要创建一个xml文件,内容如下所示。其中红色的注释,简单解释了xml各个字段的含义。
<domain type=‘kvm‘> <!--这里的’kvm’表示使用kvm加速,也可以填’qemu’,则虚拟机是qemu全模拟的--> <name>lingyuecloud</name> <!--虚拟机名字,用户自己定义--> <os> <type arch=‘x86_64‘ machine=‘pc‘>hvm</type> <!--虚拟机架构以及类型,如果要创建32位虚拟机,这里可以将x86_64改成i686 --> <boot dev=‘hd‘/> <!--此项表示首先从硬盘启动,如果需要首先从CDROM启动,用户可以在前面加上<boot dev=’cdrom’> --> </os> <features> <!--定义一些需要传给虚拟机的VCPU的特性--> <acpi/> <apic/> </features> <memory unit=‘KiB‘>262144</memory> <!--虚拟机内存规格--> <vcpu>1</vcpu> <!--虚拟机VCPU数量--> <clock offset=‘utc‘> <!--设置虚拟机的时钟,不同时钟之间的区别可以参考内核文档Timekeeping Virtualization for X86-Based Architectures --> <timer name=‘pit‘ tickpolicy=‘delay‘/> <timer name=‘rtc‘ tickpolicy=‘catchup‘/> <timer name=‘hpet‘ present=‘no‘/> </clock> <on_poweroff>destroy</on_poweroff> <!--设置虚拟机内部poweroff的时候,libvirt的动作为destroy --> <on_reboot>restart</on_reboot> <!--设置虚拟机内部reboot的时候,libvirt的动作为restart --> <on_crash>destroy</on_crash> <!--设置虚拟机内部crash的时候,libvirt的动作为destroy;此项对debug很有用,debug时设置此项为pause,可以在虚拟机内部crash的时候,libvirt使得虚拟机暂停,此时开发人员可以将虚拟机内存dump出来进行分析 --> <devices> <!-- device标签下都是定义要呈现给虚拟机的各种设备--> <emulator>/usr/libexec/qemu-kvm</emulator> <!-- QEMU二进制文件的完整路径-->
<disk type=‘file‘ device=‘disk‘> <!--定义一块磁盘--> <driver name=‘qemu‘ type=‘qcow2‘ cache=‘none‘/> <!--磁盘类型以及cache设置--> <source file=‘/home/lingyuecloud/cirros-0.3.5-x86_64-disk.img‘/> <target dev=‘vda‘ bus=‘virtio‘/> <!-- vda表示硬盘设备名,或者说盘符,每个硬盘一个,不能重复,后续依次为vdb、vdc等,bus表示设备类型,如果是virtio,系统必须有virtio驱动;若系统没有virtio驱动则可以改成ide类型;--> </disk> <controller type=‘ide‘ index=‘0‘/> <controller type=‘usb‘ index=‘0‘/> <input type=‘tablet‘ bus=‘usb‘/> <!--键盘,此处为USB类型--> <input type=‘mouse‘ bus=‘ps2‘/> <!--鼠标,此处为PS2类型-->
<graphics type=‘vnc‘ port=‘-1‘ autoport=‘yes‘ listen=‘0.0.0.0‘ keymap=‘en-us‘/> <!-- vnc设置,通常port设置为-1,libvirt会自动分配port --> <video> <!--显示设置--> <model type=‘cirrus‘ vram=‘32768‘ heads=‘1‘/> </video> </devices> </domain> |
利用libvirt xml文件,通过virsh命令即可实现对虚拟机的生命周期管理。其中,virsh有两种使用方式:(1)在virsh命令后直接跟相关子命令和参数;(2)在输入virsh命令并敲击回车进入virsh环境后,再输入相关子命令和参数。本文使用virsh后紧跟子命令的用法。
利用virsh创建虚拟机的步骤包括define和start两个步骤。(1)依据创建的虚拟机配置文件,使用“virsh define 虚拟机配置文件.xml”命令定义后的该虚拟机就在libvirt的管理之下了;即使libvirt服务重启或者宿主机系统重启,define过的虚拟机依然存在。define之后虚拟机不会启动;使用“virsh list”命令查看虚拟机列表时,该虚拟机默认不显示,需要加“--all”参数。(2)虚拟机define之后,使用“virsh start 虚拟机名”命令来启动,上述过程如下所示:
[lingyuecloud@lingyuecloud ~]$ virsh define cirros-0.3.5-x86_64-disk.xml 定义域lingyuecloud(从cirros-0.3.5-x86_64-disk.xml)
[lingyuecloud@lingyuecloud ~]$ virsh list Id 名称 状态 ----------------------------------------------------
[lingyuecloud@lingyuecloud ~]$ virsh list --all Id 名称 状态 ---------------------------------------------------- - lingyuecloud 关闭
[lingyuecloud@lingyuecloud ~]$ virsh start lingyuecloud 域lingyuecloud已开始
[lingyuecloud@lingyuecloud ~]$ virsh list Id 名称 状态 ---------------------------------------------------- 1 lingyuecloud running
[lingyuecloud@lingyuecloud ~]$ virsh domdisplay lingyuecloud vnc://localhost:1 |
之后,可使用“virsh domdisplay”命令来查看虚拟机vnc的连接端口,根据返回的端口号,可使用remote-viewer连接地址“vnc://127.0.0.1:5901”即可连接到该虚拟机。
若要关闭虚拟机,可执行“virsh shutdown 虚拟机名”命令(发送关机信号到Guest OS中)或者“virsh destroy 虚拟机名”命令(强制关闭虚拟机,可能造成数据丢失)。其他libvirt命令读者可执行“virsh help”进行查阅。
3.2.3 使用virt-manager启动虚拟机
virt-manager是一个图形化的虚拟机管理工具,相比命令行,virt-manager操作更加直观且不容易出错。CentOS系统默认没有安装virt-manager,用户需要使用以下命令来安装:
[lingyuecloud@lingyuecloud ~]$ sudo yum install virt-manager |
安装完成后,在shell中运行命令“sudo virt-manager”来打开virt-manager的图形界面,然后点击“文件”->“新建虚拟机”即可创建新的虚拟机。创建之前,先将下载的CirrOS镜像复制一份,创建过程中,选择“导入现有磁盘印象(E)”,然后浏览选择到复制的CirrOS镜像,其他选项默认即可,如图所示:
图 5 新建虚拟机(1)
图 6 新建虚拟机(2)
虚拟机运行后,virt-manager会自动连接到虚拟机的控制台,用户可以看到虚拟机启动过程并进行操作。在控制台界面上,点击“查看”->“详情”还可查看和编辑虚拟机的详细配置(部分配置需要关机后才能修改、部分配置编辑后需要重启生效),如图所示:
图 7 编辑虚拟机配置
4. 总结
本文介绍了简易的虚拟化环境的安装搭建以及虚拟机的创建过程。总体上讲,不论是QEMU命令操作、libvirt命令操作还是利用virt-manager图形化管理工具,对虚拟机的管理都略显复杂,尤其涉及到更多功能操作时如网络虚拟化、存储虚拟化、虚拟机连接认证等更是难以管理。针对上述问题,灵跃桌面云建议采用云计算平台管理工具进行统一管理,其更加高效、简洁,相关讨论将持续更新,敬请关注。