一,什么是KVM

      KVM包括很多部件:首先,它是一个Linux内核模块(现在包括在主线中)用于转换处理器到一种新的用户 (guset) 模式。用户模式有自己的ring状态集合,但是特权ring0的指令会陷入到管理器(hypervisor)的代码。由于这是一个新的处理器执行模型,代 码不需要任何的改动。   除了处理器状态转换,这个内核模块同样处理很小一部分低层次的模拟,比如MMU注册(用于管理VM)和一部分PCI模拟的硬件。 在可预见的未来,Qemu团队专注于硬件模拟和可移植性,同时KVM团队专注于内核模块(如果某些部分确实有性能提升的话,KVM会将一小部分模拟代码移 进来)和与剩下的用户空间代码的交互。 kvm-qemu可执行程序像普通Qemu一样:分配RAM,加载代码,不同于重新编译或者调用calling KQemu,它创建了一个线程(这个很重要);这个线程调用KVM内核模块去切换到用户模式,并且去执行VM代码。当遇到一个特权指令,它从新切换会 KVM内核模块,该内核模块在需要的时候,像Qemu线程发信号去处理大部分的硬件仿真。 这个体系结构一个比较巧妙的一个地方就是客户代码被模拟在一个posix线程,这允许你使用通常Linux工具管理。如果你需要一个有2或者4核的虚拟 机,kvm-qemu创建2或者4个线程,每个线程调用KVM内核模块并开始执行。并发性(若果你有足够多的真实核)或者调度(如果你不管)是被通用的 Linux调度器,这个使得KVM代码量十分的小 当一起工作的时候,KVM管理CPU和MEM的访问,QEMU仿真硬件资源(硬盘,声卡,USB,等等)当QEMU单独运行时,QEMU同时模拟CPU和 硬件。

二、KVM架构

kvm基本结构有2个部分构成:

    kvm 驱动,现在已经是linux kernel的一个模块了。其主要负责虚拟机的创建,虚拟内存的分配,VCPU寄存器的读写以及VCPU的运行。

    另个组成是Qemu,用于模拟虚拟机的用户空间组件,提供I/O设备模型,访问外设的途径。

wKiom1anbZXQ-MYYAADARdvbDoU668.png


三、KVM 工作原理

kvm基本工作原理概述:

    用户模式的qemu利用libkvm通过ioctl进入内核模式,kvm模块未虚拟机创建虚拟内存,虚拟CPU后执行VMLAUCH指令进入客户模 式。加载Guest OS并执行。如果Guest OS 发生外部中断或者影子页表缺页之类的情况,会暂停Guest OS的执行,退出客户模式出行异常处理,之后重新进入客户模式,执行客户代码。如果发生I/O事件或者信号队列中有信号到达,就会进入用户模式处理。(如 下图)


wKioL1anbITBOK8RAAFSyoiGZ9k918.png


四、手动安装配置KVM

1.安装前的准备
    1.CPU支持虚拟化(Inter-VT、AMD-V)
    [root@localhost ~]# grep --color 'svm|vmx|lm'  /proc/cpuinfo

    相关CPU功能标志包括:   
    svm=安全虚拟机(AMD-V)
    vmx=虚拟机x86(Inter-VT)
    lm=长模式(64位支持)	
    
    2. BIOS开启CPU虚拟化支持
    1)重启
    2)按delete键
    3) 进入BIOS开启
    
2.安装虚拟化(yum配置完毕)
# yum -y install kvm python-virtinst libvirt bridge-utils 
virt-manager qemu-kvm-tools virt-viewer virt-v2v qemu-kvm tunctl
[root@localhost ~]#vim /etc/sysconfig/selinux //关闭selinux
SELINUX=disabled

3.启动libvirtd
[root@localhost ~]# /etc/init.d/libvirtd start  //启动
[root@localhost ~]# ps -e|grep libvirtd   //查看是否启动
[root@localhost ~]#chkconfig libvirtd on
注释:永久开启!不然系统重启后不会自动启动这个服务的哟~
# virsh  iface-bridge eth0 br0
注释:创建网络桥!
验证:
ifconfig   br0
注释:观察IP地址是否跑到了br0网卡上!

4.配置网络桥接
root@localhost network-script]# vi ifcfg-eth0 
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=none
BRIDGE=br0

[root@localhost network-scripts]# vi ifcfg-br0
DEVICE=br0
TYPE=Bridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.100
GATEWAY=192.168.0.1
NETMASK=255.255.255.0
DNS1=192.168.0.1
DELAY=0

5.重启网络
[root@localhost]# service NetworkManager stop  //这个关闭掉就行
停止 NetworkManager 守护进程:                             [确定]
注释:为什么关闭它呢~因为它和KVM桥接网卡冲突!
#chkconfig NetworkManager off 
注释:永久关闭该服务!!!不然系统重启后还会自己再把这个服务开启的哟~
[root@localhost rules.d]# service network restart

