首页 > 技术文章 > Xen

guowei-Linux 2019-08-19 19:03 原文

 

         Xen是一种开源的虚拟机监控器(VMM),属于Type-I;支持全虚拟化和半虚拟化;

         Xen的Hypervisor直接运行在硬件之上,其所创建的虚拟机都要运行在Hypervisor上;Xen只对CPU和内存进行了虚拟化,也就是说Xen只负责管理驱动CPU和内存其他的像IO等设备都是交给Dom0中的操作系统管理的,自己不负责管理,这是因为IO的种类很多,需要开发很多的驱动程序,是比较麻烦的,并且操作系统已经可以支持大多数IO设备了,直接使用岂不爽哉!

         Xen管理虚拟机的方式:

                   Xen将每个运行在其上的虚拟机都称之为Domain,每个虚拟机具有一个Domain号,其中第一个虚拟机被称为Dom0,其他的以此类推;这些Domain可以分为两类,即Domain0和其他DomainU#;

                   Xen安装以后会自动运行一个名为Dom0的虚拟机,接下来的Xen的所有管理虚拟机的功能都是通过这个Dom0来实现的;这个Dom0既为用户管理其他虚拟机提供了接口,也负责接受其他虚拟机的IO调用请求(即DomU#的CPU和内存是由Hypervisor管理分配的,IO是由Dom0管理的),所以Dom0也被称为Privileged Domain(特权域);

                   Dom0也具有用户空间和内核空间;

                   在Xen中虚拟出来的CPU被当做一个进程或线程,然后Xen Hypervisor将这些线程或进程调度到物理CPU的某个核心上,从而实现CPU的虚拟化;而内存的虚拟可以理解为Hypervisor对真实的物理内存进行了二次映射,即Hypervisor对物理内存空间进行一遍映射,处于DomU中的虚拟机又对Hypervisor的虚拟内存进行了一遍映射(映射方式即为通常的映射方式);

                   Note:Xen只有在CPU支持虚拟化的情况下才可以进行全虚拟化,否则只能进行半虚拟化;Xen还可以将二者结合,使用HVM(硬件辅助的虚拟化)进行CPU和内存的虚拟化,对于IO设备使用PV(半虚拟化)进行虚拟化;

         Xen的IO模拟:

                   当DomU中的虚拟机需要使用IO设备时,一般都会通过Dom0为其模拟一个专用的相应的IO设备,供其使用;

                            比如磁盘设备的使用就是首先在Dom0中首先挂载相应的硬件磁盘设备,然后生成其对应的磁盘映像文件,再通过对磁盘映像文件进行模拟从而生成磁盘硬件设备,再将其提供给DomU中的虚拟机使用。这也意味着DomU中的虚拟机要安装相应的硬件驱动才可以使用这个模拟的磁盘设备;大体过程就是Domu中的虚拟机使用IO要具有相对于Dom0提供的模拟的IO设备的驱动,而Dom0还要再进行一次转换,即真正的相对于硬件IO的驱动,显而易见这种方式的性能不怎么样!

                   IO的半虚拟化:

                            Xen在DomU中的虚拟机上模拟一个前端驱动,然后在Dom0中在为其模拟一个对应的后端驱动;当虚拟机使用IO驱动时,就可以通过前端驱动(front)直接将请求交给后端驱动(backend),中间不做什么复杂的转换(比如上面那种方式中需要进行的模拟磁盘寻道之类的操作)。后端也不做什么多余的处理,直接将请求交给物理IO硬件;显然,这种方式的性能比上一种高很多!

                   Note:当众多的磁盘映像文件一起对底层的IO硬件设备进行请求时,其会使用一个称为环状缓冲的机制来解决这个问题。大体上就是将发送来的请求都放置到环上,当环放满时就意味着缓冲器满了,就只能阻塞新的IO请求,使其等待缓冲区释放空间,在将其调度进来;

         Xen的PV技术:

 

                   不依赖于CPU的HVM特性,但要求Guest OS(DomU中的虚拟机)的内核要进行修改进而知晓自己运行在PV环境中,其对CPU和内的使用要通过对Hypervisor 进行Hyper Call调用来进行;

                  可以运行在DomU中的OS:Linux(2.6.24+),NetBSD,FreeBSD,OpenSolaris等;

                            Note:windows不可以,因为Windows的内核是闭源的,除非微软自己进行修改,使其可以运行在Xen的PV模式中;

         Xen的HVM技术:

 

                   依赖于Intel VT或AMD的AMD-V的硬件虚拟化功能,并且一般还要依赖于QEMU来模拟IO设备;

                   可以运行在DomU中的OS:几乎所有市面上的操作系统;

         Xen的PV on HVM技术:

                   即上面提到的CPU为HVM模式,IO设备为PV模式;

                   可以运行在DomU中的OS:只要OS可以驱动PV接口类型的IO设备即可;

         XenStore:

                   为各Domain提供的共享信息的存储空间;且有着层级结构的名称空间;位于Dom0中;

         Xen的工具栈:

                   xm/xend:在Xen Hypervisor的Dom0中要启动xend服务;

                            xm:命令行管理工具,有很多子命令;

                   xl:Xen的轻量化工具,类似于xm并且会取代xm;

                   xe/xapi:提供了对Xen进行管理的API;

 

                   virsh/libvirt:在虚拟机上提供libvirt库,并启动了libvirtd服务即可通过远程对虚拟机进行管理;既可以管理Xen又可以管理KVM和Qemu;但是相对于上面对提到的工具比较重量级一点;

 

         Xen的使用;

                   环境:

                            在Vmware中创建一个虚拟机用于安装Xen;(Centos7)

                   1.在Vmware中的虚拟机的设置中将硬件虚拟化勾选上,这样就可以让Vmware将物理的硬件虚拟化功能映射到其管理的虚拟机上,使之支持硬件虚拟化;

 

                   安装Xen

                            1. 安装搭建Xen的虚拟化环境

          

yum -y install centos-release-xen

sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/CentOS-Xen.repo

yum --enablerepo=centos-virt-xen-48 -y update kernel

yum --enablerepo=centos-virt-xen-48 -y install xen

 

                            2. 修改虚拟机的内存数

                                     

cat /etc/default/grub

    GRUB_CMDLINE_XEN_DEFAULT="dom0_mem=1024M,max:1024M cpuinfo com1=115200,8n1 console=com1,tty loglvl=all guest_loglvl=all"

                                              
    GRUB_CMDLINE_LINUX_XEN_REPLACE_DEFAULT="console=hvc0 earlyprintk=xen nomodeset"

    Note:文件中会多出上面的两行;其中dom0_mem用于指定Dom0的内存大小;

 

                                              更多信息请查看:http://xenbits.xen.org/docs/unstable/misc/xen-command-line.html#dom0_vcpus_pin

                            3. 将支持 Xen 的 Linux 内核添加到 grub.conf中,以便系统能默认启动支持 Xen 的 Linux 内核;这个操作可以通过grub-bootxen.sh 自动完成; 

                            4.重启系统,Xen环境配置完成;

                            5.重启系统之后可以通过xl list查看是否有Dom0;

                   xl命令行工具:man help | man xl.conf

                            xl list:列出关于域的信息;

 

                                     ID:domain的ID标识,逐个递增;

                                     Mem:内存大小;

                                     VCPUs:指定Domain的虚拟CPU个数;

                                     State:Domain的状态;

                     r:运行

                     b:阻塞

                     p:暂停于内存中,如果突然宕机则数据会丢失

                     s:停止

                     c:崩溃

                     d:dying,处于正在关闭的过程中

 

                                     Time:运行时间;

                            常用指令:

                                     create:创建虚拟机

                                     console:连接虚拟机

                                     destory:销毁虚拟机

                                     shutdown:关机

                                     reboot:重启

                                     pause:暂停,将数据暂停在内存中

                                     unpause:解锁暂停状态

                                     save:将DomU的内存中的数据转存到指定的磁盘文件中,类似于Vmware中的挂起;

                                               ~]# xl save  busybox-001 /tmp/busybox-001.img /etc/xen/busybox

                                     restore:从指定的磁盘文件中恢复DomU数据到内存中;

                                               ~]# xl restore /etc/xen/busybox /tmp/busybox-001.img

                                     vcpu-list:显示domain中使用的虚拟CPU;

                                     vcpu-pin:将虚拟CPU固定只能在某些物理CPU上运行;

                                               ~]# xl vcpu-pin busybox-001 0 3

                                     info:查看当前Hypervisor的信息;

                                     dmesg:显示虚拟机启动时所输出的信息;

                                     top:显示虚拟机对资源的使用情况;

                                     pci-list:显示pass-through PCI设备;

                                     pci-attach:插入一个pass-through PCI设备;

                                     pci-detach:拆除一个pass-through PCI设备;

                                     network-list:查看虚拟机上的网卡设备;

                                     network-attach:添加一块网卡设备;

                                     network-detach:移除一块网卡设备;

                                     block-list:查看虚拟机上的磁盘设备;

                                     block-attach:添加一块磁盘设备;

                                     block-detach:移除一块磁盘设备;

                   创建Xen的PV模式的虚拟机(DomU使用Dom0中的kernel):

                            步骤:

                                     1.指定虚拟机要使用的kernel文件;

                                               可以位于Dom0中,也可以位于DomU中;

                                     2.指定虚拟机要使用的initramfs或initrd文件;

                                     3.安装DomU的内核模块;位于DomU中;

                                     4.为DomU提供根文件系统;

                                     5.设置Swap设备;

                                     6.将上述的内容定义在DomU的配置文件中;

                            Note:使用xl工具配置虚拟机可以通过man xl.cfg来查看帮助信息;

                                     xl.cfg中常用的指令:

                                               name=:指定唯一的domain名称;

                                               type=:指定创建的虚拟机类型;

                                                        pv:半虚拟化;

                                                        pvh:PV on HVM;

                                                        hvm:硬件辅助的虚拟化;

                                               vcpus=:指定VCPU的个数;

                                               maxvcpus=:指定可以使用的最大VCPU个数;

                                               cpus=:指定可以使用的物理CPU个数;

                                                        可以指定仅使用固定CPU;比如cpus="0-3,5,^1"表示仅使用0,2,3,5号四个物理CPU;

                                               memory=:指定可以使用的内存大小;

                                               maxmem=:指定可以使用的最大内存大小;

                                               on_poweroff=:指定在Guest虚拟机中执行关机时,在Dom0中要执行的动作;

                                                        destroy:销毁(关机),默认

                                                        restart:重启

                                                        rename-restart:更名后重启

                                                        preserve:保存这个域

                                                        coredump-destroy:将虚拟机中的内核空间中的数据到出到指定文件中进行保存,然后销毁这个domain;默认导出到/var/lib/xen/dump/NAME中;

                                               uuid=:DomU的唯一标识;

                                               disk=:通过列表指定磁盘设备;多个磁盘之间使用逗号隔开;这里的磁盘可以是磁盘映像文件,也可以是Dom0中的某个物理分区;其中使用物理设备性能比较好,但是不便于虚拟机的迁移;

                                                        格式:disk=[<target>, [<format>, [<vdev>, [<access>]]]]

                                                                 target:表示磁盘映像文件或设备文件路径;比如:/dev/vg/guest-volume

                                                                 format:表示磁盘格式;比如raw(默认), qcow, qcow2, vhd, qed;

                                                                           可以通过qemu-img工具创建以上格式的磁盘文件;

                                                                                    qemu-img create [-q] [-f fmt] [-o options] filename [size]

                                                                                    例子:~]# qemu-img-xen create -f raw -o size=2G /images/xen/busybox.img

                                                                                    Note:qemu-img  create -f qcow2 -o ?:可以查看某种格式所支持的选项;

                                                                 vdev:此设备在DomU中被识别为的硬件设备格式;比如hd[a-z]、sd[a-z]、xvd[a-z]等;

                                                                 access:表示此设备的访问权限;

                                                                           ro,r:表示只读;

                                                                           rw,w:表示读写(默认);

                                                        例子:disk=["/images/xen/linux.img,raw,xvda,rw","/images/xen/file.img,qcow2,xvdb,rw"]

                                                        官方文档:http://xenbits.xen.org/docs/unstable/man/xl-disk-configuration.5.html

                                               vif=:通过列表指定虚拟网卡设备;

                                                        格式:vif = [ '<vifspec>', '<vifspec>', ... ]

                                                                 mac=:指定MAC地址,一般以00:16:3E开头;

                                                                 bridge=:指定此网络接口在Dom0中被关联至哪个桥设备上;

                                                                 mode=:指定虚拟成的网卡类型:

                                                                           rtl8139 (default)

                                                                           e1000

                                                                 vifname=:指定在Dom0中接口的名称;

                                                                 ip=:指定固定IP地址;

                                                                 rate=:指定设备的传输速率;

                                                        例子:vif = [ 'mac=00:16:3E:74:34:32', 'mac=00:16:3e:5f:48:e4,bridge=xenbr1' ]

                                                        官方文档:http://xenbits.xen.org/docs/unstable/man/xl-network-configuration.5.html

                                               vfb=:通过列表指定虚拟的显示接口;

                                                        可以通过sdl(vfb = [ 'sdl=1' ])或者vnc(vfb = [ 'vnc=1' ])模拟实现;

                                                        如果使用vnc启动图形界面的话,需要在本地安装tigervnc这个软件包;这个VNC时工作在Dom0中的;

                                               PV模式的专有选项:

                                                        kernel=:指定虚拟机的内核文件路径;位于Dom0中;

                                                        ramdisk=:指明为kernel中指定的内核提供的ramdisk文件路径;位于Dom0中;

                                                        bootloader=:如果DomU使用自己的kernel及ramdisk,而非上面再Dom0中所提供的,则需要使用此处的bootloader选项来加载内核;这个bootloader功能是通过Dom0中的应用程序模拟出来的;与kernel和ramdisk选项相排斥,选择一种方法即可;

                                                        root=:指定根文件系统的位置;一般是与kernel和ramdisk选项一起使用;

                                                        extra=:指定内核引导时使用的额外参数;一般是与kernel和ramdisk选项一起使用;比如init=/bin/sh

                            具体配置过程:

                                     1.创建磁盘映像文件:

                       mkdir -pv /images/xen

                       qemu-img-xen create -f raw -o size=2G /images/xen/busybox.img

                       mkfs.ext4 /images/xen/busybox.img

                       mount -o loop /images/xen/busybox.img /mnt

 

                                     2.使用busybox构建根目录:

                       yum group install "开发工具"

                       yum install ncurses-devel.x86_64

                       tar xf busybox-1.22.1.tar.bz2

                       cd busybox-1.22.1/

                       make menuconfig

                             Busybox Settings  --->

                                 Build Options  --->

                                       [*] Build BusyBox as a static binary (no shared libs)

                       make

                       make install

                       cp -a _install/* /mnt/

                       cd /mnt

                       mkdir proc sys dev etc var home boot media

                       chroot /mnt/ /bin/sh

                       exit

 

                                     3.为DomU中的虚拟机提供kernel和initramfs文件:

                         cd /boot

                         ln -sv vmlinuz-2.6.32-754.el6.x86_64 vmlinuz

                         ln -sv initramfs-2.6.32-754.el6.x86_64.img initramfs.img

                           Note:使用3.10内核时虚拟机创建以后会自动销毁,使用4.9内核时启动以后根文件系统不是事先指定的,而是其自己的(这点可能是因为我使用的是相对于Xen的4.9的内核所引起的);

                         cd /etc/xen/

                         cp xlexample.pvlinux busybox

                         cat busybox

                             name = "busybox-001"

                             kernel = "/boot/vmlinuz"

                             ramdisk = "/boot/initramfs.img"

                             extra = "selinux=0 init=/bin/sh"

                             memory = 256

                             vcpus = 2

                             disk = [ '/images/xen/busybox.img,raw,xvda,rw' ]

                             root =  "/dev/xvda ro"

 

                                               cd /boot

                                               ln -sv vmlinuz-2.6.32-754.el6.x86_64 vmlinuz

                                               ln -sv initramfs-2.6.32-754.el6.x86_64.img initramfs.img

                                               Note:使用3.10内核时虚拟机创建以后会自动销毁,使用4.9内核时启动以后根文件系统不是事先指定的,而是其自己的(这点可能是因为我使用的是相对于Xen的4.9的内核所引起的);

                                              cd /etc/xen/

                                               cp xlexample.pvlinux busybox

                                               cat busybox

                                                        name = "busybox-001"

                                                        kernel = "/boot/vmlinuz"

                                                        ramdisk = "/boot/initramfs.img"

                                                        extra = "selinux=0 init=/bin/sh"

                                                        memory = 256

                                                        vcpus = 2

                                                        disk = [ '/images/xen/busybox.img,raw,xvda,rw' ]

                                                        root =  "/dev/xvda ro"

                                     4.创建虚拟机:

                                               xl -v create busybox

                                              xl console busybox-001   进入虚拟机,使用Ctrl + ] 退出;

                                     5.配置网络接口:

                                               修改配置文件的方式:

                                                        cd /etc/sysconfig/network-scripts/

                                                        cp ifcfg-ens33 ifcfg-xenbr0

                                                        vim ifcfg-ens33

                                                                 将于IP地址有关的全部删除,比如网关、掩码等,添加一项:BRIDGE=xenbr0;

                                                                 ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33

                                                                           TYPE=Ethernet

                                                                           PROXY_METHOD=none

                                                                           BROWSER_ONLY=no

                                                                           BOOTPROTO=static

                                                                           DEFROUTE=yes

                                                                           IPV4_FAILURE_FATAL=no

                                                                           IPV6INIT=yes

                                                                           IPV6_AUTOCONF=yes

                                                                           IPV6_DEFROUTE=yes

                                                                           IPV6_FAILURE_FATAL=no

                                                                           IPV6_ADDR_GEN_MODE=stable-privacy

                                                                           NAME=ens33

                                                                           UUID=9549a5c4-9cd6-4f9f-9d1b-08bdae8783f7

                                                                           DEVICE=ens33

                                                                           ONBOOT=yes

                                                                           BRIDGE=xenbr0

                                                                 Note:对于Centos6不要使用NetworkManager管理网络;

                                                        vim ifcfg-xenbr0

                                                                  修改设备名为xenbr0、删除物理地址以及UUID、将TYPE改为Brider;

                                                                 ~]# cat /etc/sysconfig/network-scripts/ifcfg-xenbr0

                                                                           TYPE=Bridge

                                                                           PROXY_METHOD=none

                                                                           BROWSER_ONLY=no

                                                                           BOOTPROTO=dhcp

                                                                           DEFROUTE=yes

                                                                          IPV4_FAILURE_FATAL=no

                                                                           IPV6INIT=yes

                                                                           IPV6_AUTOCONF=yes

                                                                           IPV6_DEFROUTE=yes

                                                                           IPV6_FAILURE_FATAL=no

                                                                           IPV6_ADDR_GEN_MODE=stable-privacy

                                                                           NAME=xenbr0

                                                                           DEVICE=xenbr0

                                                                           ONBOOT=yes

                                                        systemctl restart network.service

                                               使用命令行工具的方式:

                                                        ifconfig ens33 0 up

                                                        brctl addbr xenbr0

                                                        brctl addif xenbr0 ens33

                                                        ifconfig xenbr0 192.168.80.132/24 up

                                               Note:使用3.7或3.10内核设置桥设备时会出现死机的情况;

                                     6.添加虚拟网卡设备

                                               vim /etc/xen/busybox

                                                        vif = [ 'bridge=xenbr0' ]   将网卡桥接到xenbr0上;

                                               mount -o loop /images/xen/busybox.img /mnt

                                               mkdir -pv /mnt/lib/modules

                                               cp /lib/modules/2.6.32-754.el6.x86_64/kernel/drivers/net/xen-netfront.ko /mnt/lib/modules

                                               xl console busybox-001

                                               insmod /lib/modules/xen-netfront.ko

                                               ifconfig -a    eth0已经出现,此网卡设备即为front-net;

                                               Ctrl + ]

                                               ifconfig -a    出现一个名为vif2.0的网卡,此网卡设备即为backed-net;其中2.0的2表示Domain ID为2的虚拟机的网卡,0表示第一块网卡设备;

                                               brctl show

                                                        发现vif2.0被桥接到了xenbr0上;

                                               xl console busybox-001  再次进入虚拟机

                                               ifconfig eth0 192.168.80.134 up

                                               ping -c 4 192.168.80.134

                                               Note:当我们只想要某些虚拟机主机之间通信,而不让它们与外网通信时,可以创建一个桥设备,然后将它们全都桥接到这个桥设备上即可(这个不要将物理连接外网的网卡桥接到这个桥设备上),这就是Vmware中的VMnet2模式;仅主机模式就是在这个的基础上为物理主机模拟出一块网卡,再将这块虚拟网卡桥接到哪个桥设备上并且关闭核心间转发功能即可;

                   使用DomU自己的kernel创建虚拟机:

                            1.创建磁盘镜像文件:

                                     ~]# qemu-img create -f raw -o size=3G /images/xen/busybox3.img

                            2.对磁盘镜像文件进行分区:

                                     使用losetup命令进行分区

                                               losetup -f:显示第一个可用的loop设备;

                                               losetup -a:显示所有已用的loop设备;

                                               格式:losetup loop_device file

                                     ~]# losetup /dev/loop0  /images/xen/busybox3.img  将映像文件关联至loop设备上,以便于进行分区;

                                     ~]# fdisk  /dev/loop0

                                               添加两个主分区,一个为100M,一个为1G;

                                     ~]# kpartx -av /dev/loop0  从分区表创建设备映射关系

                                     ~]# mkfs.ext4 /dev/mapper/loop0p1

                                     ~]# mkfs.ext4 /dev/mapper/loop0p2

                                     ~]# mkdir /mnt/{boot,sysroot}

                                     ~]# cd /mnt/

                                     mnt]# mount /dev/mapper/loop0p1 boot/

                                     mnt]# mount /dev/mapper/loop0p2 sysroot/

                                     ~]# cp /boot/vmlinuz-2.6.32-754.el6.x86_64 boot/vmlinuz

                                     ~]# cp /boot/initramfs-2.6.32-754.el6.x86_64.img boot/iniramfs.img

                                     ~]# grub-install --roor-directory=/mnt /dev/loop0

                                     ~]# cat /mnt/boot/grub/grub.conf       -->Centos6

                                               default=0

                                               timeout=5

                                               title BusyBox(kernel-2.6)

                                                        root(hd0,0)

                                                        kernel /vmlinuz root=/dev/xvda1 ro selinux=0 init=/bin/sh

                                                        initrd /initramfs.img

 

                                     ~]# cp -a /root/busybox-1.22.1/_install/*  sysroot/

                                     ~]# kpartx -d /dev/loop0

                                     ~]# losetup -a

                                     ~]# cp /etc/xen/busybox1 /etc/xen/busybox3

                                     ~]# cat /etc/xen/busybox3

                                               name = "busybox-003"

                                               memory = 256

                                               vcpus = 2

                                               vif = [ 'bridge=xenbr0' ]

                                               disk = [ 'file:/images/xen/busybox3.img,xvda,rw' ]

                                               bootloader = 'pygrub'

                                     ~]# xl -v create /etc/xen/busybox3 -c

 

                                     Note:当虚拟机创建成功以后,可以使用cloud-init将虚拟机的磁盘映像文件中的唯一标识信息都去掉,然后将其作为模板,以后就可以直接创建虚拟机了,每次使其创建新的虚拟机时,都会自动生成相应的新的标识信息,比如MAC地址、UUID等;

                                     Xen虚拟机除了使用xl命令管理以外,还可以使用virt-manager这个图形化工具管理;

 

 

 

     注:根据马哥视频做的学习笔记,如有错误,欢迎指正;侵删

 

推荐阅读