虚拟化技术是什么:

  在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部份是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。--转自百度百科


为什么需要虚拟化:
  虚拟化技术在近几年来非常的火热, 实际上在上个世纪60年代, 就已经有了虚拟化的实现。由于计算机的发展遵循了摩尔定律数十年之久。 在二十一世纪初时, 单台计算机的性能已经非常的强大了, 大多数服务器的计算资源都有大量的空闲, 所以虚拟化的技术从重新进入人们的视野。


虚拟化技术主要有以下几个优点:
计算资源能够得到充分的利用
简化物理网络架构, 便于管理
减少基础运维工作频度
易于实现运维自动化、平台化

什么时候会使用虚拟化:
  虚拟化无处不在,每天都听到的云计算就是以虚拟化技术为基础。阿里云、腾讯云等众多提供云服务、VPS的厂商哪家没有使用虚拟化? 我们使用的虚拟机, VMWare Wokstation, VirtualBox, VMWare ESXI… 也都是虚拟化。甚至于很多学校、公司使用的云桌面, 也都是虚拟化技术实现的。还有现在炙手可热的Docker技术, 也是虚拟化。作为一个运维, 你可以不懂云计算, 大数据, 但是你必须了解虚拟化, 这个无处不在的技术!


虚拟化类型简介

模拟:
在底层的硬件上运行OS, OS上通过虚拟化模拟器软件来模拟一个硬件环境, 可以模拟不同平台的环境, 著名的模拟器: PearPC, Bochs, QEMU

完全虚拟化: (Full Virtualization):
CPU、内存不做模拟, 只对其进行分配和管理, 可通过BT, HVM等技术进行加速, 只能模拟本机CPU; 著名的软件: VMWare Workstation, VirtualBox, KVM…

半虚拟化: (Para Virtualization)
在底层硬件上安装VMM(Virtual Machines Monitor)来管理各虚拟机, 各虚拟机的内核需要修改, 从而知道自己是虚拟机, 通过特殊方式调用驱动和特权指令; 著名的软件: Xen, VMWare ESXI, UML …

OS虚拟化:
每一个虚拟机只有用户空间, 所有的虚拟机共享一个内核, 更加的节省资源, 更接近原生性能; 著名的实现: OpenVZ, Docker, Solaris Containers, FreeBSD jails…

Hypervisor是什么:
Hypervisor意为监视器, 宿主机通过Hypervisor来管理各虚拟机

从另一个角度来解释, 虚拟化技术分为两种类型:
Type-I: Hypervisor运行在硬件上: 如: VMWare ESXI, Xen…
Type-II: Hypervisor运行在OS上: 如: VMWare Workstation, VirtualBox…


Xen的简介
  Xen是一个开源的可直接运行于硬件层之上的虚拟化软件,它可在传统虚拟技术极度不友好的X86架构上也有上佳的表现;它是英国剑桥大学开发的开源虚拟化软件,它的初衷是在一台物理机上运行上百台虚拟机;
  Xen的设计十分精巧,它属于虚拟化type-I ,因为Xen实际是一个简化版的Hypervisor层;相对于Type-II类型的基于Host的虚拟化(如:VMware Workstattion),其性能相对会较好;Xen仅对CPU和Memory直接接管,而其它IO硬件驱动则由其上运行的第一个虚拟机来提供支持.这样做的原因是: Xen无法为众多IO设备开发驱动,而硬件设备的开发商也不会专为Xen提供驱动,因此Xen采用了这样一种特别的设计方式。
  Xen默认认为自己是直接运行于硬件层之上的虚拟化软件,并且可以直接驱动CPU和内存,需注意CPU和内存是所有想要运行的操作系统必须能直接支持的,但Xen为保证自身的小巧,它并没有提供虚拟机的管理接口,因此它采用了一种独特的方式,先运行一台特权虚拟机,且这台VM必须支持Kernel的修改,因此选择开源的Linux做为特权VM是最合适的,这样也可方便采用Linux所支持的方式来开发虚拟机管理接口,实现与Xen Hypervisor层直接交互来完成为VM分配CPU和内存资源及创建、删除、停止、启动VM的管理接口;通常这台特权虚拟机一定会采用当前比较流行的Linux发行版,因为它能支持更多IO硬件设备,如:网卡,磁盘,显卡,声卡等; 到目前为止,NetBSD, GNU/Linux, FreeBSD和Plan 9,OpenSolaris等系统已经支持已半虚拟化方式运行在Xen的DomU中;并且目前Xen已经支持x86,x86_64和ARM等平台,并正在向IA64、PPC移植。移植到其他平台从技术上是可行的,未来有可能会实现。
  Xen虚拟机支持在不停止的情况下在多个物理主机之间实时迁移。在操作过程中,虚拟机在没有停止工作的情况下内存被反复的复制到目标机器。虚拟机在最终目的地开始执行之前,会有一次60-300毫秒的非常短暂的暂停以执行最终的同步化,给人无缝迁移的感觉。类似的技术被用来暂停一台正在运行的虚拟机到磁盘,并切换到另外一台,第一台虚拟机在以后可以恢复。


