什么是KVM?

KVM是开源软件,全称是Kernel-Based Virtual Machine(基于内核级虚拟机)技术; 
是一种用于Linux内核中的虚拟化基础设施,可以将Linux内核转化为一个hypervisor;
KVM在07年2月被导入Linux 2.6.20核心中,以可加载核心模块的方式被移植到FreeBSD及illumos上; 
KVM在具备Intel VT或AMD-V功能的x86平台上运行。它也被移植到S/390,PowerPC与IA-64平台上。在Linux内核3.9版中,加入ARM架构的支持; 
KVM目前由Red Hat等厂商开发,对CentOS/Fedora/RHEL等Red Hat系发行版支持极佳; (摘自wikipedia)

什么又是”虚拟化”?

在计算机技术中,虚拟化(技术)或虚拟技术(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源(CPU、内存、磁盘空间、网络适配器等),予以抽象、转换后呈现出来并可供分区、组合为一个或多个电脑配置环境。由此打破实体结构间的不可切割的障碍,使用户可以比原本的配置更好的方式来应用这些电脑硬件资源(其实就是虚拟整个PC硬件)。这些资源的新虚拟部分是不受现有资源的架设方式,地域或物理配置所限制。一般所指的虚拟化资源包括计算能力和数据存储。(摘自wikipedia)

“Hypervisor”和主机虚拟化

Hypervisor: 
Hypervisor又称虚拟机器监视器(英语:virtual machine monitor,缩写为 VMM)是用来建立与执行虚拟机器的部分电脑软件,固件或是硬件。被Hypervisor用来执行一个或多个虚拟机器的电脑被称为主体机器(host machine),这些虚拟机器,则称为客体机器(guest machine)。hypervisor可以用一个客体操作系统(guest operating systems)的外貌出现,提供虚拟的作业平台,负责管理其他客体操作系统的运作。在它之上运作的多个操作系统,共同分享了虚拟化之后的硬件资源。(摘自wikipedia) 
可以简单理解Hypervisor为超级管理员:这种超级管理分别运行在不同虚拟机上其功能是不一样的; 
Hypervisor功能是创建,管理,加载,分配,虚拟出物理机器的有效硬件资源给虚拟客户机使用; 

主机虚拟化: 
常用的两类虚拟化技术 
1型虚拟化:在硬件上跑的不是宿主机(直接跑的是虚拟化软件,需驱动底层硬件)所创建每个主机都是虚拟机; 
特点: 
    需要硬件支持 
    虚拟机监视器作为主操作系统 
    运行效率高 
2型虚拟化:在硬件安装操作系统(操作系统安装虚拟软件vmware,virtualbox); 
特点: 
    虚拟机监视器作为应用程序运行在主操作系统环境内 
    运行效率一般较类型I低

完全虚拟化与半虚拟化

完全虚拟化:用软件辅助并运行在物理机上,由软件发起指令,内核捕获;

半虚拟化:Guest_OS明确知道自己运行在虚拟机上,向物理机发起特权指令调用;

CPU虚拟化一般分两种:(模拟,虚拟)

模拟与虚拟在于,虚拟(性能)比模拟(需靠软件转换)好;

CPU虚拟化

CPU虚拟化需要本身对硬件所支持,需修改内核; 
x86 操作系统是直接运行于裸硬件设备,因此它自认为完全占有计算机硬件,而处理及访问应用程序和硬件设备是x86处理器底层四个特权级别来实现(环0,1,2,3); 
环0:运行特权指令,只有操作系统才能有权限(内核); 
环1-2:由于历史原因未使用; 
环3:放的是一些非特权指令,可进程使用(一但调用就会触发CPU异常,CPU软中断指令); 
现有基于x86处理器的操作系统,多数UNIX、Linux以及Windows系列大都只用了环0和环3两个特权级别;

没有对比就没有差异—>(Xen、KVM)

Xen:
hypervisor(超级管理员),直接运行在硬件上,只驱动CPU内存,各种IO不驱动;
装完后赶紧提供一个虚拟机(与xen一体),改内核重启立即创建虚拟机把原宿主机改成了虚拟机,以后就不启动宿主机直接启动Xen;
虚拟机命名:dom(原宿主机叫dom0管理其它虚拟机,I/O由它来驱动);
kvm:
悄悄并腐蚀了寄生在内核宿主机之上的hypervisor,kvm是模块如果要使用直接装载就可以;
如果装载了kvm模块内核立即变为僵尸并变成了hypervisor,用户空间变为了其中一台虚拟机的管理控制台,完全寄生不驱动任何驱动管理程序;
可虚拟CPU,内存,不能虚拟出来I/O设备,模拟I/O 需借助外部组件qemu;
qemu:存软件实现的模拟器,性能不好。可虚拟CPU,内存,I/O,大小1M左右;
qemu的加速器:qemu-accelerator(从模拟器变成虚拟机,需与架构一致);
组织方式:
	qemu去模拟I/O,需安装在控制台处dom0;
	kvm去虚拟化CPU,内存;

KVM的安装和有关知识

安装前提: 
1、实现环境:CentOS7.2_x86_64 
2、KVM依赖于HVM机制(interl是VT-X,AMD是amd-v); 
3、查看系统是否支持虚拟化,确保内核编译提供了kvm模块; 
~]# egrep 'vmx|svm' /proc/cpuinfo 
4、KVM主要运行在x86机器上(核心模块:kvm) 
5、验证检测kvm模块被正确装载 
~]# modprobe kvm 
~]# lsmod |grep kvm 
~]# ls -l /dev | grep kvm 