6.用virt-install生成.img文件(参数含义在上一篇KVM初体验已有注释)
# virt-install --name=ubuntu1 
--ram 1024 --vcpus=1 
--disk path=/root/ubuntu1.img,size=10 
 --accelerate --cdrom /root/redhat6.4.iso 
--graphics vnc,port=5920 --network bridge=br0
[root@localhost ~]# vi /etc/libvirt/qemu.conf 
vnc_listen = "0.0.0.0"
user = "root"               //去掉注释
group = "root"              //去掉注释
dynamic_ownership = 0       //去掉注释,把1改为0

7.启动虚拟机
虚拟机使用方法:
virsh  destroy       虚拟机名        #关闭虚拟机
virsh  undefine      虚拟机名        #删除虚拟机
virsh  start         虚拟机名        #开启虚拟机
virsh   list   --all 显示所有虚拟机
virsh   console      虚拟机名        #连接虚拟机

手动安装完毕,现在就可以在命令行里秀操作了。


五、自动化脚本安装KVM

#!/bin/bash
echo "[1] 配置YUM"
echo "[2] 安装KVM工具"
echo "[3] 设置桥接"
echo "[4] 手动安装虚拟机"
echo "[5] 查看虚拟机"
echo "[6] 开启虚拟机"
echo "[7] 关闭虚拟机"
echo "[8] 连接虚拟机"
echo "[9] 自动安装虚拟机"
echo "[0] 退出"
read -p "type:"  NUM
if [ $NUM = 0 ];then
exit;
elif [ $NUM = 1 ];then
#配置YUM
    rm -rf /etc/yum.repos.d/*;
cat > /etc/yum.repos.d/yum.repo << EOF
[yum]
name=yum
enabled=1
gpgcheck=0
baseurl=ftp://192.168.0.200/rhel6.4
EOF
elif [ $NUM = 2 ];then
#安装KVM工具
     LANG=en yum groupinstall "Virtualization*" -y;
elif [ $NUM = 3 ];then
#设置桥接
    chkconfig NetworkManager off;
    chkconfig network on;
    service NetworkManager stop;
    service network start;
    yum install  "bridge-utils" -y;
    service libvirtd restart;
    chkconfig libvirtd on;
    virsh iface-bridge eth0 br0;
elif [ $NUM = 4 ];then
#安装虚拟机
    read -p "输入虚拟机的名字:"  NAME
    read -p "输入虚拟及硬盘大小(G): "  SIZE
    read -p "输入虚拟机内存大小(M): "  MEM
    ping -c 1 192.168.0.200 > /dev/null
    if [ $? -ne 0 ];then
    echo "无法接连192.168.0.200,请检查网络!";
    exit;
    fi
    virt-install --nographics -n $NAME --os-type=linux --os-variant=rhel6 -r $MEM --arch=x86_64 --vcpus=1 --disk path=/var/lib/libvirt/images/$NAME,size=$SIZE,format=qcow2 -w bridge=br0 -l ftp://172.16.8.100/rhel6.4 -x " console=ttyS0";
elif [ $NUM = 5 ];then
#查看虚拟机
virsh list --all
elif [ $NUM = 6 ];then
#开机
read -p "虚拟机名称: " XNAME
virsh start $XNAME;
elif [ $NUM = 7 ];then
#关闭
read -p "虚拟机名称: " XNAME  &> /dev/null
virsh destroy $XNAME;
elif [ $NUM = 8 ];then
#连接虚拟机
read -p "虚拟机名称: " XNAME
virsh console $XNAME;
elif [ $NUM = 9 ];then
#自动安装虚拟机
read -p "输入虚拟机的名字:"  NAME
        read -p "输入虚拟及硬盘大小(G): "  SIZE
        read -p "输入虚拟机内存大小(M): "  MEM
        ping -c 1 192.168.0.200 > /dev/null
        if [ $? -ne 0 ];then
        echo "无法接连192.168.0.200,请检查网络!";
        exit;
        fi
        virt-install --nographics -n $NAME --os-type=linux --os-variant=rhel6 -r $MEM --arch=x86_64 --vcpus=1 --disk path=/var/lib/libvirt/images/$NAME,size=$SIZE,format=qcow2 -w bridge=br0 -l ftp://192.168.0.200/rhel6.4 -x "ks=ftp://192.168.0.200/rhel6.4.ks console=ttyS0";


else
echo "请输入:0~9数字!";
fi

注:此脚本已基本实现KVM自动化安装的基本功能。

总结:

    其实KVM的安装和使用都很方便简单的,大家要理解KVM各个参数的含义。最关键的就是KVM的网络桥接的设置,但是现在KVM在某些方面还是有一定的缺陷(比如创建光驱要关机等),希望会在后续版本中有所改进,在这里大家要多看官方软件自身的文档,会有很大的帮助。