Xen的大体结构:
Xen的组成分为三部分:
(1)硬件层之上的Xen Hypervisor层:负责直接驱动CPU和Memory这些基础硬件,为其它所有虚拟机提供CPU、内存、Interrupt(中断)管理,并且还提供了HyperCall的调用。
(2)第一个虚拟机: 此虚拟机在Xen中称为特权虚拟机: 它有整个虚拟化环境的访问权,并负责创建用户级虚拟机,并为其分配I/O设备资源.它的Kernel是经过特别修改的VM,它可以直接访问IO硬件也可访问其它用户VM。
(3)其它众多虚拟机: 这些虚拟就是用户级虚拟机: 它们是实际提供给用户使用的虚拟机,也是相关隔离的VM。

虚拟化技术之虚拟化技术介绍及Xen的应用实现_摩尔定律

需要注意:Xen支持三种虚拟化,当然此处的虚拟化特指CPU的半虚拟化或完成虚拟化.
<1> Para-Virtualization(半虚拟化): 在这种虚拟化中,CPU不要求支持HVM特性,
但GuestOS的Kernel必须允许被修改.否则将无法支持该GuestOS运行在DomU中。这是因为必须让GuestOS知道自己是运行在虚拟化环境中,这样它在进行特权指令操作硬件时,会直接发起HyperCall向Xen Hypervisor发起请求来完成所谓的硬件操作。在PV技术下,能够运行在DomU上的OS包括:
Linux, NetBSD, FreeBSD, OpenSolaris

虚拟化技术之虚拟化技术介绍及Xen的应用实现_摩尔定律_02

                                        
<2> HVM(基于硬件的完全虚拟化): 此种虚拟化需要借助于Intel的VT-x 或 AMD的AMD-v 的HVM技术
及Qemu的IO硬件模拟,才能支持GuestOS的kernel不修改,就可直接被DomU支持。
这是因为Xen Hypervisor是运行在CPU的环-1上的,GuestOS的kernel是运行在CPU的环0上,
GuestOS向环0上发起的所有假特权指令调用都由CPU直接捕获,并交由环-1上的Xen Hypervisor处理,最后由Xen代其执行,这样DomU若发起关机指令时,Xen仅会切断该GuestOS的电源,而不会影响其它GuestOS。
在HVM技术下,能够运行在DomU上的OS包括: 所有支持X86架构的OS.

虚拟化技术之虚拟化技术介绍及Xen的应用实现_摩尔定律_03

                                   
<3> PV on HVM: I/O设备半虚拟化运行,CPU运行于HVM模式
此中方式是为了解决HVM方式中IO设备也必须完全模拟而带来的性能低下问题;通过让CPU进行完全虚拟化,而I/O设备则采用在GuestOS中安装相应的IO驱动实现IO的半虚拟化的方式来提高效率。
在PV on HVM的技术下,能够运行在DomU上的OS包括:
只要OS能驱动PV接口类型的IO设备,即可.


Xen对VM的称呼:
Xen对VM统称为Domain.
第一台特权VM,在Xen中通常称为: Domain0,简称为Dom0, 别名: Privileged Domain.
其它后续用户级VM,在Xen中称为: Domain1,Domain2,…., 它们有一个统称为DomU,别名:Unprivileged Domain.

虚拟化技术之虚拟化技术介绍及Xen的应用实现_云计算_04

Xen对CPU和内存的虚拟化过程[注: 关于虚拟化中CPU和内存的虚拟化在附件加入了一些补充]:
Xen在给VM提供CPU的虚拟化时,它采用的也是在Xen hypervisor层启动一个线程,并将这些线程映射到某个物理核心上,
当然通过DomU的配置文件中的cpus可以指定将这些模拟CPU的线程绑定到某几个物理核心上;而内存的虚拟化
则是内存页的映射,将物理内存上多个连续或不连续的内存页映射给VM,让VM看来这就是一个完整的连续的内存空间.


Xen对IO设备的虚拟化过程:
当启动一个用户VM(DomU)时, 该VM所需的CPU和内存都有Xen Hypervisor提供,而它若需要使用IO设备时,则向特权VM
发起请求,特权VM(Dom0)会为该用户VM创建一个模拟的硬件设备线程,并运行于特权VM的用户空间,当用户VM向该IO硬件
发起调用时,特权VM上相应的模拟设备接收请求并将其转化为特权VM对IO硬件的操作,交给特权VM的内核来代为
完成其操作。这里需注意这些虚拟IO硬件需要由Qemu来模拟,Xen本身并没有提供相应的模拟功能。
(注:特权VM的CPU和内存也是有Xen Hypervisor提供.)
 
