支持虚拟化的条件
intel的cpu:vmx
AMD的cpu:svm
本文使用的是vmware workstation,cpu要开启如下两个条件即可. 如果是物理机,需要在bios里面设置,默认都是开启状态。

在cpuinfo中可以查看具体的支持虚拟化的信息
[root@linux-node1 ~]# grep -E "svm|vmx" /proc/cpuinfo (可以看到支持vmx)
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts nopl
xtopology tsc_reliable nonstop_tsc aperfmperf eagerfpu pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch ida arat epb pln pts dtherm hwp hwp_noitfy hwp_act_window hwp_epp tpr_shadow vnmi ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 invpcid rtm rdseed adx smap xsaveopt

安装kvm
[root@linux-node1 ~]#yum install qemu-kvm qemu-kvm-tools virt-manager libvirt virt-install -y

kvm: linux内核的一个模块,模块不需要安装,只需要加载
qemu:虚拟化软件,可以虚拟不同的CPU,支持异构(x86的架构可以虚拟化出不是x86架构的)
qemu-kvm:用户态管理kvm,网卡,声卡,PCI设备等都是qemu来管理的

创建一个虚拟磁盘,-f 指定格式,路径是/opt/CentOS-7.1-x86_64.raw,大小为10G
[root@linux-node1 ~]# qemu-img create -f raw /opt/CentOS-7.1-x86_64.raw 10G
Formatting '/opt/CentOS-7.1-x86_64.raw', fmt=raw size=10737418240

显示内核中kvm的状态
[root@linux-node1 ~]# lsmod|grep kvm
kvm_intel 170181 0
kvm 554609 1 kvm_intel

[root@linux-node1 ~]#systemctl enable libvirtd.service
[root@linux-node1 ~]#systemctl start libvirtd.service
[root@linux-node1 ~]#systemctl status libvirtd.service

启动libvirt,查看状态,关键字:active
KVM

开始装一台虚拟机
在vmware上挂载一个镜像
KVM

导入到宿主机中,当然时间可能较长
[root@linux-node1 ~]# dd if=/dev/cdrom of=/opt/CentOS-7.1-x86_64.iso
8830976+0 records in
8830976+0 records out
4521459712 bytes (4.5 GB) copied, 150.23 s, 30.1 MB/s

[root@linux-node1 ~]#ls /opt/
CentOS-7.1-x86_64.iso CentOS-7.1-x86_64.raw

使用命令创建一台虚拟机
首先学virt-install命令,在这里使用–help查看,并且只学习重要的,其他的稍后会有提供
virt-install –help
-n(Name):指定虚拟机的名称
–memory(–raw):指定内存大小
–cpu:指定cpu的核数(默认为1)
–cdrom:指定镜像
–disk:指定磁盘路径(即上文创建的虚拟磁盘)
–virt-type:指定虚拟机类型(kvm,qemu,xen)
–network:指定网络类型

执行创建虚拟机命令
[root@linux-node1 ~]#virt-install --name CentOS-7.1-x86_64 --virt-type kvm --ram 1024 --cdrom=/opt/CentOS-7.1-x86_64.iso --disk path=/opt/CentOS-7.1-x86_64.raw --network network=default --graphics vnc,listen=0.0.0.0 --noautoconsole
Starting install...
Domain installation still in progress. You can reconnect to
the console to complete the installation process.

[root@linux-node1 ~]#iptables -F

找任意电脑安装Tightvnc view VNC客户端。可以远程监控安装情况。
VNC 192.168.1.103:5900(第一台使用5900,第二台是5901,以此类推。。。)
KVM

安装的时候选Press Tab for full configuration options on menu items.
KVM
在安装启动时加上参数:
net.ifnames=0 biosdevname=0

这样安装就会修改默认的网卡名称为eth0
KVM
设置分区:

KVM

