KVM浅析&基于Qemu创建Guest OS的测试

来源:互联网 发布:c递归算法经典实例 编辑:程序博客网 时间:2024/06/06 08:36

《KVM虚拟化技术:实战与原理解析》作者写作过程草稿连载http://smilejay.com/kvm_theory_practice/
KVM简介
与xen开发了一套从VCPU调度到内存管理一应俱全的底层操作系统不同,Kernel-Based Virtual Machine是基于kernel的虚拟机,完全利用Linux内核来实现CPU的调度,内存管理的功能。KVM只能运行在支持硬件虚拟化的CPU上。
这里写图片描述
KVM核心层仅有3个内核模块:kvm,kvm_intel和kvm_amd(分别对应Intel和AMD的CPU);kvm驱动负责创建虚拟机,为vcpu注入中断和提供时钟信号,使用KVM的io_ctl接口可以管理vcpu和vm。
KVM开发者选择了已经成型的开源虚拟化软件QEMU作为用户层管理Guest OS的接口。Qemu实现了I/O设备模拟,提供访问外设的途径。这种架构使得KVM避免了繁琐的设备模拟和设备驱动(内核中80%以上的代码就是驱动部分)。QEMU除了是一款虚拟化软件以外还是一款仿真器,它可以模拟多种不同的CPU和平台,例如x86,Power PC,S390 guest(IBM的一种大型机)经由kqemu这个开源的加速器,QEMU能模拟至接近真实电脑的速度。

KVM架构
使用modprobe命令装载KVM模块后,Linux内核就成为了一个hypervisor,并且在Linux原有的Kernel mode和User mode的基础上,新增加了Guest mode,Guest mode拥有自己的Kernel mode和User mode。在KVM模型中,每一个Gust OS都是作为一个标准的Linux进程,都可以使用Linux进程管理命令管理。在虚拟机运行时,三种模式的工作各为:

  • Guest mode: 执行非I/O的客户代码, Virtual Machine运行在这个模式下;
  • User mode:代表用户执行I/O指令,Qemu运行在这个模式下;
  • Kernel mode:实现Guest mode的切换,处理因为I/O或者其他指令引起的从客户模式退出(VM_EXIT)的指令;kvm模块工作在这个模式下。

这里写图片描述
KVM 工作原理
User mode Qemu利用libkvm通过ioctl进入Kernel mode,kvm模块为Guest OS创建Virtual Memory,VCPU,然后执行VMLAUCH指令进入Guest mode,加载Guest OS并执行。如果Guest OS发生外部中断或者影子页表缺页之类的情况,会暂停Guest OS的执行,退出Guest mode进行异常处理,之后重新进入Guest mode,执行客户代码。如果发生I/O事件或者信号队列中有信号到达,就会进入User mode 处理。
这里写图片描述
libvirt
libvirt是为了安全高效的管理节点上的各个域,而提供一个公共的稳定的软件层。它是目前使用最为广泛的对KVM虚拟机进行管理的工具和应用程序接口(API),而且一些常用的虚拟机管理工具(如virsh、virt-install、virt-manager等)和云计算框架平台(如OpenStack、OpenNebula、Eucalyptus等)都在底层使用libvirt的应用程序接口。

libvirt对多种不同的Hypervisor的支持是通过一种基于驱动程序的架构来实现的。libvirt对不同的Hypervisor提供了不同的驱动:对Xen有Xen的驱动,对QEMU/KVM有QEMU驱动,对VMware有VMware驱动。

libvirt作为中间适配层,让底层Hypervisor对上层用户空间的管理工具是可以做到完全透明的,因为libvirt屏蔽了底层各种Hypervisor的细节,为上层管理工具提供了一个统一的、较稳定的接口(API)。通过libvirt,一些用户空间管理工具可以管理各种不同的Hypervisor和上面运行的客户机,它们之间基本的交互框架如下图所示。
这里写图片描述
在libvirt中涉及到几个重要的概念,解释如下:

  • Node:一个物理机器,上面可能运行着多个虚拟客户机。Hypervisor和Domain都运行在Node之上。
  • Hypervisor:也称虚拟机监控器(VMM),如KVM、Xen、VMware、Hyper-V等,是虚拟化中的一个底层软件层,它可以虚拟化一个节点让其运行多个虚拟客户机(不同客户机可能有不同的配置和操作系统)。
  • Domain:是在Hypervisor上运行的一个客户机操作系统实例。域也被称为实例(instance,如亚马逊的AWS云计算服务中客户机就被称为实例)、客户机操作系统(Guest OS)、虚拟机(virtual machine),它们都是指同一个概念。