Qemu模拟IO设备(完全虚拟化方式): 假如用户VM向特权VM请求磁盘,特权VM可以将一个分区、文件等,
通过Qemu将其模拟成一个磁盘设备,就拿文件来说,特权VM先创建一个映像文件,再通过Qemu为该文件模拟一个磁盘控制器芯片,然后,将其映射到用户VM上,当然模拟的这个磁盘控制器芯片一定是一个最常见的,用户VM的Kernel一定支持的,但需注意: 模拟的磁盘可能会与实际的物理磁盘不同,因为要尽可能兼容。这样一来用户VM假如要写数据到磁盘的过程如下:
用户VM-APP—>用户VM-Kernel调用虚拟磁盘的驱动进行写数据前的准备
(如:数据写入到磁盘中的扇区位置/数据编码等)—>
用户VM-Kernel将编码后的信息发给特权VM的模拟磁盘进程—>
特权VM的模拟磁盘进程再将编号信息还原后发给特权VM-kernel—>
特权VM-kernel调用真实物理磁盘的驱动对数据进行写前准备—>最后磁盘驱动调度磁盘完成写入.
Xen向Domain提供了一个抽象层,其中包含了管理和虚拟硬件的API。Domain 0内部包含了真实的设备驱动(原生设备驱动),可直接访问物理硬件,Xen 提供的管理 API 可与其交互,并通过用户模式下的管理工具(如:xm/xend、xl等)来管理 Xen 的虚拟机环境。

虚拟化技术之虚拟化技术介绍及Xen的应用实现_摩尔定律_05


半虚拟化的IO设备:它与模拟最大不同是DomU知道自己是运行在虚拟化环境中的,并且知道这个磁盘不是真正的磁盘
它只是Xen模拟的一个磁盘前端驱动(Disk Frontend),它要写数据时,直接将数据交给Disk Frontend,而不再去调用磁盘
驱动进行数据编码,当特权VM端的Disk backend收到来自DomU的数据时,也是直接转给特权VM-Kernel,由其直接调用
物理磁盘驱动来对这些原始数据进行处理并写入磁盘。

补充:
Xen2.0之后,引入了分离设备驱动模式。该模式在每个用户域中建立前端(front end)设备,在特权域(Dom0)中建立后端(back end)设备。所有的用户域操作系统像使用普通设备一样向前端设备发送请求,而前端设备通过IO请求描述符(IO descripror ring)和设备通道(device channel)将这些请求以及用户域的身份信息发送到处于特权域中的后端设备。这种体系将控制信息传递和数据传递分开处理。
半虚拟化客户机(Domain U PV)的PV Block Driver接收到要向本地磁盘写入数据的请求,然后通过Xen Hypervisor将自己与Domain 0共享的本地内存中的数据写入到本地磁盘中。在Domain 0 和半虚拟化Domain U之间存在事件通道(我的理解:Device Channel包含Event Channel),这个通道允许它们之间通过存在于Xen Hypervisor内的异步中断来进行通信。Domain 0将会接收到一个来自于Xen Hypervisor的系统中断,并触发Domain 0中的Block Backend驱动程序去访问本地系统内容,并从自己与半虚拟化客户机的共享内存中读取适合的数据块后,随即被写入到本地磁盘的指定位置中。


虚拟化技术之虚拟化技术介绍及Xen的应用实现_云计算_06


但无论采用模拟或半虚拟化最终都是对物理磁盘的操作,假如当前只有一个物理磁盘,众多用户VM都在进行大量的读写请求,此时,为了避免用户VM无限制的向特权VM发起请求,特权VM中采用一个环状缓存区,每到一个IO请求,就先将其塞入这个环状缓冲区的槽位中,若缓冲区满了,就会告诉用户VM IO设备繁忙。当然其它各种IO设备大致都采用这种机制来控制。


如何获取xen:

在RHEL5中, Xen是默认的虚拟化方案, 在RHEL6以后使用KVM来代替Xen


Xen对Linux内核的要求:

Linux 2.6.37之后才原生支持Xen, Linux 3.0后才针对Xen进行关键优化

获取Xen4 Centos:

Xen4centos项目提供了众多rpm来实现、并支持rhel6/Centos6运行Xen
# yum install http://au1.mirror.crc.id.au/repo/kernel-xen-release-latest.noarch.rpm  自动产生Xen yum源配置文件

安装xen:

# yum -y install xen45
# yum -y install kernel-xen

修改grub
因为安装xen会自动安装linux 3.X的内核, 我们还需要对其进行一些修改, 使得使用xen进行启动:

# vim /etc/grub.conf
default=0
timeout=5
splashp_w_picpath=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (4.4.33-1.el6xen.x86_64)
    root (hd0,0)
    kernel /xen.gz dom0_mem=1024M cpufreq=xen dom0_max_vcpus=1 dom0_vcpus_pin --自动添加Dom0内核引导title
    module /vmlinuz-4.4.33-1.el6xen.x86_64 ro root=/dev/mapper/vg0-root rd_NO_LUKS rd_NO_DM LANG=en_US.UTF-8 rd_LVM_LV=vg0/swap rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=vg0/root  KEYBOARDTYPE=pc KEYTABLE=us rhgb crashkernel=auto quiet rhgb quiet
    module /initramfs-4.4.33-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/vg0-root rd_NO_LUKS rd_NO_DM LANG=en_US.UTF-8 rd_LVM_LV=vg0/swap rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=vg0/root  KEYBOARDTYPE=pc KEYTABLE=us rhgb crashkernel=auto quiet rhgb quiet
    initrd /initramfs-2.6.32-431.el6.x86_64.img