虚拟机基本操作学习
生成kvm虚拟机:virt-install
查看在运行的虚拟机:virsh list
查看所有虚拟机:virsh list -all
查看kvm虚拟机配置文件:virsh dumpxml name
启动kvm虚拟机:virsh start name
正常关机:virsh shutdown name
非正常关机(相当于物理机直接拔掉电源):virsh destroy name
删除:virsh undefine name(彻底删除,找不回来了,如果想找回来,需要备份/etc/libvirt/qemu的xml文件)
根据配置文件定义虚拟机:virsh define file-name.xml
挂起,终止:virsh suspend name
恢复挂起状态:virsh resumed name

启动刚才创建的虚拟机
[root@linux-node1 ~]# virsh list --all
Id Name State

  • CentOS-7.1-x86_64 shut off
    [root@linux-node1 ~]# virsh start CentOS-7.1-x86_64
    Domain CentOS-7.1-x86_64 started
    [root@linux-node1 ~]# virsh list --all
    Id Name State

    3 CentOS-7.1-x86_64 running

在主机中查看刚创建的虚拟机的ip由来
[root@linux-node1 ~]# ps aux | grep dns
nobody 32622 0.0 0.0 15556 192 ? S 15:44 0:00 /usr/sbin/dnsm
asq --conf-file=/var/lib/libvirt/dnsmasq/default.conf
KVM
[root@linux-node1 ~]#cat /var/lib/libvirt/dnsmasq/default.conf
里面有dhcp-range
dhcp-range=192.168.122.2,192.168.122.254

虚拟机中安装 yum install net-tools

编辑kvm的xml文件,更改虚拟机CPU配置
配置虚拟机的cpu,两种方式(启动的时候指定核数,更改xml)
第一种方法:为了实现cpu的热添加,就需要更改cpu的最大值,当然热添加的个数不能超过最大值
[root@linux]#virsh edit CentOS-7.1-x86_64
<vcpu placement='auto' current="1">4</vcpu> 当前为1,自动扩容,最大为4

重启虚拟机
[root@linux-node1 ~]# virsh shutdown CentOS-7.1-x86_64
Domain CentOS-7.1-x86_64 is being shutdown
[root@linux-node1 ~]# virsh list --all
[root@linux-node1 ~]# virsh start CentOS-7.1-x86_64
Domain CentOS-7.1-x86_64 started
[root@linux-node1 ~]# virsh list --all

登录虚拟机上,查看cpu信息,确认cpu的个数,下面开始进行cpu热添加
cat /proc/cpuinfo (就1个CPU)

KVM
cpu的热添加(cpu只支持热添加,不支持热减少)
[root@linux-node1 ~]# virsh setvcpus CentOS-7.1-x86_64 2 --live
再到虚拟机中查看cpu信息
cat /proc/cpuinfo (就2个CPU)
KVM

kvm版本较高,并不需要echo “1”到/sys/devices/system/cpu/cpu1/online 进行激活,本版本已经自动可以激活

虚拟机中查看cat /sys/devices/system/cpu/cpu1/online
1

第二种方法:安装的时候指定
virt-install -vcpus 5 -vcpus 5,maxcpus=10,cpuset=1-4,6,8 -vcpus sockets=2,cores=4,thread=2

编辑kvm的xml文件,更改虚拟机内存配置
内存的设置拥有一个“气球(balloon)机制”,可以增大减少,但是也要设置一个最大值,默认并没有设置最大值,也可以在安装的时候指定,这里不再重复此方法
[root@linux-node1 ~]# virsh edit CentOS-7.1-x86_64
<memory unit='KiB'>4194304</memory> 把最大内存改为4G
<currentMemory unit='KiB'>1048576</currentMemory> 当前内存为1G

重启虚拟机并查看当前状态的内存使用情况
[root@linux-node1 ~]# virsh shutdown CentOS-7.1-x86_64
[root@linux-node1 ~]# virsh list --all
[root@linux-node1 ~]# virsh start CentOS-7.1-x86_64
[root@linux-node1 ~]# virsh list --all

[root@linux-node1 ~]# virsh qemu-monitor-command CentOS-7.1-x86_64 --hmp --cmd info balloon
balloon: actual=4096

虚拟机里查看内存
KVM