这里写图片描述
KVM管理工具有两组libvirt和Qemu
这里写图片描述
virtio
http://www.ibm.com/developerworks/cn/linux/1402_caobb_virtio/
Virtio是对半虚拟化hypervisor中的一组通用模拟设备的抽象,virtio由Rusty Russell 开发,他当时的目的是支持自己的虚拟化解决方案 Lguest。Virtio该设置还允许hypervisor导出一组通用的模拟设备,并通过一个通用API让它们变得可用。有了半虚拟化hypervisor之后,Guest OS能够实现一组通用的接口,在一组后端驱动程序之后采用特定的设备模拟。后端驱动程序不需要是通用的,因为它们只实现前端所需的行为。
这里写图片描述
下面基于VMware上CentOS6.4_X86_64安装KVM软件包组,并是否可以启动测试一个微型Linux系统
安装KVM,KVM是第一个整合到Linux主线内核的虚拟化技术(从2.6.20开始),红帽收购了KVM,旗下的虚拟化业务也由XEN向KVM转移。
KVM使用了QEMU的一部分,并稍加改造,就成了可控制KVM的用户空间工具了。所以官方提供的KVM下载有两大部分(qemu和kvm)三个文件(KVM模块、QEMU工具以及二者的合集)。

[root@DQ ~]# yum groupinstall " Virtualization"   "Virtualization Client" " Virtualization Platform"

libvirtd 是一个作为 libvirt 虚拟化管理系统中的服务器端的守护程序,如果要让某个节点能够用 libvirt 进行管理(无论是本地还是远程管理),都需要在这个节点上运行着 libvirtd 这个守护进程,以便让其他上层管理工具可以连接到该节点,libvirtd 负责执行其他管理工具发送它的虚拟化管理操作指令。而 libvirt 的客户端工具(包括virsh、virt-manager等)可以连接到本地或远程的 libvirtd 进程,以便管理节点上的客户机(启动、关闭、重启、迁移等)、收集节点上的宿主机和客户机的配置和资源使用状态。

[root@DQ ~]# service libvirtd start   [root@DQ ~]# chkconfig libvirtd on              

使用virt-install创建虚拟机并安装GuestOS
virt-install是一个命令行工具,它能够为KVM、Xen或其它支持libvrit API的hypervisor创建虚拟机并完成GuestOS安装;此外,它能够基于串行控制台、VNC或SDL支持文本或图形安装界面。安装过程可以使用本地的安装介质如CDROM,也可以通过网络方式如NFS、HTTP或FTP服务实现。对于通过网络安装的方式,virt-install可以自动加载必要的文件以启动安装过程而无须额外提供引导工具。当然,virt-install也支持PXE方式的安装过程,也能够直接使用现有的磁盘映像直接启动安装过程。