注: kernel 必须指定xen*.gz为启动的内核, dom0_mem:设定Dom0启动后可以使用的内存大小,
cpufreq: 设定由Xen来管理CPU,  dom0_max_vcpus: 设定Dom0可以使用多少颗CPU,
dom0_vcpus_pin: 将Dom0固定在系统启动后,分配给它的CPU上,以避免它去抢占其它物理CPU核心,
这样其它物理核心就可以分配给DomU来使用了。


重启系统:

# reboot  --选择刚添加grub.conf Dom0的title,此时本机已为Hpervisor+Dom0

检查xen环境状态

# xl list
Name                                        ID   Mem VCPUs    State    Time(s)
Domain-0                                     0  1024     1     r-----      12.5
# xl info
host                   : node1.samlee.com
release                : 4.4.33-1.el6xen.x86_64


实践案例:创建一台cirros虚拟机:
(1)下载Cirros: http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img

# wget http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img

(2)创建虚拟磁盘p_w_picpath存储目录

# mkdir -pv /p_w_picpaths/xen/vm1
# cp cirros-0.3.4-x86_64-disk.img /p_w_picpaths/xen/vm1/cirros.img

(3)创建Xen DomU的启动配置文件:

# cp /etc/xen/xlexample.pvlinux /etc/xen/cirros
# 修改cirros后配置如下:
# grep -Ev '^$|^#'   /etc/xen/cirros 
name = "cirros-001"
bootloader="pygrub"
memory = 512
vcpus = 2
vif = [ 'bridge=xenbr0' ]
disk = [ '/p_w_picpaths/xen/vm1/cirros.img,qcow2,xvda,rw' ]

(4)创建桥接口
#注: 在创建桥接口前,需要先注意禁止NetworkManager服务启动.
# service  NetworkManager  stop  &&  chkconfig  NetworkManager  off
#桥接口的作用:
#DomU启动后,它若需要与Dom0或外网通信就需要通过Dom0来实现,而Dom0实现的方式就是
# 创建桥接口,桥接后,系统会将Dom0的物理网卡模拟成一个二层交换机,然后,创建一个虚接口代替
# ethX, 这样当物理网卡收到目的MAC是自己的数据包时,就转发到虚接口上.若不是则转发给后端DomU.

# cat /etc/sysconfig/network-scripts/{ifcfg-eth0,ifcfg-xenbr0}
DEVICE=eth0
BOOTPROTO=none
NM_CONTROLLED=yes
ONBOOT=yes
TYPE=Ethernet
BRIDGE=xenbr0
IPV6INIT=no
USERCTL=no
DEVICE=xenbr0
TYPE=Bridge
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=none
IPADDR=172.16.100.6
NETMASK=255.255.0.0
GATEWAY=172.16.0.2
DNS1=8.8.8.8
USERCTL=no
DELAY=0

(5)测试启动

# 注:测试启动后,请注意网卡的MAC地址. 由于上面配置文件中没有指定MAC地址,因此每次启动后,
#       其MAC地址会被Xen自动重新分配.
#   -c : 启动的同时进入控制台.
#   -n : 检查配置文件,非真正启动.
# xl create /etc/xen/cirros -c  #启动并登录DomU的终端后,若要退回的Dom0,按: Ctrl+], 
                                # 若退回到Dom0后, Xshell 等连接工具不能正常显示:可输入reset来重置.
# xl list                                
# xl  console  cirros-001  #手动登录cirros的控制台

Xen命令及配置文件使用详解:

Xen启动DomU的配置文件说明
xl list :      #首先需要了解的第一个命令.
xen VM的常见状态:
r: -- running
b: -- block(阻塞)
p: -- pause(暂停): 类似与睡眠.
s: -- stop
c: -- crash(崩溃)
d: -- dying, 正在关闭的过程中.

   
如何创建一个Xen PV模式的VM:

1.Kernel 和 initrd或initramfs :这些Linux Kernel文件必须要有,但可以不在DomU上,它们可以在Dom0上.
2.DomU内核模块(即:/lib/modules/`uname -r`): 这些就需要在DomU根文件系统中存储了。
3.根文件系统
4.swap设备: 若条件充足也可以提供.           
以上四步的内容必须定义在DomU的配置文件中.
注: xl 和 xm启动DomU的配置文件是存在一些不同的.
           
对于xl命令创建VM所需的配置文件说明可查看:
# man  xl.cfg
# 注: man  xl.conf   #这是对xl命令所使用的配置文件.

                   
xl.cfg的配置文件参数说明:

