首页 > 代码库 > 云计算之虚拟化技术详解—Xen虚拟化实战
云计算之虚拟化技术详解—Xen虚拟化实战
一、虚拟化的概述
虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机。在一台计算机上同时运行多个逻辑计算机,计算元件在虚拟的基础上而不是真实的基础上运行,是一个为了简化管理,优化资源的解决方案。如同空旷、通透的写字楼,整个楼层没有固定的墙壁,用户可以用同样的成本构建出更加自主适用的办公空间,进而节省成本,发挥空间最大利用率。这种把有限的固定的资源根据不同需求进行重新规划以达到最大利用率的思路,在IT领域就叫做虚拟化技术。
虚拟化技术可以扩大硬件的容量,简化软件的重新配置过程。CPU的虚拟化技术可以单CPU模拟多CPU并行,允许一个平台同时运行多个操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率。
二、CPU虚拟化模型
在windows/linux系统上安装虚拟机软件,模拟主机。
VMM与其他进程一起运行在Kernel上,而Guest os运行在VMM上VMM为guest os模拟真实CPU硬件环境,,但Guest os却不知道,认为自己直接运行在硬件上,执行普通指令VMM可直接调度到kernel执行,当需要执行特权指令时如申请内存,或者读写磁盘等操作,则由VMM通过BT技术做指令转换代向kernel申请。
半虚拟化(需要修改guest os内核,只限于可以修改内核的os)
不用BT转换,让它们知道自己运行在虚拟化环境中,普通指令可直接发往cpu执行,当需要运行特权指令时,它们通过系统调用去调用VMM:hypervisor 提供的Hypercall来实现。
硬件虚拟化也称完全虚拟化(HVM)
我们都知道cpu工作是分环的分别是ring 0、ring 1、ring 2、ring 3,Cpu硬件虚拟化其实是在cpu内部增加一层环 ring -1,这样VMM运行在ring -1 上,guest os 运行在 ring 0 上,不过特权指令移到了ring -1 上,ring 0 依旧无法执行特权指令,当需要执行特权指令时,还需要发起系统调用。 这样的好处是,直接可以在硬件级别捕获guest os对特权指令的请求,我们不需要通过软件的方式模拟出一个ring 0了,也不需要修改内核就可以让guest os 工作了,性能不但有所提升,也可以支持更多的操作系统了。
Intel VT-X
AMD AMD-V
三、内存虚拟化
传统方式
当guest os 访问内存空间时,首先guest os 内核会将VA转换成PA装载进MMU,然后由VMM实现在MMU中将PA转换成HA,再由VMM在内存中取得数据,返回给PA。这种方式需要在MMU中缓存两次,而每次都会在TLB中缓存,guest os 执行VA到PA转换的结果和VMM执行PA到HA转换的结果缓存至TLB中不会出现问题,但是多个虚拟机将VP到PA转换结果缓存到TLB中时,就会出现问题。 因为,每个虚拟机都有从0开始的地址空间,当另一台虚拟机访问内存时,查TLB由于地址相同命中,返回的数据却是第一台虚拟机的数据,这样就会出现TLB命中错误。 要解决此问题必须每次要清空TLB,这样的话性能就大大降低了。
基于硬件的解决方案
MMU虚拟化 带虚拟机标签的TLB
当guest os 内核在MMU中将地址表装载由VA转换成PA时,VMM就与此同时在影子MMU(又称shadow MMU)中直接将VA转换成HA,这样guest os 就可以直接从内存取数据了,看似guest os 内核的转换,但是返回的结果,不是查询MMU中的结果,而是查询影子MMU中的结果,因此在每一个guest os 装载一个进程表的同时,VMM会装载另外一张表,然后在影子MMU中完成另外一次转换返回真正物理内存的地址,而不是虚拟的连续的,线性地址空间中的地址。即使这样由于TLB是一个key—value缓存,多个虚拟机的VA相同,还是会导致TLB缓存错误的问题。于是有了带虚拟机标签的TLB查询TLB的时候不但要查key在硬件级别还会自动检查虚拟机的标记,如果标记不一致就算key一致也不会返回命中结果。在一些专业级别支持虚拟化的CPU都支持(ring -1 shadow MMU,tagged TLB)
四、I/O虚拟化
完全虚拟化,Guest os本地调用完成封装,交给VMM,VMM再完成封装交给IO。 (封装两次)
半虚拟化,Guest os 直接通过前半段调用后半段驱动,由VMM在本地完成封装交给IO。
IO-through,VMM把网卡分配给Guest-os用。在guest-os上直接安装硬件驱动与硬件交互,IO透传技术需要依赖IOMMU。
IOMMU
物理机启动的时候IO设备控制器要在CPU总线上注册使用IO端口用于与CPU通信,端口范围在0~65530每个设备只有其中一段,就算是透传技术,VMM将网卡分配给guest os 使用,guest os要识别也需要在内部注册IO端口,但是这个IO端口与我们物理机的IO端口不一样,当guest os 通过硬件向外发数据包或者存储数据的时候,通过驱动程序所交互的IO端口最终还要变成硬件的IO端口,因此IOMMU就是完成转换的。
五、认识Xen
Xen是一个开放源代码虚拟机监视器,由剑桥大学开发。它打算在单个计算机上运行多达100个满特征的操作系统。操作系统必须进行显式地修改(“移植”)以在Xen上运行(但是提供对用户应用的兼容性)。这使得Xen无需特殊硬件支持,就能达到高性能的虚拟化,xen官网http://www.xenproject.org/。
半虚拟化
Xen通过一种叫做半虚拟化的技术获得高效能的表现(较少的效能损失, 典型的情况下大约损失 2%, 在最糟的情况下会有 8% 的效能耗损; 与其它使用完全的虚拟化却造成最高到 20% 损耗的其他解决方案形成一个明显的对比),甚至在某些与传统虚拟技术极度不友好的架构上(x86),Xen也有极佳的表现。与那些传统通过软件模拟实现硬件的虚拟机不同,在3.0版本及在Intel VT-X支援前的Xen需要让客户操作系统(guest operating systems)与Xen API进行连接。到目前为止,这样连结已经可以运用在NetBSD, GNU/Linux, FreeBSD和贝尔实验室的Plan 9系统上。在Brainshare 2005会议上,Novell展示了NetWare与 Xen的连通。与Windows XP连通的技术曾在Xen开发初期进行,但微软的协议未能允许它发布。Sun微系统公司也正积极研究Solaris与Xen的连结,使其能在Xen平台上运作。
全虚拟化
Intel对Xen贡献修改以支持其VT-X Vanderpool架构扩展。如果主系统支持Vanderpool或者Pacifica扩展(Intel和AMD对本地支持虚拟化的扩展),这项技术将允许未修改的客作业系统运行在Xen虚拟机中。事实上,那意味著性能的提升,并且你可以在没有进行任何协议不允许的修改的情况下对Windows进行虚拟。
Linux内核2.6.24之后收录Xen运行为domU功能。 Linux-2.6.37之后收录了运行为dom0的功能,在linux-3.0之后收录各种关键驱动及优化。
六、Xen半虚拟化结构图
Xen直接工作在硬件上,而原来的内核作为模块运行在dom0中,Xen负责管理CPU,内存,Xen在启动的时候必须和dom0一起启动,dom0是一个特殊的虚拟机,负责各domU-IO请求的管理,当domU需要请求IO时则通过前半段驱动与dom0的后半段驱动进行交互。
七、Xen网络工作模型
桥接
Peth0是物理机网卡,由Dom0直接驱动,在桥接模式下时,xenbr0关联至Peth0工作为一个虚拟交换机,当报文发进来时,xenbr0可以根据MAC转发至桥接xenbr0上的主机对应的网络接口。 那物理网卡工作成交换机了,dom0本身怎么接受报文? 是这样的,dom0在本地又虚拟了一块网卡,MAC对应为物理网卡的MAC,当目标为dom0的报文发进来时,由xenbr0根据目标MAC转发至自己的虚拟网络接口。
路由模式
此时xenbr0扮演着一个路由器的角色工作在IP层,dom1 eth0将网关指向 Vif0 ,可以通过物理网卡eth0转发至外网,当外部主机回包的时候,没有把网关指向dom0或者没有到dom0 的路由,就回不了包了。
NAT模式
通过iptables做nat地址转换。
伪网络接口(dummy0)
这里可以理解为仅主机模式
伪网桥
只作为一个内部通道,所有连到网桥上的domu 可以互相通信,但是无法跟dom0通信,也无法跟外部通信。
八、在CentOS6.5上安装XenServer
Rpm源:
http://au2.mirror.crc.id.au/pub/el6-dom0/el6/$basearch/
http://au1.mirror.crc.id.au/repo/el6/$basearch/
http://us1.mirror.crc.id.au/repo/el6/$basearch/
http://us2.mirror.crc.id.au/repo/el6/$basearch/
http://us3.mirror.crc.id.au/el6/$basearch/
http://us5.mirror.crc.id.au/repo/el6/$basearch/
http://uk1.mirror.crc.id.au/repo/el6/$basearch/
1、安装支持xen的内核
yum install kernel-xen-3.7.4-1.el6xen.x86_64.rpm kernel-xen-firmware-3.7.4-1.el6xen.x86_64.rpm kernel-xen-release-6-4.noarch.rpm -y
2、安装xen程序
yum install xen-devel-4.1.3-2.el6.x86_64.rpm xen-doc-4.1.3-2.el6.x86_64.rpm xen-4.1.3-2.el6.x86_64.rpm xen-libs-4.1.3-2.el6.x86_64.rpm xen-licenses-4.1.3-2.el6.x86_64.rpm xen-runtime-4.1.3-2.el6.x86_64.rpm xen-hypervisor-4.1.3-2.el6.x86_64.rpm -y
3、修改/etc/grub.conf 文件
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (3.7.4-1.el6xen.x86_64)
root (hd0,0)
kernel /xen.gz dom0_mem=512M cpufreq=xen dom0_max_vcpus=2 dom0_vcpus_pin
module /vmlinuz-3.7.4-1.el6xen.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
module /initramfs-3.7.4-1.el6xen.x86_64.img
title CentOS (2.6.32-431.el6.x86_64)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=/dev/mapper/VolGroup-lv_root rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD rd_LVM_LV=VolGroup/lv_swap SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=VolGroup/lv_root KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
initrd /initramfs-2.6.32-431.el6.x86_64.img
参数详解:
kernel /xen.gz //指定内核
dom0_mem=512M //指定dom0的内存大小
cpufreq=xen //Cpu运行频率由xen控制
dom0_max_vcpus=2 //指定dom0中虚拟cpu的个数
dom0_vcpus_pin //是否把dom0绑定在某个cpu物理核心上
注意禁用NetworkManager和Selinux,然后重启从新内核启动。
验证Xen 是否正常启动
九、创建虚拟机实例
Xm管理命令
使用xm命令需要先启动xend服务。
Service xend start
mx
create 创建并启动一台虚拟机
destroy 强制关闭虚拟机
shutdown 关闭虚拟机
console 控制虚拟机
list 显示当前虚拟机列表
network-attach
network-detach
block-attach
block-detach
delete:删除虚拟机
pause: 暂停
unpause: 从暂停中恢复
suspend: 挂起
resume: 从挂起中恢复;
save: 保存状态至文件中
restore: 从保存状态中恢复
top: 资源使用状态监控
info: 查看主机相关信息,如内存等;
配置xen网络桥接
定义桥接设备xenbr0,并将eth0设备附加其上,过程如下:
cd /etc/sysconfig/network-scripts/
cp ifcfg-eth0 ifcfg-xenbr0 //创建桥接设备文件
原ifcfg-eth0 文件内容:
DEVICE=eth0
HWADDR=00:0C:29:6C:AF:21
TYPE=Ethernet
UUID=e7c5b6ee-6e44-4854-a432-96498106e4c9
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=static
IPADDR=192.168.1.90
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
改为如下内容:
DEVICE=eth0
HWADDR=00:0C:29:6C:AF:21
TYPE=Ethernet
ONBOOT=yes
BRIDGE=xenbr0
NM_CONTROLLED=no
BOOTPROTO=static
Ifcfg-xenbr0配置文件内容如下:
DEVICE=xenbr0
HWADDR=00:0C:29:6C:AF:21
TYPE=Bridge
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=static
IPADDR=192.168.1.90
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
重启网络服务后,执行ifconfig:
1、下载安装光盘中的initrd.img、vmlinuz 文件用于引导。
cd /tmp
wget http://192.168.1.202/rhel6.4/isolinux/initrd.img
wget http://192.168.1.202/rhel6.4/isolinux/vmlinuz
这里注意:必须使用将安装操作系统光盘中的文件,不能使用别的平台版本的光盘中的initrd.img和vmlinuz文件,不然会报错。
2、创建空的虚拟磁盘映像,以之作为新建非特权域的虚拟磁盘文件,此映像文件并不真正占用为其指定的空间,而是随着存储的内容而变化。
dd if=/dev/zero of=/home/test1_disk.img oflag=direct seek=10000 count=1 bs=1M
3、创建一个虚拟机配置文件,用于启动虚拟机。vim /etc/xen/test1
name=‘test1‘ //虚拟机名称
memory=512 //内存大小(单位M)
ramdisk=‘/tmp/initrd.img‘ //用于系统启动的迷你根
kernel=‘/tmp/vmlinuz‘ //内核
disk=[ ‘file:/home/test1disk.img,xvda,w‘ ] //指定本地的磁盘镜像文件,虚拟机磁盘的设备名称,模式 w代表可读写;
root="/dev/xvda1 ro" //指定根文件系统
vif=[ ‘bridge=xenbr0‘ ] //网卡配置,桥接到xenbr0;
vcpus=2 //虚拟2个cpu
extra="ip=192.168.1.12 netmask=255.255.255.0 gateway=192.168.1.1 ks=http://192.168.1.202/ks.cfg kedevice=eth0" //给内核额外传递的参数
on_reboot="destroy" //定义动作,当收到reboot指令时,执行destroy(关机)动作,这里设置成关机是因为首次安装操作系统,之后要关机修改配置文件。
on_crash="destroy"
4、启动虚拟机
xm create test1
xm console test1
30分钟之后
修改虚拟机配置文件/etc/xen/test1
name=‘test1‘
memory=512
#ramdisk=‘/tmp/initrd.img‘
#kernel=‘/tmp/vmlinuz‘
disk=[ ‘file:/home/test1disk.img,xvda,w‘ ]
#root="/dev/xvda1 ro"
vif=[ ‘bridge=xenbr0‘ ]
vcpus=2
extra="rhgb quiet selinux=0 /sbin/init 3"
bootloader="/usr/bin/pygrub" //使用虚拟机自身内核启动,当然也可以在kernel定义外部的内核。
on_reboot="restart"
on_crash="destroy"
将test1加入到xen管理,启动test1。
xm new test1
xm start test1
Xm console test1
再创建一个test2虚拟机
创建配置文件 vim test2
name=‘test2‘
memory=512
#ramdisk=‘/tmp/initrd.img‘
#kernel=‘/tmp/vmlinuz‘
disk=[ ‘file:/home/test2disk.img,xvda,w‘ ]
#root="/dev/xvda1 ro"
vif=[ ‘bridge=xenbr0‘ ]
vcpus=2
extra="rhgb quiet selinux=0 /sbin/init 3"
bootloader="/usr/bin/pygrub"
on_reboot="restart"
on_crash="destroy"
vfb=[ ‘vnc=1,vnclisten=0.0.0.0‘ ] //加入虚拟帧缓冲,配置VNC服务;
复制磁盘镜像文件
cp /home/test1disk.img /home/test2disk.img
启动test2虚拟机
xm create test2
这时候你会发现xen会开启5900端口,用于响应vnc服务的连接。
通过VNC服务连接test1
vncviewer 192.168.1.90:5900
通过VNC服务连接test2
vncviewer 192.168.1.90:5901
怎么样很简单吧!
十、最后在总结一个细节问题,和一个技巧:
细节问题:
如果提供安装镜像的服务器网段地址改变,除了要修改虚拟机配置文件中,给内核穿的参数和ks文件镜像服务器地址以外,还需要在ks文件中修改网卡的配置,我们在安装操作系统时给内核传参数里面的ip地址是网卡的第一次配置,为了得到ks文件,得到ks文件后,ks还会给网卡做一次配置。 笔者没注意这点,排除弄了很久。
技巧:
如果不愿意自己写配置文件、创建磁盘镜像、然后安装系统,这种方式创建虚拟机。 我们可以下载模版,直接修改下就能启动。 模版提供地址:www.jailtime.org
本篇结束,大家多多指点。
本文出自 “坏人的博客” 博客,转载请与作者联系!
云计算之虚拟化技术详解—Xen虚拟化实战