kvm模块载入后系统的运行模式:
 
内核模式:形象描述为,GuestOS执行I/O类操作或其它特殊指令操作,称为‘来宾-内核-模式’; 
用户模式:形象描述为,代表GuestOS请求I/O类操作; 
来宾模式:形象描述为,GuestOS的非I/O模式,即‘来宾-用户-模式’; 
        内核形象描述为,kvm hypervisor 


kvm的组件:
 
/dev/kvm: 
工作于hypervisor在用户空间可通过loctl()系统调用来完成vm的管理工作,且是一个字符设备; 
功能:创建vm,为vm分配内存,读写vcpu的寄存器向vcpu注入中断运行vcpu等; 
qemu进程:工作于用户空间,主要用于实现模拟vm的I/O设备; 


kvm的特性:

内存管理、存储、等……

内存管理:
	将分配给vm的内存交换至swap;
	支持使用huge page;
	支持使用intel_EPT或amd_RVI技术完成内在地址映射;
	GVA-->GPA-->HPA,GVA--HPA
	支持KSM(kernel same-page merging)
硬件支持:
	取决于Linux内核
存储支持:
	本地存储
	网络附加存储
	存储区域网络
	分布式存储(GlusterFS)
支持实时迁移:
	live migration(需使用共享存储)
支持的GuestOS:
	Linux,Windows,OpenBSD,FreeBSD,OpenSolaris
设备驱动:
	IO设备的完全虚拟化,实现模拟硬件
	IO设备的半虚拟化,实现virtio
virtio-blk,net,pci,console,balion(气球膨胀扩展内存)

kvm的管理工具: 
qemu: 
    quem-kvm 
    qemu-img 
libvirt: 
kvm hypervsior:libvirtd 
管理接口: 
    GUI:virt-manager,virt-viewer 
    CLI:virt-install,virsh
 

安装管理工具:
 