name:域的唯一名.
builder:指明VM的类型,generic:创建PV类型的VM;  HVM:创建HVM类型的VM
vcpus:指定CPU个数.
maxvcpus:指定最大可使用CPU的个数,这些CPU可在需要是手动启动。
cpus: 指定VM的vcpu线程可以运行在哪些物理核心列表上.
#如:cpus="0-3,5,^1"   这表示:VCPU可运行在0,2,3,5上,但不能运行在1上.
#建议将vCPU绑定到固定的物理核心上,这样可减少vCPU线程在多个物理核心上切换.
memory: 指定DomU启动时预分配的内存大小[单位:M]
maxmem: 指定最大给DomU分配的内存大小. [单位:M]
on_poweroff: 指定DomU关机时,实际采用的动作.
destroy: 直接将DomU断电关机.
restart: 重启
rename-restart: 改名后重启
preserve: 将这个DomU保存,以便下次再启动。
coredump-destroy: 将DomU的运行中的内核数据备份出来后,再关机。
coredump-restart: 先备份内核数据,再重启.
on_reboot: 重启DomU时实际采用的动作。
on_crash: 当DomU崩溃后,实际采用的动作。
uuid: DomU的UUID,非必须.
disk: 指定DomU的磁盘列表
        如: disk=[ "/img/disk/DomU1.img" , "/dev/sda3" , …]
vif: 指定DomU的网卡列表
        如: vif=[ "NET_SPEC_STRING" , "NET_SPEC_STRING" , …]
vfb: 指定DomU的显示器, vfb:virtual frame buffer(虚拟帧缓冲)
        如: vfb=[ "VFB_SPEC_STRING" , "VFB_SPEC_STRING" ,…]
pci: 指定DomU的PCI设备列表.
        如:pci=[ "PCI_SPEC_STRING" , "PCI_SPEC_STRING" ,…]


PV模型的专用指令:
 

kernel : 指定内核文件路径,此路径为Dom0的路径.
ramdisk: 指定initrd或initramfs文件的路径.
root: 指定根文件系统. 此参数仅与kernel和ramdisk一起使用,因为,kernel和ramdisk都是在Dom0上的,
并没有grub.conf来告诉kernel根文件系统在哪里,因此这里需要指定。
extra: 与root参数类似,它是指定kernel启动时的其它参数的.
#以上4个参数用于kernel文件在Dom0上, 下面固定格式用于DomU有自身的Kernel文件.
bootloader="pygrub": 若DomU使用自己的kernel和ramdisk,则此时需要一个Dom0中的应用程序来
           实现其bootloader功能; 这个不用指定root,因为,DomU的启动所需的所有文件都在自己
           的镜像文件中,它可以从grub.conf中指定根文件系统的位置.

注:

#让DomU通过网络之间安装操作系统,需要注意:
#kernel 和 ramdisk所需要的文件必须是:安装光盘目录下/isolinux/{vmlinuz,initrd.img}
   kernel="/p_w_picpaths/kernel/vmlinuz"
   ramdisk="/p_w_picpaths/kernel/initrd.img"                       
   extra="ks=http://1.1.1.1/centos6.6_x86_64.ks"       #注:给内核传递的ks文件。
另注:【注: 没有亲自测试,若有偏差还望指正.】
cloud-init*.rpm工具包可以将安装的OS中的特有信息(如:MAC, 磁盘信息等)删除,并且可以在下次启动时,自动生成这些信息.是制作云模板OS镜像的工具。



磁盘参数的指定方式:

xl方式创建VM时,磁盘指定格式: http://xenbits.xen.org/docs/unstable/misc/xl-disk-configuration.txt
[<target>, [<format>,[<vdev>,[<access>]]]]
target:  表示磁盘映像文件或设备文件路径:
          如: /p_w_picpaths/xen/linux.img
            /dev/vg-xen/lv-linux
format: 表示磁盘的格式:
          如: raw、qcow2..等,具体格式可查看: qemu-img  –help |grep 'Supported formats'
vdev: 指定添加的虚拟磁盘被DomU识别为何种类型的磁盘; 支持:hd, sd, xvd(xen-vritual-disk)
        注: 指定是需要写成: sda 或 sdb等,即要指定这是第几块磁盘.
access: 访问权限,除CDROM为'r'只读外,其它都为'rw'
示例:
     disk=["/p_w_picpaths/xen/linux.img,qcow2,xvda,rw",  "/iso/CentOS6.7.iso,,hdc,devtype=cdrom"]
    # 使用Dom0中物理磁盘分区做为DomU的存储空间
     disk=['/dev/vg-data/lv-bbox,raw,xvda,rw']

创建虚拟磁盘文件:

#注qemu-img创建的磁盘映像文件是采用稀疏磁盘格式创建的.因此用:du -sh  linux.img 可看到其大小为0.
#【qemu-img 的子命令简介详见附件】
qemu-img  create  -f  raw  -o  size=2G   /p_w_picpaths/xen/linux.img      
或  qemu-img  create  -f  raw  /p_w_picpaths/xen/linux.img  2G
若想知道当前指定的磁盘格式支持哪些额外参数:
     qemu-img  create  -f  qcow2  -o  ?   /p_w_picpaths/xen/linux.img   
           size : 指定qcow2格式的虚拟磁盘大小。
           backing_file: 指定其后端存储快照信息的映像文件位置.
           backing_fmt: 指定后端映像文件的格式。
           encryption: 是否对创建的映像文件加密
           cluster_size: 指定qcow2格式的簇大小.
           preallocation: 指定创建qcow2格式的磁盘映像文件时,需要预先做些什么:
                       > off : 什么也不做,创建一个空磁盘.
                       > metadata: 预先创建qcow2的元数据信息,建议设置.
                       > full: 直接填充成指定大小的磁盘文件,它包含了metadata.

             