virt-install命令有许多选项,这些选项大体可分为下面几大类,同时对每类中的常用选项也做出简单说明。
一般选项:指定虚拟机的名称、内存大小、VCPU个数及特性等;

  • -n NAME, –name=NAME:虚拟机名称,需全局惟一;
  • -r MEMORY, –ram=MEMORY:虚拟机内在大小,单位为MB;
  • –vcpus=VCPUS[,maxvcpus=MAX][,sockets=#][,cores=#[,threads=#]:VCPU个数及相关配置;
  • –cpu=CPU:CPU模式及特性,如coreduo等;可以使用qemu-kvm
  • -cpu ?来获取支持的CPU模式;

安装方法:指定安装方法、GuestOS类型等;

  • -c CDROM, –cdrom=CDROM:光盘安装介质;
  • -l LOCATION, –location=LOCATION:安装源URL,支持FTP、HTTP及NFS等,如ftp://172.16.0.1/pub;
  • –pxe:基于PXE完成安装;
  • –livecd: 把光盘当作LiveCD;
  • –os-type=DISTRO_TYPE:操作系统类型,如linux、unix或windows等;
  • –os-variant=DISTRO_VARIANT:某类型操作系统的变体,如rhel5、fedora8等;
  • -x EXTRA, –extra-args=EXTRA:根据–location指定的方式安装GuestOS时,用于传递给内核的额外选项,例如指定kickstart文件的位置,–extra-args “ks=http://172.16.0.1/class.cfg”
  • –boot=BOOTOPTS:指定安装过程完成后的配置选项,如指定引导设备次序、使用指定的而非安装的kernel/initrd来引导系统启动等;
    例如:
  • –boot cdrom,hd,network:指定引导次序;
  • –bootkernel=KERNEL,initrd=INITRD,kernel_args=”console=/dev/ttyS0”:指定启动系统的内核及initrd文件;

存储配置:指定存储类型、位置及属性等;
–disk=DISKOPTS:指定存储设备及其属性;
格式为–disk /some/storage/path,opt1=val1,opt2=val2等;常用的选项有:

  • device:设备类型,如cdrom、disk或floppy等,默认为disk;
  • bus:磁盘总结类型,其值可以为ide、scsi、usb、virtio或xen;
  • perms:访问权限,如rw、ro或sh(共享的可读写),默认为rw;
  • size:新建磁盘映像的大小,单位为GB;
  • cache:缓存模型,其值有none、writethrouth(缓存读)及writeback(缓存读写);
  • format:磁盘映像格式,如raw、qcow2、vmdk等;
  • sparse:磁盘映像使用稀疏格式,即不立即分配指定大小的空间;
  • –nodisks:不使用本地磁盘,在LiveCD模式中常用;

网络配置:指定网络接口的网络类型及接口属性如MAC地址、驱动模式等;
-w NETWORK, –network=NETWORK,opt1=val1,opt2=val2
将虚拟机连入宿主机的网络中,其中NETWORK可以为:

  • bridge=BRIDGE:连接至名为“BRIDEG”的桥设备;
  • network=NAME:连接至名为“NAME”的网络;

其它常用的选项还有:

  • model:GuestOS中看到的网络设备型号,如e1000、rtl8139或virtio等;
  • mac:固定的MAC地址;省略此选项时将使用随机地址,但无论何种方式,对于KVM来说,其前三段必须为52:54:00;
  • –nonetworks:虚拟机不使用网络功能;

图形配置:定义虚拟机显示功能相关的配置,如VNC相关配置;

  • –graphics TYPE,opt1=val1,opt2=val2:指定图形显示相关的配置,此选项不会配置任何显示硬件(如显卡),而是仅指定虚拟机启动后对其进行访问的接口;
  • TYPE:指定显示类型,可以为vnc、sdl、spice或none等,默认为vnc;
  • port:TYPE为vnc或spice时其监听的端口;
  • listen:TYPE为vnc或spice时所监听的IP地址,默认为127.0.0.1,可以通过修改/etc/libvirt/qemu.conf定义新的默认值;
  • password:TYPE为vnc或spice时,为远程访问监听的服务进指定认证密码;
  • –noautoconsole:禁止自动连接至虚拟机的控制台;

设备选项:指定文本控制台、声音设备、串行接口、并行接口、显示接口等;

  • –serial=CHAROPTS:附加一个串行设备至当前虚拟机,根据设备类型的不同,可以使用不同的选项,格式为“–serialtype,opt1=val1,opt2=val2,…”,例如:
    –serial pty:创建伪终端;
    –serial dev,path=HOSTPATH:附加主机设备至此虚拟机;
    –video=VIDEO:指定显卡设备模型,可用取值为cirrus、vga、qxl或vmvga;

虚拟化平台:虚拟化模型(hvm或paravirt)、模拟的CPU平台类型、模拟的主机类型、hypervisor类型(如kvm、xen或qemu等)以及当前虚拟机的UUID等;

  • -v, –hvm:当物理机同时支持完全虚拟化和半虚拟化时,指定使用完全虚拟化;
  • -p, –paravirt:指定使用半虚拟化;
  • –virt-type:使用的hypervisor,如kvm、qemu、xen等;所有可用值可以使用’virsh capabilities’命令获取;
    这里写图片描述
    这里写图片描述

其它:

  • –autostart:指定虚拟机是否在物理启动后自动启动;
  • –print-xml:如果虚拟机不需要安装过程(–import、–boot),则显示生成的XML而不是创建此虚拟机;默认情况下,此选项仍会创建磁盘映像;
  • –force:禁止命令进入交互式模式,如果有需要回答yes或no选项,则自动回答为yes;
  • –dry-run:执行创建虚拟机的整个过程,但不真正创建虚拟机、改变主机上的设备配置信息及将其创建的需求通知给libvirt;
  • -d, –debug:显示debug信息;

尽管virt-install命令有着类似上述的众多选项,但实际使用中,其必须提供的选项仅包括–name、–ram、–disk(也可是–nodisks)及安装过程相关的选项。此外,有时还需要使用括–connect=CONNCT选项来指定连接至一个非默认的hypervisor。

virsh uri:查看当前主机上hypervisor的连接路径;可以使用virsh connect命令连接
这里写图片描述
下面这个示例创建一个名为self-made的虚拟机,因为实验环境在VMware中,没有硬件支持,所以指定hypervisor为qemu,内存大小为512MB,磁盘为80G的映像文件/var/lib/libvirt/images/selfmade.img,通过boot.iso光盘镜像来引导启动安装过程。
说明:boot.iso是我之前基于rhel5.4制作的,功能没有完全,在VMware上直接引导启动时可以进行到Loading achi driver这一步,而后镜像在使用过程中会断开连接
这里写图片描述
单击虚拟机界面右下角光盘的图标,选择连接,然后返回安装界面点OK,进行安装又会自动断开连接,目前还不知道是哪里出错
这里写图片描述
下面先用这个不完整的boot.iso做测试,看kvm是否可以启动
这里写图片描述
在上述步骤中敲下Enter键,引导止步于
Loading vmlinuz…………………………..
Loading initrd.img…………………………………………………
Ready.
执行以下命令可以发现self-made已经运行
这里写图片描述
下面创建虚拟磁盘文件,而后格式化挂载分别作为Guest OS的/boot和/,制作一个微型Linux系统测试kvm能否启动
这里写图片描述
这里写图片描述

[root@DQ ~]# mkfs.ext4 /dev/mapper/loop0p1[root@DQ ~]# mkfs.ext4 /dev/mapper/loop0p2

安装grub,为其提供vmliuz和initramfs.img,grub安装时没有模拟出来BIOS设备
这里写图片描述
将/sbin/init的任务精简,复制二进制程序运行依赖的系统库文件到虚拟磁盘映像文件挂载点/mnt中对应的路径下;提供/sbin/init运行需要的配置文件rcS.conf以及配置文件依赖于的脚本/etc/rc.d/rc.sysinit
这里写图片描述
安装一个名为CentOS6.4的虚拟机,直接导入
这里写图片描述
由上图可知测试止步于Booting……(从磁盘引导)可能由于实验环境是在VMware中,强行基于Qemu创建虚拟机对于kvm来说可能有些难度,目前我还不是太清楚
virsh define: 创建一个虚拟机,根据事先定义的xml格式的配置文件;创建以后不会自动启动;
virsh create: 创建一个虚拟机,创建完成后会自动启动;
virsh undefine: 删除一个虚拟机
这里写图片描述
每个虚拟机创建后,其配置信息保存在/etc/libvirt/qemu目录中,文件名与虚拟机相同,格式为XML
这里写图片描述

下面的示例将创建一个名为rhel6的虚拟机,其有两个虚拟CPU,安装方法为FTP,并指定了ks文件的位置,磁盘映像文件为稀疏格式,连接至物理主机上的名为brnet0的桥接网络:

# virt-install \    --connect qemu:///system \    --virt-type kvm \    --name rhel6 \    --ram 1024 \    --vcpus 2 \    --network bridge=brnet0 \    --disk path=/VMs/images/rhel6.img,size=120,sparse \    --location ftp://172.16.0.1/rhel6/dvd \    --extra_args “ks=http://172.16.0.1/rhel6.cfg” \    --os-variant rhel6 \    --force 

下面的示例将创建一个名为rhel5.8的虚拟机,磁盘映像文件为稀疏模式的格式为qcow2且总线类型为virtio,安装过程不启动图形界面(–nographics),但会启动一个串行终端将安装过程以字符形式显示在当前文本模式下,虚拟机显卡类型为cirrus:

# virt-install \--connect qemu:///system \--virt-type kvm \ --name rhel5.8 \ --vcpus 2,maxvcpus=4 \--ram 512 \ --disk path=/VMs/images/rhel5.8.img,size=120,format=qcow2,bus=virtio,sparse \ --network bridge=brnet0,model=virtio--nographics \--location ftp://172.16.0.1/pub \ --extra-args "ks=http://172.16.0.1/class.cfg  console=ttyS0  serial" \--os-variant rhel5 \--force  \--video=cirrus

下面的示例则利用已经存在的磁盘映像文件(已经有安装好的系统)创建一个名为rhel5.8的虚拟机:

# virt-install \    --name rhel5.8    --ram 512    --disk /VMs/rhel5.8.img    --import
0 0
原创粉丝点击