对内存进行热添加并查看
[root@linux-node1 ~]# virsh qemu-monitor-command CentOS-7.1-x86_64 --hmp --cmd balloon 2000
[root@linux-node1 ~]# virsh qemu-monitor-command CentOS-7.1-x86_64 --hmp --cmd info balloon
balloon: actual=2000

虚拟机里查看内存

KVM

更改虚拟机中存储,硬盘设置(不建议在生产环境使用硬盘的扩大收缩模式,很容易产生故障)
[root@linux-node1 ~]# qemu-img --help |grep -i "formats:" (查看支持硬盘的格式)
Supported formats: vvfat vpc vmdk vhdx vdi sheepdog rbd raw host_cdrom host_floppy host_device file qed qcow2 qcow parallels nbd iscsi gluster dmg cloop bochs blkverify blkdebug
kvm支持很多种硬盘格式
硬盘格式总体上分为两种:1为全镜像格式,2为稀疏格式
全镜像格式(典型代表raw格式),其特点:设置多大就是多大,写入速度快,方便的转换为其他格式,性能最优,但是占用空间大
稀疏模式(典型代表qcow2格式),其特点:支持压缩,快照,镜像,更小的存储空间(即用多少占多少)
硬盘格式都可以通过qemu-img管理,详情qemu-img -help