创建虚拟网络接口:

#虚拟网卡的创建直接在配置文件中使用vif指定即可。
#格式: vif=[ "NET_SPEC_STRING" , "NET_SPEC_STRING" , …]
    NET_SPEC_STRING:的格式如下:
       key=value
       key包含以下几个:
        -->mac :指定网卡的MAC地址,注:MAC地址必须以:00:16:3e 开头,这是IANA分配给Xen的MAC厂商前缀.
       -->bridge: 指定此网卡要桥接到Dom0上的那个桥设备上.
       -->model: 指定模拟网卡的芯片类型:[rtl8139 |e1000]
       -->vifname:指定在Dom0中显示的接口名, 注: 在DomU中显示还是eth0…
       -->script: DomU在创建网络接口时,预先执行的脚本.注: 此脚本的路径也是Dom0上的路径.
       -->ip:指定要注入DomU中的IP地址。
       -->rate: 指定网卡的设备速率.
        如:rate=10Mb/s 
           rate=1MB/s@20ms      #20毫秒内只能传输1M/0.02s=20000字节/20ms



使用libvirt实现Xen虚拟机的图形管理:

# yum -y install libvirt libvirt-deamon-xen virt-manager python-virtinst libvirt-client
注: virt-manager: 是图形管理VM的接口界面,类似与VMware,可创建、启动、停止等
        python-virtinst: 此工具提供了virt-install命令行管理VM的接口.
        libvirt-client: 提供了一个virsh命令来管理VM。
        
# service  libvirtd  start    #要使用libvirt工具集,此服务必须首先启动.
virsh  dumpxml  busybox       #将busybox的信息输出为virsh的可用的xml配置文件,可修改此文件做模板来创建新VM实例.


PV DomU的根文件系统可以以多种不同的方式安置:

(1)虚拟磁盘映像文件
(a)方便制作成通用模板
当用qemu-img创建好一个虚拟磁盘映像文件,并向其中安装好OS后,可以使用cloud-init这种工具对其进行修改,去除其中OS的唯一性的数据信息(如:MAC地址等),需要注意的是,磁盘映像文件实际上是由标准格式的并且
在其上创建完文件系统后,就可以通过FS的API接口在不挂载的情况下对其中的文件进行修改.
(b)方便实现实时迁移
1. 将模板映像文件放置于FTP/NFS/Samba等共享存储上,且有多台Xen Hypervisor:
场景一: 需要快速创建一台VM.
假如当前业务中MySQL的从库读压力过大,需要扩容,此时就可以直接通过自行开发的脚本工具来判断当前那个Xen Hypervisor更空闲,然后,直接下载从共享存储上下载一个模板磁盘映像,直接就可以启动起来.
并且这是配置好的从库模板,启动后它可以直接连接到主库等等.
      
场景二: 快速迁移
假如当前某台Xen Hypervisor的CPU、Memory或其他资源突然升高,此时,可直接将该Xen Hypervisor上某些VM的内存数据导出到共享存储上,然后直接在另一台比较宽裕的Xen Hypervisor上,下载模板映像文
件并直接将该共享存储上导出的内存数据与模板映像文件关联,就可恢复到此Xen Hypervisor上实现快速迁移。
                
(2)分布式文件系统上存储磁盘映像文件,且有多台Xen Hypervisor:

场景一: 故障快速恢复
假如当前Xen Hypervisor上运行了多台VM,但Xen Hypervisor所在物理机突然故障,这时,我们完全可以直接将分布式存储系统上的磁盘映像文件直接让正常的Xen Hypervisor接管,已实现快速迁移.

场景二:快速迁移
如上面场景二类似,但此处我们无需在下模板磁盘映像文件,直接dump出运行中VM的内存数据到共享存储上就可以直接在另一台Xen Hypervisor上启动起来。
(1)使用Dom0上空闲的物理磁盘分区
(2)使用Dom0上空闲的逻辑卷
(3)使用iSCSI设备提供的块级别网络文件系统 或 分布式文件系统。
(4)网络文件系统,如: NFS, Samba

基本命令使用说明:

# xl help create        #查看创建DomU的帮助
# xl -v create /etc/xen/cirros  -n            #测试配置文件是否符合需求.
# xl create /etc/xen/cirros  -c                 #创建并启动成功后,立刻连接到其控制台上.
# xl -v create /etc/xen/cirros                 #启动cirros虚拟机
# xl list        #查看当前运行的VM情况
# xl console cirros-001           #连接到刚刚启动的cirros虚拟机的控制台.
--> # ctrl + ]                                      #退回到Dom0.
--> # exit                                          #拆除cirros,即销毁cirros.
# xl destroy cirros-001            #关机并销毁cirros, 注:销毁后,下次再用配置文件启动DomU时,就是一个新的DomU了.