~]# yum install -y libvirt (大量依赖程序包,安装前配置好yum环境) 
~]# systemctl start libvirtd.service (启动libvirt守护进程) 
~]# ifconfig (查看虚拟的virbr0-桥设备,提供nat类型网络) 
KVM虚拟化基础_第1张图片
安装启动虚拟机: 
~]# yum install virt-manager virt-viewer virt-install 
virt工具包的安装 
~]# yum install qemu-kvm 
图形测试连接 
~]# virt-manager
如果系统是最小化安装的,记得安装此包(xorg-x11-xauth ,不然在使用ssh连接主机时图形无法支持;

KVM虚拟化基础_第2张图片           图形化安装 

查看守护进程文件类型: 
~]# rpm -ql libvirtd-daemon 
配置文件 
/etc/libvirt/libvirtd.conf 
Unite file 
/usr/lib/systemd/system/libvirtd.service 
相关术语: 
    node:物理服务器 
    hypervisor:支持虚拟机运行的环境 
    domain:虚拟机 
    dom0:prilileged,特权域 
    domU:非特权域 
hypervisor的访问路径:

本地及远程URL

本地URL:
driver[+transport]:///[PATH][?extra-param]
	driver:驱动名称,例如qemu,xen,lxc;
	transport:传输方式
	kvm使用qemu驱动,格式qemu:///system
远程URL:
driver[+transport]:///[user@][host][:port]/[PATH][?extra-param]
示例:
	qemu:///172.16.5.40/system
	qemu+ssh://[email protected]/system

创建网桥: 
与物理网络连接直接通信,需创建网桥把物理网卡当’桥’来使用 
手动配置方法 
~]# cd /etc/sysconfig/network-scripts/ 
~]# vim ifcfg-eno16777736 (当’桥’用) 
    删除IP地址 
    增加BRIDGE=’br0’ 
~]# cp ifcfg-eno16777736 if-br0 
~]# vim if-br0 
    DEVICE=br0 
    TYPE=Bridge 
name去掉,重启就ok 
使用virsh命令配置方法 
注意:如果使用桥接接口,不能启用NetworkManager服务 
~]# virsh help iface-bridge 
~]# virsh iface-list 
~]# virsh iface-bridge eno16777736 br0 –no-stp 

创建虚拟机: 
此安装方法略过…特别容易,记得选择桥接接口就可以,安装方式pxe等;

KVM虚拟化基础_第3张图片

virsh的常用命令

virsh help:获取帮助

virsh keyword
	list:列出域
示例:
	~]# virsh vcpuinfo rhel6.6 (列出虚拟CPU信息)
	~]# virsh dumpxml rhel6.6 >/tmp/mytemplate.xml
	(基于已有虚拟机导出配置文件实现批量虚拟机实例)
	crate:创建并启动域;
	define:创建域;
	domid:获取域ID;
	domuuid:获取域的uuid;
	dominfo:域信息;
	reboot:重启域;
	destory:关闭域;
	shutdown:关闭域;
	undfine:删除域;
	save:保存状态至文件中;
	restore:从保存文件中恢复域状态;
	pause:暂停域;
	resume:恢复暂停的域;

管理’域’资源的命令:

virsh help setmem: 
setmem:更改域的内存大小(不可超出最大值) 
    ~]# virsh setmem rhel6.6 768m –current 
setmaxmem:设定内存最大值; 
setvcpus:修改CPU数量; 
    ~]# virsh setvcpus rhel6.6 1 –current 
    ~]# virsh help vcpupin 可以绑定在哪些CPU上 
vcpuinfo:获取域的vcpu信息; 
    ~]# virsh vcpuinfo rhel6.6 
domblkstart:显示域块设备相关信息; 
    ~]# virsh domblkstart rhel6.6 
domiflist:显示域的接口列表 
    ~]# virsh domiflist rhel6.6 
    ~]# virsh domifstat rhel6.6 vnet0 
ifacelist:获取物理设备网络信息 
    ~]# virsh iface-list 

动态增删disk: 
    qemu-img create 
    virsh attach-disk 
    virsh detach-disk 
动态增删interface 
    virsh attach-interface 
    type:bridge 
    source:某桥的名称 
    virsh detach-interface –mac MAC