编辑kvm的xml文件,更改虚拟机网桥连接配置
Kvm虚拟机网络默认情况是NAT情况。
但是在生产情况,使用更多的是桥接模式,更改虚拟机为网桥模式,原理图如下,网桥的基本原理就是创建一个桥接接口br0,在物理网卡和虚拟网络接口之间传递数据
KVM
修改eth0(这里Centos7的eth0在装机的时候就指定,不需要特意指定了)
添加一个网桥并查看
[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.52540050ea92 yes virbr0-nic
vnet0

[root@linux-node1 ~]# brctl addbr br0

[root@localhost ~]# brctl show
bridge name bridge id STP enabled interfaces
br0 8000.000000000000 no
virbr0 8000.52540050ea92 yes virbr0-nic
vnet0

把eth0加入网桥,使用桥接模式,给br设置ip,添加路由网关,关闭防火墙(192.168.1.103不是刚才所创建的kvm虚拟机的ip地址)
[root@linux-node1 ~]# brctl addif br0 eth0 && ip addr del dev eth0 192.168.1.103/24 && ifconfig br0 192.168.1.103/24 up && route add default gw 192.168.1.1 && iptables -F

然后,编辑虚拟机的网络配置使用br0网桥模式 (删除红色)
[root@linux-node1 ~]# virsh edit CentOS-7.1-x86_64
<interface type='network'>
<mac address='52:54:00:aa:bf:d9'/>
<source network='default'/>
<model type='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<interface type="bridge"> <!--虚拟机网络连接方式-->
<source bridge="br0" /> <!-- 当前主机网桥的名称-->
<mac address="52:54:00:aa:bf:d9" /> <!--为虚拟机分配mac地址,务必唯一,如果是dhcp获得同样ip,引起冲突-->
</interface>

重启虚拟机,网桥模式生效,此时使用ssh便可以链接到所创建的虚拟机了,在vmvare机器上使用ifconfig查看详情(刚才所创建的kvm的ip地址192.168.1.112)
KVM

挂起虚拟机
[root@linux-node1 ~]# virsh suspend xxx
[root@linux-node1 ~]# virsh list --all

恢复虚拟机
[root@linux-node1 ~]# virsh resume xxx
[root@linux-node1 ~]# virsh list --all

强制关闭虚拟机
[root@linux-node1 ~]#virsh destroy xxx

删除虚拟机: 删除关闭了的虚拟机
[root@linux-node1 ~]#virsh undefine xxx

KVM的优化(以下操作不是直接在kvm上,是在192.168.1.103上操作)
cpu的优化
intel的cpu的运行级别,按权限级别高低Ring3->Ring2->Ring1->Ring0,(Ring2和Ring1暂时没什么卵用)Ring3为用户态,Ring0为内核态
KVM
Ring3的用户态是没有权限管理硬件的,需要切换到内核态Ring0,这样的切换(系统调用)称之为上下文切换,物理机到虚拟机多次的上下文切换,势必会导致性能出现问题。对于全虚拟化,inter实现了技术VT-x,在cpu硬件上实现了加速转换,CentOS7默认是不需要开启的。

cpu的缓存绑定cpu的优化
[root@linux]# lscpu|grep cache
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 8192K
L1 L2 L3 三级缓存和CPU绑定
L1是静态缓存,造价高,L2,L3是动态缓存,通过脉冲的方式写入0和1,造价较低。cache解决了cpu处理快,内存处理慢的问题,类似于memcaced和数据库。如果cpu调度器把进程随便调度到其他cpu上,而不是当前L1,L2,L3的缓存cpu上,缓存就不生效了,就会产生miss,为了减少cache miss,需要把KVM进程绑定到固定的cpu上,可以使用taskset把某一个进程绑定(cpu亲和力绑定,可以提高20%的性能)在某一个cpu上,例如:taskset -cp 1 25718(1指的是cpu1,也可以绑定到多个cpu上,25718是指的pid).
cpu绑定的优点:提高性能,20%以上
cpu绑定的缺点:不方便迁移,灵活性差

内存的优化
内存寻址:宿主机虚拟内存 -> 宿主机物理内存
虚拟机的虚拟内存 -> 虚拟机的物理内存
以前VMM通过采用影子列表解决内存转换的问题,影子页表是一种比较成熟的纯软件的内存虚拟化方式,但影子页表固有的局限性,影响了VMM的性能,例如,客户机中有多个CPU,多个虚拟CPU之间同步页面数据将导致影子页表更新次数幅度增加,测试页表将带来异常严重的性能损失。如下图为影子页表的原理图
KVM
KVM
在此之际,Intel在最新的Core I7系列处理器上集成了EPT技术(对应AMD的为RVI技术),以硬件辅助的方式完成客户物理内存到机器物理内存的转换,完成内存虚拟化,并以有效的方式弥补了影子页表的缺陷,该技术默认是开启的,如下图为EPT技术的原理
KVM
KSM内存合并
宿主机上默认会开启ksmd进程,该进程作为内核中的守护进程存在,它定期执行页面扫描,识别副本页面并合并副本,释放这些页面以供它用,CentOS7默认是开启的
[root@localhost ~]# ps aux|grep ksmd|grep -v grep
root 27 0.0 0.0 0 0 ? SN 13:22 0:00 [ksmd]

大页内存,CentOS7默认开启的
[root@localhost ~]#cat /sys/kernel/mm/transparent_hugepage/enabled
[always] madvise never
[root@localhost ~]#ps aux |grep khugepage|grep -v grep
root 27 0.0 0.0 0 0 ? SN 02:39 0:00 [khugepaged]

Linux平台默认的内存页面大小都是4K,HugePage进程会将默认的的每个内存页面可以调整为2M。

磁盘IO的优化
IO调度算法,也叫电梯算法,详情请看http://www.unixhot.com/article/4
① Noop Scheduler:简单的FIFO队列,最简单的调度算法,由于会产生读IO的阻塞,一般使用在SSD硬盘,此时不需要调度,IO效果非常好
② Anticipatory IO Scheduler(as scheduler)适合大数据顺序顺序存储的文件服务器,如ftp server和web server,不适合数据库环境,DB服务器不要使用这种算法。
③ Deadline Schedler:按照截止时间的调度算法,为了防止出现读取被饿死的现象,按照截止时间进行调整,默认的是读期限短于写期限,就不会产生饿死的状况,一般应用在数据库
④ Complete Fair Queueing Schedule:完全公平的排队的IO调度算法,保证每个进程相对特别公平的使用IO

查看本机Centos7默认所支持的调度算法
[root@localhost ~]# dmesg|grep -i "scheduler"
[ 0.662373] io scheduler noop registered
[ 0.662374] io scheduler deadline registered (default)
[ 0.662391] io scheduler cfq registered

临时更改某个磁盘的IO调度算法,将deadling模式改为cfq模式
[root@localhost ~]# cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
[root@localhost ~]# echo cfq >/sys/block/sda/queue/scheduler
[root@localhost ~]# cat /sys/block/sda/queue/scheduler
noop deadline [cfq]

使更改的IO调度算法永久生效,需要更改内核参数(elevator=deadline或者 elevator=noop等)
[root@localhost ~]#vi /boot/grub/menu.lst (新版centos可能在vi /boot/grub2/grub.cfg)
kernel /boot/vmlinuz-3.10.0-229.el7 ro root=LABEL=/ elevator=deadline rhgb quiet

cache的优化
关于write through和write back,默认write through即可
Write-back
在这种策略下,当数据被写到raid卡的cache中,控制器就向IO调度器返回了写操作完成信号; 双刃剑,它虽然带来了IO性能的提升,但是随之而来的风险:因为cache是ROM,假设服务器突然断电,则cache中的数据可能丢失; 为了解决这个问题,raid卡加加装一块锂电池(BBU),即当服务器断电时,能把cache中的数据刷到磁盘上;同样的道理,BBU又成为一个风险点,因为锂电池需要保证始终有足够的电量来保证能将cache中的数据写到磁盘上,raid卡会加入一个BBU的管理策略,learn cycle(充放电周期,一般有30/90天,让电池充放电一次,持续约6小时),那么这6小时又称为一个风险点;所以raid卡又会增加一个策略:No WB when bad bbu,即当BBU坏掉,或者BBU正在充放电时,禁用write-back,此时Write policy就会变成:write-through。
KVM
Write through
只有当数据被写到物理磁盘中,控制器才向IO调度器返回了写操作完成信号; 这种策略以牺牲IO性能,来保证数据安全性,淘宝这边的策略:因为Write-Through的io性能无法满足业务的需求,所以我们这边会采用另一个模式:WB when bad bbu,即不管bbu状态是否正常,我们都会采用write-back,那数据安全怎么办?服务器异常断电的情况,在我们这边概率极低;即便很不幸的我们IDC局部断电了,我们也有主备模式来保证数据的相对安全;我们会监控BBU的状态,一旦发生了BBU failed,我们会将安排停机更换

创建虚拟机镜像
虚拟磁盘及镜像
由于在一开始创建了虚拟磁盘,并命名为CentOS-7.1-x86_64.raw,这就是虚拟机的镜像。
[root@localhost ~]# cd /opt/
[root@chuck opt]# ls
CentOS-7.1-x86_64.iso CentOS-7.1-x86_64.raw rh
镜像制作原则
分区的时候,只分一个/根分区,并不需要swap分区,由于虚拟机的磁盘性能就不好,如果设置了swap分区,当swap工作的时候,性能会更差。例如阿里云主机,就没有交换分区。
镜像制作需要删除网卡(eth0)(/etc/sysconfig/network scripts/ifcfg-eth0)中的UUID和MAC项,如果有udev(/etc/udev/rules.d/70-persistent-ipoib.rules)的规则也要删除
关闭selinux,关闭iptables
安装基础软件的包:net-tools lrzsz screen tree vim wget

KVM管理平台:
OpenStack
oVirt (小规模部署,推荐ovirt)管理端+客户端组成。oVrit Engine(相当于vCenter) oVirt主机/节点(相当于ESXi)

https://www.ovirt.org/download/

[root@localhost opt]# yum localinstall http://resources.ovirt.org/pub/yum-repo/ovirt-release36.rpm
[root@localhost opt]# yum install -y ovirt-engine
安装oVrit Engine
[root@localhost opt]# engine-setup (基本使用默认配置安装)(没说明的都选默认)
Configure VDSM on this host? (Yes, No) [No]: 默认
Firewall manager to configure (iptables): iptables
Use weak password? (Yes, No) [No]: yes
Local ISO domain ACL: *(rw)

安装后,登陆 https://192.168.1.103
KVM
选 Administration Portal
KVM

安装客户端
[root@localhost opt]# yum localinstall http://resources.ovirt.org/pub/yum-repo/ovirt-release36.rpm
[root@localhost opt]# yum install -y ovirt-engine-setup-plugin-allinone

KVM