启动cirros虚拟机登录后:

# ifconfig  -a                #是看不到任何接口的.
# insmod  /lib/modules/xen-netfront.ko    #安装网卡接口驱动模块
# ifconfig  -a 
# ifconfig  eth0  172.16.100.9  up
--># ctrl + ]           #回到到Dom0,查看网络接口状态.
--># Dom0:  ifconfig  -a    #将可以看到一个新接口.vif#.@ 
                 # "#": 表示DomU的ID ;  @:表示Dom0上创建的桥ID.
--># Dom0:  brctl  show     #将看到新接口已经被桥接到Dom0的桥设备上了。


xl的其它常用命令:

# xl shutdown   DomU_Name
# xl reboot   DomU_Name
# xl pause   DomU_Name         #暂停DomU
# xl unpause  DomU_Name
  
# xl save  DomU_Name    /path/to/save_name.img    /etc/xen/ConfigFile #将DomU挂起。
# xl restore  /etc/xen/ConfigFile   /path/to/save_name.img            #恢复DomU到运行态,无需指定DomU_Name.
  
# xl help  cd-insert              #插入光驱,仅适用于HVM模式
# xl help  cd-eject               #拔出光驱
  
# xl vcpu-list   DomU_Name        #显示DomU上有几颗真正使用的虚拟CPU.
                                  #CPU Affinity:表示该虚拟CPU线程可以运行在哪些物理核心上.
# xl vcpu-pin  DomU_ID  0  3      #将DomU的0号VCPU绑定到物理核心3上.
# xl vcpu-set  DomU_Name  1       #设置DomU当前只能使用1颗VCPU.若当前它有多颗VCPU,则其它CPU将被暂停.
                                  #注: 若在配置文件中指定了maxvcpus ,则此命令可动态添加VCPU数量.
                                  否则只能在当前VCPU总数的基础上减少。
                                              
# xl pci-list   DomU_Name        #显示当前DomU上的PCI设备.
# xl pci-attach  DomU_Name       #给运行时的DomU添加一块PCI设备.
# xl pci-detach  DomU_Name       #将运行的DomU中的PCI设备直接移除。
  
# xl info            #查看当前Xen Hypervisor的摘要描述信息
#    -- nr_cpus      #物理核心总数
#    -- max_cpu_id   #最大支持的VCPU个数
#                    #更详细的信息参见:http://smilejay.com/2012/03/xl-info_xm-info/
  
# xl demsg DomU_Name         #查看DomU启动时信息.
# xl top                     #查看DomU的资源使用情况.
  
# xl network-list   DomU_Name                      #查看DomU的网络接口列表
# xl network-attach  DomU_Name  bridge="xenbr1"    #给运行中DomU添加一块虚拟网卡.
# xl network-detach  DomU_Name  1                  #拆除网卡编号为1的网卡.
  
# qemu-img  create  -f  qcow2  -o  size=3G,preallocation=metadata  /p_w_picpaths/xen/busybox.2.img
# xl block-list   DomU_Name            #查看当前DomU_Name的磁盘列表.
# xl block-attach  DomU_Name   '/p_w_picpaths/xen/busybox.2.img,qcow2,xvdb,rw'    #给DomU添加一个磁盘设备.
# xl block-detach  DomU_Name   DevID   #移除一块磁盘.block-list中Vdev项就是DevID.
  
# xl uptime  DomU_Name       #查看DomU的运行时长.

   

基本功能测试如下:
(1)测试打开本地图形窗口及VNC远程:

# echo  "vfb='['sdl=1']'" >> /etc/xen/cirros      #开启仅本机访问的VNC窗口.
       
# 测试使用VNC远程连接打开.
# 开启可远程连接的VNC服务.
# echo "vfb=['vnc=1,vnclisten=0.0.0.0,vncpasswd=123456']"   >>  /etc/xen/cirros


(2)测试动态添加和拆除磁盘

# qemu-img create -f raw -o size=1G /p_w_picpaths/xen/vm1/cirros-01.img 
Formatting '/p_w_picpaths/xen/vm1/cirros-01.img', fmt=raw size=1073741824 
# xl block-attach cirros-001 '/p_w_picpaths/xen/vm1/cirros-01.img,raw,xvdb,rw'
# xl console cirros-001
# fdisk -l |grep 'Disk /dev'
     Disk /dev/xvda: 41 MB, 41126400 bytes
     Disk /dev/xvdb: 1073 MB, 1073741824 bytes       #可以看到已经添加成功.
      
# xl block-list cirros-001
Vdev  BE  handle state evt-ch ring-ref BE-path                       
51712 0   5      4     15     8        /local/domain/0/backend/qdisk/5/51712
51728 0   5      4     17     845      /local/domain/0/backend/qdisk/5/51728
      
# xl block-detach cirros-001 51728            #拆除磁盘.
      