附加磁盘设备,必须常见磁盘设备 
包管理工具:yum install -y qemu-img 
示例:qem-img create -f qcow2 -o ? /tmp/test.qcow2 
    ~]# qem-img create -f qcow2 -o preallocation=metadata /tmp/test.qcow2 250G 支持稀疏格式 
    ~]# ls lh /tmp/test.qcow2(显示原始大小) 
    ~]# qem-img resize /tmp/test.qcow2 调整空间大小 
把映像文件附加到虚拟机上 
    ~]# virsh help attach-disk 帮助 
    ~]# virsh attach-disk rhel6.6 /tmp/test.img vdb 附加 
    ~]# virsh domblklist rhel6.6 查看附加的 
    ~]# fdisk -l 查看磁盘 
拆出磁盘 
    ~]# virsh help detach-disk 
    ~]# virsh detach-disk rhel6.6 vdb 

附加网络接口,必须创建网络接口 
ip link add无用功,不需要手动添加会帮我们自动添加 
    ~]# ip link help 
    ~]# ip link add name veth1.0 type veth peer veth1.1 创建一对网卡,一半1.0一半1.1 
    ~]# ip link show 

向虚拟机动态添加网卡 
    ~]# brctl show (桥控制命令) 
    ~]# ip link add veth1.0 type veth peer name veth1.1 
    ~]# ip link show 

向桥添加接口 
    ~]# brctl addif virbr0 veth1.0 
    ~]# brctl show 

把另一个接口添加到虚拟机上 
    ~]# virsh help attach-interface 
    ~]# virsh dumpxml rhel6.6 
    ~]# virsh attach-interface rhel6.6 bridge virbr0 
    ~]# virsh domiflist rhel6.6 
    ~]# ifconfig -a 

拆出网络接口 
    ~]# virsh help detach-interface 
    ~]# virsh detach-interface rhel6.6 bridge –mac 52:54:00:4e:ca:4e 
    ~]# virsh domiflist rhel6.6 
    ~]# brctl show

使用qemu-kvm手动创建虚拟机

注意:qemu跟virsh没有关系,不是virsh家族的,所以用virsh看不到运行中的虚拟机; 

包管理工具 

~]# yum install -y qemu-kvm
~]# rpm -ql qemu-kvm
~]# ln -sv /usr/libexec/qemu-kvm /usr/bin
~]# qemu-kvm -h 帮助
~]# qemu-kvm -machine help 指定要模拟的主机类型
~]# qemu-kvm -cpu ? 支持的CPU类型

创建虚拟机

~]# mkdir /vms/p_w_picpaths/test -pv
~]# cp cirros-0.3.0-x86_64-disk.img /vms/p_w_picpaths/test/test-0.qcow2 
~]# qemu-kvm -name test -m 64 -smp 2 -drive file=/vms/p_w_picpaths/test/test-0.qcow2,media=disk,if=virtio,format=qcow2,-net none,-nographic
~]# sudo su - 切换管理员账号
~]# help 获取命令帮助
~]# Ctrl+a+c 切换监控界面			

启用vnc功能在本机连接并支持图形窗口界面接口

~]# qemu-kvm -name test -m 64 -smp 2 -drive file=/vms/p_w_picpaths/test/test-0.qcow2,media=disk,if=virtio,format=qcow2,-net none,-vnc:1
~]# yum install -y tigervnc
~]# vncviewer:1

使用添加-net支持网络功能以便加入到某个桥上,并快速激活此接口

    激活接口可使用脚本,仅适用于物理桥;

~]# vim /etc/qemu-ifup
bridge=br0
if [-n "$1"];then
    ip link set $1 up
    sleep 1
brctl addif $bridge $1
    else
    echo "error.no interface specified."
    exit 1
fi
在粘贴到vi编辑器内把删除以行首开头的空白行
全文搜索删除行首空白行:(:%s/*[[:space:]]*//g)

~]# brctl show

~]# vim /etc/qemu-ifdown
bridge=br0
if [-n "$1"];then
    ip link set $1 down
    sleep 1
brctl addif $bridge $1
    else
    echo "error.no interface specified."
    exit 0
fi

