一,什么是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设备模型,访问外设的途径。[/]
三、KVM 工作原理
kvm基本工作原理概述:
用户模式的qemu利用libkvm通过ioctl进入内核模式,kvm模块未虚拟机创建虚拟内存,虚拟CPU后执行VMLAUCH指令进入客户模 式。加载Guest OS并执行。如果Guest OS 发生外部中断或者影子页表缺页之类的情况,会暂停Guest OS的执行,退出客户模式出行异常处理,之后重新进入客户模式,执行客户代码。如果发生I/O事件或者信号队列中有信号到达,就会进入用户模式处理。
如下图所示:
四、手动安装配置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 虚拟机名 #连接虚拟机
手动安装完毕,现在就可以在命令行里秀操作了。
代码语言:javascript复制五、自动化脚本安装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~4数字!";
fi
代码语言:javascript复制注:此脚本已基本实现KVM自动化安装的基本功能。
总结 其实KVM的安装和使用都很方便简单的,大家要理解KVM各个参数的含义。最关键的就是KVM的网络桥接的设置,但是现在KVM在某些方面还是有一定的缺陷(比如创建光驱要关机等),希望会在后续版本中有所改进,在这里大家要多看官方软件自身的文档,会有很大的帮助。