# xl block-list cirros-001
Vdev  BE  handle state evt-ch ring-ref BE-path                       
51712 0   5      4     15     8        /local/domain/0/backend/qdisk/5/51712



(3)测试动态添加网卡

# xl network-attach cirros-001           #不加参数也可以添加虚拟网卡.
# xl network-attach cirros-001 'ip=172.16.100.9,bridge=xenbr1'         #添加参数,但IP参数没有生效.不知为何?
# xl network-attach cirros-001  
Idx BE Mac Addr.         handle state evt-ch   tx-/rx-ring-ref BE-path                       
0   0  00:16:3e:69:b9:49     0     4     16   775/774         /local/domain/0/backend/vif/5/0
1   0  00:16:3e:18:48:bc     1     4     17  1280/1281        /local/domain/0/backend/vif/5/1
2   0  00:16:3e:06:d0:58     2     4     18  1792/1793        /local/domain/0/backend/vif/5/2

(4)保存DomU当前的内存数据到指定位置

# 注:默认挂起后,会destroy DomU.
#    -p : 保存当前时刻的内存状态后,将DomU暂停在内存中.
#    -c : 保存当前时间的内存状态后, DomU继续运行.
# xl save -p cirros-001 /tmp/cirros-1611261547.img /etc/xen/cirros 
Saving to /tmp/cirros-1611261547.img new xl format (info 0x1/0x0/1128)
xc: Saving memory: iter 0 (last sent 0 skipped 0): 131072/131072  100%
# xl list
Name                                        ID   Mem VCPUs    State    Time(s)
Domain-0                                     0  1024     1     r-----      62.7
cirros-001                                   8   512     2     --p---       5.8
# xl console cirros-001
    [10489.060379] Freezing user space processes ... (elapsed 0.01 seconds) done.
# xl save  -c  cirros-001 /tmp/cirros-1611261610.img /etc/xen/cirros 
    Saving to /tmp/cirros-1611261610.img new xl format (info 0x0/0x0/1307)
    xc: Saving memory: iter 0 (last sent 0 skipped 0): 131072/131072  100%
# xl list                                              
Name                                        ID   Mem VCPUs State Time(s)
Domain-0                                     0  1024     2     r-----       62.5
cirros-001                                   2   512     2     -b----       2.1

(5)恢复保存的DomU状态

# xl restore /etc/xen/cirros /tmp/cirros-1611261610.img 
Loading new save file /tmp/cirros-1611261610.img (new xl fmt info 0x1/0x0/1128)
 Savefile contains xl domain config in JSON format
Parsing config from /etc/xen/cirros
xc: Reloading memory pages: 131072/131072  100%
#注: 在保存内存数据前,我事先为cirros添加了一块磁盘 和 一块网卡.
#请注意: 恢复DomU后,动态关联的网卡和磁盘都已经被去除了。
# xl network-list cirros-001
     Idx BE Mac Addr.         handle state evt-ch   tx-/rx-ring-ref BE-path                       
     0   0  00:16:3e:48:55:6d     0     4     16   775/774         /local/domain/0/backend/vif/5/0
# xl block-list cirros-001
     Vdev  BE  handle state evt-ch ring-ref BE-path                       
     51712 0   5      4     15     8        /local/domain/0/backend/qdisk/5/51712

(6)测试动态增加内存和CPU:

# xl list
      Name                                        ID   Mem VCPUs State Time(s)
      Domain-0                                     0  1024     2     r-----     932.5
      cirros-001                                   6   512     1     -b----       4.3
# grep -Ev '^$|^#' cirros 
      name = "cirros-001"
      bootloader="pygrub"
      memory = 512
      maxmem = 1024
      vcpus = 1
      maxvcpus = 3
      cpus = "0-2"                            #将CPU绑定到0,1,2这三颗物理核心上.
      vif = [ 'ip=10.1.0.10,bridge=xenbr0' ]  # IP参数设置后,测试发现总是不生效,不知原因为何?
      disk = [ '/p_w_picpaths/xen/cirros.img,qcow2,xvda,rw' ]
      vfb = [ 'vnc=1,vncpasswd=123456,vnclisten=0.0.0.0' ]
              
# xl mem-set cirros-001 600m
# xl list
      Name                                        ID   Mem VCPUs State Time(s)
      Domain-0                                     0  1024     2     r-----     945.7
      cirros-001                                   8   600     1     -b----       2.8
      
# 上面测试结果显示: 必须在配置文件中启动最大内存(maxmem)参数,才能使用命令来动态调整Memory.     
# xl vcpu-set cirros-001 3
# xl vcpu-list cirros-001
    Name                                ID  VCPU   CPU State   Time(s) CPU Affinity
    cirros-001                           8     0    0   -b-       2.7  all      #注: 动态调整VCPU个数后,并没有动态激活更多的VCPU.
    cirros-001                           8     1    -   --p       0.1  all      #问题原因,目前还不清楚...
    cirros-001                           8     2    -   --p       0.1  all      #在DomU中查看 cat  /proc/cpuinfo,也只有一颗.


以上为xen常用操作应用。