启动虚拟机测试

~]# qemu-kvm -name test -m 64 -smp 2 -drive file=/vms/p_w_picpaths/test/test-0.qcow2,media=disk,if=virtio,format=qcow2,-net nic,model=virtio,macaddr=52:54:00:00:01,-net tap,ifname=veth1 -vnc:1
~]# vncviewer :1
~]# sudo su -
~]# ifconfig -a

创建两个网桥接口,让两台虚拟机相互通信(仅主机通信)

包工具:

~]# yum install bridge-utils

~]# which brctl

~]# rpm -qf /usr/sbin/brctl

~]# brctl 获取帮助

~]# brctl addbr mybr0 添加桥后非活动

~]# ip link set mybr0 up

启动两台虚拟机,并桥接到mybr0网卡上

~]# cp /etc/qemu-ifup-mybr0
    bridge=mybr0 
~]# cp /etc/qemu-ifdown-mybr0
    bridge=mybr0 
~]# qemu-kvm -name test -m 64 -smp 2 -drive file=/vms/p_w_picpaths/test/test-0.qcow2,media=disk,if=virtio,format=qcow2,-net nic,model=virtio,macaddr=52:54:00:00:01,-net tap,ifname=veth1,script=/etc/qemu-ifup-mybr0,downscript=/etc/qemu-ifup-mybr0,-vnc:1 -daemonize
~]# mkdir /vms/p_w_picpaths/test1/
~]# cp ./cirros-0.3.0-x86_64-disk.img /vms/p_w_picpaths/test1/test-1.qcow2
~]# qemu-kvm -name test -m 64 -smp 2 -drive file=/vms/p_w_picpaths/test1/test-1.qcow2,media=disk,if=virtio,format=qcow2,-net nic,model=virtio,macaddr=52:54:00:00:02,-net tap,ifname=veth2,script=/etc/qemu-ifup-mybr0,downscript=/etc/qemu-ifup-mybr0,-vnc:1 -daemonize
~]# brctl show (确保两个都被桥到物理桥上)

启动两台虚拟机并配置网卡地址

~]# vncviewer :1

~]# ifconfig eth0 10.1.0.50/16 up

~]# vncviewer :2

~]# ifconfig eth0 10.1.0.60/16 up

~]# ping两台机器

启动两台虚拟机并配置网卡地址后与物理机通信

~]# ifconfig mybr0 10.1.0.254/16 up

~]# 去ping各虚拟机和物理机

让两台虚拟机实现(nat通信)

~]# route add default gw 10.1.0.254 在vnc1上添加路由

~]# cat /proc/sys/net/ipv4/ip_forward 在物理机上开网卡间转发功能

~]# tcpdump -i eno16777736 -nn -icmp 抓包看下

~]# 这时物理机能ping出去,但是从vncping的包进不来

~]# 此时在物理机器上加入源地址转发策略

~]# iptables -t nat -A POSTROUTING -s 10.0.0.0/16 -j SNAT --to-source 172.16.5.40

~]# 再次在物理机上发出ping请求,这时包就可以到达物理机上了

让两台虚拟机实现与外部网卡地址通信

在物理机上br0上加入子接口

~]# ifconfig br0:0 172.16.5.70/16

~]# iptables -t nat -vnL --line-numbers

~]# iptables -t nat -A POSTROUTING -s 10.0.0.0/16 -j SNAT --to-source 172.16.5.70

~]# iptables -t nat -A PREROUTING -d 172.16.5.70 -j DNAT --to-destination 10.1.0.50

~]# ping 172.16.5.70 在vnc1上发出ping请求

~]# tcpdump -i mybr0 -nn -icmp 在物理机上抓包

使用网络名称地址空间虚拟路由器

~]# ip netns add route1
~]# ip netns list
~]# ip netns exec route1 tcpdump -i eth0 -nn -icmp
~]# ip netns exec route1 bash 打开虚拟路由环境route1的bash窗口 
~]# exit 退出此虚拟环境

done......