第1章 虚拟化KVM
1.1 虚拟化KVM介绍
1.1.1 为什么学习虚拟化
² 解决资源浪费
² 解决一起使用的资源枪战冲突
1.1.2 为什么学习KVM
VMware是收费的(对于企业)对于个人来说是免费的
开源版本KVM
公司使用场景:底层使用KVM,上层使用OpenStack,通过OpenStack管理KVM
1.2 虚拟化的技术演变
1.2.1 软件模拟
软件虚拟化 QEMU
1.2.2 虚拟化层翻译
(1)软件全虚拟化
软件捕获翻译相当于翻译官
VMware,有一个专门的虚拟化引擎。通过虚拟化引擎,捕获虚拟机的指令,并进行处理,这也是为什么在虚拟机上虽然使用的是物理机一样的指令,但是虚拟机不能对硬件进行操作的原因,比如重启虚拟机不会引起宿主机的重启。这种解决方案也叫软件全虚拟化方案。
(2)半虚拟化
虚拟化是另一种类似于全虚拟化的技术,它使用Hypervisor分享存取底层的硬件,但是它的guest操作系统集成了虚拟化方面的代码。该方法无需重新编译或引起陷阱,因为操作系统自身能够与虚拟进程进行很好的协作。
(3)硬件支持的全虚拟化
硬件支持的全虚拟化:硬件支持的虚拟化层翻译--》kvm==》美国人懂中文了
1.2.3 容器虚拟化
Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack 集群和其他的基础应用平台。
Docker通常用于如下场景:
² web应用的自动化打包和发布;
² 自动化测试和持续集成、发布;
² 在服务型环境中部署和调整数据库或其他的后台应用;
² 从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的PaaS环境。
1.2.4 虚拟化的优势
①更高的资源利用率——虚拟可支持实现物理资源和资源池的动态共享,提高资源利用率,特别是针对那些平均需求远低于需要为其提供专用资源的不同负载。
②降低管理成本——虚拟可通过以下途径提高工作人员的效率:减少必须进行管理的物理资源的数量;隐藏物理资源的部分复杂性;通过实现自动化、获得更好的信息和实现中央管理来简化公共管理任务;实现负载管理自动化。另外,虚拟还可以支持在多个平台上使用公共的工具。
③提高使用灵活性——通过虚拟可实现动态的资源部署和重配置,满足不断变化的业务需求。
④提高安全性——虚拟可实现较简单的共享机制无法实现的隔离和划分,这些特性可实现对数据和服务进行可控和安全的访问。
⑤更高的可用性——虚拟可在不影响用户的情况下对物理资源进行删除、升级或改变。
⑥更高的可扩展性——根据不同的产品,资源分区和汇聚可支持实现比个体物理资源小得多或大得多的虚拟资源,这意味着您可以在不改变物理资源配置的情况下进行规模调整。
⑦互操作性和投资保护——虚拟资源可提供底层物理资源无法提供的与各种接口和协议的兼容性。
⑧改进资源供应——与个体物理资源单位相比,虚拟能够以更小的单位进行资源分配。
1.3 KVM简介
1.3.1 KVM简介
KVM 全称是 基于内核的虚拟机(Kernel-based Virtual Machine),它是一个 Linux 的一个内核模块,该内核模块使得 Linux 变成了一个 Hypervisor:
² 它由 Quramnet 开发,该公司于 2008年被 Red Hat 收购。
² 它支持 x86 (32 and 64 位), s390, Powerpc 等 CPU。
² 它从 Linux 2.6.20 起就作为一模块被包含在 Linux 内核中。
² 它需要支持虚拟化扩展的 CPU。
² 它是完全开源的。
² KVM虚拟机=KVM内核模块+QEMU模拟器
1.3.2 KVM的架构
KVM是linux内核的模块,它需要CPU的支持,采用硬件辅助虚拟化技术Intel-VT,AMD-V,内存的相关如Intel的EPT和AMD的RVI技术,Guest OS的CPU指令不用再经过Qemu转译,直接运行,大大提高了速度,KVM通过/dev/kvm暴露接口,用户态程序可以通过ioctl函数来访问这个接口。
KVM内核模块本身只能提供CPU和内存的虚拟化,所以它必须结合QEMU才能构成一个完成的虚拟化技术。
1.3.3 QEMU与KVM
qemu将KVM整合进来,通过ioctl调用/dev/kvm接口,将有关CPU指令的部分交由内核模块来做。kvm负责cpu虚拟化+内存虚拟化,实现了cpu和内存的虚拟化,但kvm不能模拟其他设备。qemu模拟IO设备(网卡,磁盘等),kvm加上qemu之后就能实现真正意义上服务器虚拟化。因为用到了上面两个东西,所以称之为qemu-kvm。
Qemu模拟其他的硬件,如Network, Disk,同样会影响这些设备的性能,于是又产生了pass through半虚拟化设备virtio_blk, virtio_net,提高设备性能。
KVM虚拟机是基于linux内核虚拟化,自linux2.6.20之后就集成在linux的各个主要发行版本中。它使用linux自身的调度器进行管理,所以相对于xen,其核心源码很少。KVM的虚拟化需要硬件的支持(如intel VT技术或者AMD V技术),是基于硬件的完全虚拟化。而xen早期则是基于软件模拟的para-virtualization,新版本是基于硬件支持的完全虚拟化。
qemu是一种模拟处理器,现在运用最多的就是将KVM和QEMU结合起来。
准确来说,KVM是Linux kernel的一个模块,可以用命令modprobe去加载KVM模块。加载了该模块后,才能进一步通过工具创建虚拟机。但是仅有KVM模块是不够的。因为用户无法直接控制内核去做事情,还必须有一个运行在用户空间的工具才行。这个用户空间的工具,kvm开发者选择了已经成型的开源虚拟化软件QEMU。说起来QEMU也是一个虚拟化软件。它的特点是可虚拟不同的CPU。比如说在x86的CPU上可虚拟一个power的CPU,并可利用它编译出可运行在power上的CPU,并可利用它编译出可运行在power上的程序。KVM使用了QEMU的一部分,并稍加改造,就成了可控制KVM的用户空间工具了。所以你会看到,官方提供的KVM下载有两大部分(qemu和kvm)三个文件(KVM模块、QEMU工具以及二者的合集)。也就是说,你可以只升级KVM模块,也可以只升级QEMU工具。
QEMU是一个开源项目,实际就是一台硬件模拟器,可以模拟许多硬件,包括X86架构处理器、AMD64架构处理器等。
QEMU的好处:因为是纯软件模拟,所以可以支持的平台模拟支持的设备。
QEMU的缺点:是纯软件模拟,所以非常慢。
KVM只是内核模块,只提供CPU和内存。所以还使用qemu模拟io设备如磁盘网卡。
1.3.4 KVM 是实现拦截虚机的 I/O 请求的原理:
现代 CPU 本身了对特殊指令的截获和重定向的硬件支持,甚至新的硬件会提供额外的资源来帮助软件实现对关键硬件资源的虚拟化从而提高性能。以 X86 平台为例,支持虚拟化技术的 CPU 带有特别优化过的指令集来控制虚拟化过程。通过这些指令集,VMM 很容易将客户机置于一种受限制的模式下运行,一旦客户机视图访问物理资源,硬件会暂停客户机的运行,将控制权交回给 VMM 处理。VMM 还可以利用硬件的虚级化增强机制,将客户机在受限模式下对一些特定资源的访问,完全由硬件重定向到 VMM 指定的虚拟资源,整个过程不需要暂停客户机的运行和 VMM 的参与。由于虚拟化硬件提供全新的架构,支持操作系统直接在上面运行,无需进行二进制转换,减少了相关的性能开销,极大简化了VMM的设计,使得VMM性能更加强大。从 2005 年开始,Intel 在其处理器产品线中推广 Intel Virtualization Technology 即 IntelVT 技术。
1.3.5 Libvirt与KVM
libvirt是目前使用最为广泛的对KVM虚拟机进行管理的工具和API。Libvirtd是一个daemon进程,可以被本地的virsh调用,也可以被远程的virsh调用,Libvirtd调用qemu-kvm操作虚拟机。
组成 :
n 一套API的lib库,支持主流的编程语言,包括c,python。ruby等。
n libvirtd服务。
n 命令行工具virsh
1.3.6 openstack, kvm, qemu-kvm以及libvirt之间的关系
VM是最底层的hypervisor,它是用来模拟CPU的运行,它缺少了对network和周边I/O的支持,所以我们是没法直接用它的。
QEMU-KVM就是一个完整的模拟器,它是构建基于KVM上面的,它提供了完整的网络和I/O支持。
Openstack不会直接控制qemu-kvm,它会用一个叫libvirt的库去间接控制qemu-kvm。libvirt提供了跨VM平台的功能,它可以控制除了QEMU之外的模拟器,包括vmware, virtualbox, xen等等。
所以为了openstack的跨VM性,所以openstack只会用libvirt而不直接用qemu-kvm。libvirt还提供了一些高级的功能,例如pool/vol管理。
1.4 KVM使用
1.4.1 虚拟机/服务器开启虚拟化
在BIOS开启虚拟化
虚拟机版本是新版
虚拟机开启虚拟化配置
1.4.2 KVM安装
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo yum -y install qemu-kvm qemu-kvm-tools virt-manager libvirt virt-install python-virtinst-0.600.0-29.el6.noarch # 一套Python的虚拟机安装工具 gpxe-roms-qemu-0.9.7-6.14.el6.noarch # 虚拟机iPXE的启动固件,支持虚拟机从网络启动 virt-manager-0.9.0-29.el6.x86_64 # 基于Libvirt的图像化虚拟机管理软件,需要图形界面操作系统 qemu-img-0.12.1.2-2.479.el6.x86_64 # 用于操作虚拟机硬盘镜像的创建、查看和格式转化 libvirt-python-0.10.2-54.el6.x86_64 # libvirt为Python提供的API qemu-kvm-0.12.1.2-2.479.el6.x86_64 # KVM在用户空间运行的程序 qemu-kvm-tools-0.12.1.2-2.479.el6.x86_64 libvirt-0.10.2-54.el6.x86_64 # 用于管理虚拟机,它提供了一套虚拟机操作API libvirt-client-0.10.2-54.el6.x86_64 # Libvirt的客户端,最重要的功能之一就是就在宿主机关机时可以通知虚拟机也关机,使虚拟机系统正常关机,而不是被强制关机,造成数据丢失 virt-top-1.0.4-3.15.el6.x86_64 # 类似于top命令,查看虚拟机的资源使用情况 virt-what-1.11-1.2.el6.x86_64 # 在虚拟机内部执行,查看虚拟机运行的虚拟化平台 virt-viewer-0.5.6-8.el6.x86_64 # 显示虚拟机的控制台console [root@oldboyedu ~]# mkdir -p /application/tools/ [root@oldboyedu ~]# dd if=/dev/sr0 of=/application/tools/CentOS7_2.iso 查看: [root@oldboyedu39 ~]# lsmod |grep kvm kvm_intel 162153 0 kvm 525259 1 kvm_intel [root@oldboyedu39 ~]# grep -Eo '(vmx|svm)' /proc/cpuinfo vmx vmx [root@oldboyedu39 ~]# cd /application/tools/ [root@oldboyedu39 tools]# ls CentOS-7-x86_64-DVD-1511.iso 启动服务 systemctl start libvirtd.service [root@oldboyedu39 ~]# mkdir -p /application/kvm_data [root@oldboyedu39 ~]# cd /application/kvm_data [root@oldboyedu39 kvm_data]# qemu-img create -f qcow2 /application/kvm_data/moban.qcow2 20G Formatting '/application/kvm_data/moban.qcow2', fmt=qcow2 size=21474836480 encryption=off cluster_size=65536 lazy_refcounts=off [root@oldboyedu39 kvm_data]# ll -h total 196K -rw-r--r-- 1 root root 193K Oct 23 10:17 moban.qcow2 [root@oldboyedu39 kvm_data]#
1.5 创建虚拟机
1.5.1 创建硬盘
1.5.2 安装虚拟机
[root@oldboyedu39 ~]# mkdir -p /application/kvm_data [root@oldboyedu39 ~]# cd /application/kvm_data [root@oldboyedu39 kvm_data]# qemu-img create -f qcow2 /application/kvm_data/moban.qcow2 20G Formatting '/application/kvm_data/moban.qcow2', fmt=qcow2 size=21474836480 encryption=off cluster_size=65536 lazy_refcounts=off [root@oldboyedu39 kvm_data]# ll -h total 196K -rw-r--r-- 1 root root 193K Oct 23 10:17 moban.qcow2 [root@oldboyedu39 kvm_data]# qemu-img info moban.qcow2 image: moban.qcow2 file format: qcow2 virtual size: 20G (21474836480 bytes) disk size: 196K cluster_size: 65536 Format specific information: compat: 1.1 lazy refcounts: false [root@oldboyedu39 kvm_data]# virt-install --virt-type=kvm --name=c72-moban --vcpus=1 -r 1024 -c /application/tools/CentOS7_2.iso --network bridge=br0 --graphics vnc,listen=0.0.0.0 --noautoconsole --os-type=linux --os-variant=rhel7 --disk path=/application/kvm_data/moban.qcow2,size=20,format=qcow2
1.5.3 命令使用
[root@oldboyedu39 kvm_data]# virsh start c72-moban 开机 Domain c72-moban started [root@oldboyedu39 kvm_data]# virsh list 查看状态 Id Name State ---------------------------------------------------- 2 c72-moban running [root@oldboyedu39 kvm_data]# 生成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 resume name
1.5.4 注意
模板机配置文件 [root@oldboyedu39 ~]# cd /etc/libvirt/qemu/ [root@oldboyedu39 qemu]# ls c72-moban.xml networks [root@oldboyedu39 qemu]# 磁盘文件 [root@oldboyedu39 tools]# cd /application/kvm_data/ [root@oldboyedu39 kvm_data]# ls moban.qcow2 [root@oldboyedu39 kvm_data]#
1.6 磁盘文件格式介绍
raw和qcow2简单区别
² raw不支持快照
² qcow2支持快照
1.6.1 raw介绍
老牌的格式了,用一个字来说就是裸,也就是赤裸裸,你随便dd一个file就模拟了一个raw格式的镜像。由于裸的彻底,性能上来说的话还是不错的。目前来看,KVM和XEN默认的格式好像还是这个格式。因为其原始,有很多原生的特性,例如直接挂载也是一件简单的事情。
裸的好处还有就是简单,支持转换成其它格式的虚拟机镜像对裸露的它来说还是很简单的(如果其它格式需要转换,有时候还是需要它做为中间格式),空间使用来看,这个很像磁盘,使用多少就是多少(du -h看到的大小就是使用大小),但如果你要把整块磁盘都拿走的话得全盘拿了(copy镜像的时候),会比较消耗网络带宽和I/O。接下来还有个有趣的问题,如果那天你的硬盘用着用着不够用了,你咋办,在买一块盘。但raw格式的就比较犀利了,可以在原来的盘上追加空间:
dd if=/dev/zero of=zeros.raw bs=1024k count=4096(先创建4G的空间)
cat foresight.img zeros.raw > new-foresight.img(追加到原有的镜像之后)
当然,好东西是吹出来的,谁用谁知道,还是有挺多问题的。由于原生的裸格式,不支持snapshot也是很正常的。传说有朋友用版本管理软件对raw格式的文件做版本管理从而达到snapshot的能力,估计可行,但没试过,这里也不妄加评论。但如果你使用LVM的裸设备,那就另当别论。说到LVM还是十分的犀利的,当年用LVM做虚拟机的镜像,那性能杠杠的。而且现在好多兄弟用虚拟化都采用LVM来做的。在LVM上做了很多的优化,国外听说也有朋友在LVM增量备份方面做了很多的工作。目前来LVM的snapshot、性能、可扩展性方面都还是有相当的效果的。目前来看的话,备份的话也问题不大。就是在虚拟机迁移方面还是有很大的限制。但目前虚拟化的现状来看,真正需要热迁移的情况目前需求还不是是否的强烈。虽然使用LVM做虚拟机镜像的相关公开资料比较少,但目前来看牺牲一点灵活性,换取性能和便于管理还是不错的选择。
1.6.2 qcow2
现在比较主流的一种虚拟化镜像格式,经过一代的优化,目前qcow2的性能上接近raw裸格式的性能,这个也算是redhat的官方渠道了,哈哈,希望有朋友能拍他们砖:
对于qcow2的格式,几点还是比较突出的,qcow2的snapshot,可以在镜像上做N多个快照:
² 更小的存储空间,即使是不支持holes的文件系统也可以(这下du -h和ls -lh看到的就一样了)
² Copy-on-write support, where the image only represents changes made to an underlying disk image(这个特性SUN ZFS表现的淋漓尽致)
² 支持多个snapshot,对历史snapshot进行管理
² 支持zlib的磁盘压缩
² 支持AES的加密
1.6.3 vmdk
Mware的格式,这个格式说的蛋疼一点就有点牛X,原本VMware就是做虚拟化起家,自己做了一个集群的VMDK的pool,做了自己的虚拟机镜像格式。又拉着一些公司搞了一个OVF的统一封包。从性能和功能上来说,vmdk应该算最出色的,由于vmdk结合了VMware的很多能力,目前来看,KVM和XEN使用这种格式的情况不是太多。但就VMware的Esxi来看,它的稳定性和各方面的能力还是可圈可点。
1.7 KVM克隆
通用方法:既能够本机克隆,也能跨机克隆
前提:关机克隆
[root@oldboyedu39 qemu]# virsh list --all 查看状态 Id Name State ---------------------------------------------------- - c72-moban shut off [root@oldboyedu39 qemu]# 克隆磁盘文件 [root@oldboyedu39 kvm_data]# virsh dumpxml c72-moban >/tmp/moban.xml [root@oldboyedu39 kvm_data]# cp moban.qcow2 clone.qcow2 [root@oldboyedu39 kvm_data]# ll total 3034052 -rw-r--r-- 1 root root 1553465344 Oct 23 11:34 clone.qcow2 -rw-r--r-- 1 root root 1553465344 Oct 23 11:32 moban.qcow2 [root@oldboyedu39 kvm_data]# pwd /application/kvm_data [root@oldboyedu39 kvm_data]# ll -h total 2.9G -rw-r--r-- 1 root root 1.5G Oct 23 11:34 clone.qcow2 -rw-r--r-- 1 root root 1.5G Oct 23 11:32 moban.qcow2 [root@oldboyedu39 kvm_data]# 克隆配置文件 [root@oldboyedu39 ~]# sed -i "2s#c72-moban#c72-clone#;3s#.*#`uuidgen` #;s#moban.qcow2#clone.qcow2#;s#^.*# #" /tmp/moban.xml 对比 [root@oldboyedu39 ~]# diff /tmp/moban.xml{,.ori} 2,3c2,3 < c72-clone <39fed509-08ef-4892-b429-3206f9e292ae --- >c72-moban >da066b7c-a502-43b4-b1ae-08f59f6d5225 34c34 < --- > 67c67 <--- > [root@oldboyedu39 ~]# [root@oldboyedu39 ~]# virsh define /tmp/moban.xml 定义域 c72-clone(从 /tmp/moban.xml) [root@oldboyedu39 ~]# virsh list --all Id 名称 状态 ---------------------------------------------------- - c72-clone 关闭 - c72-moban 关闭 [root@oldboyedu39 ~]# 开机 [root@oldboyedu39 ~]# virsh start c72-clone 域 c72-clone 已开始 [root@oldboyedu39 ~]# virsh start c72-moban 域 c72-moban 已开始 [root@oldboyedu39 ~]# [root@oldboyedu39 ~]# virsh list --all Id 名称 状态 ---------------------------------------------------- 3 c72-clone running 4 c72-moban running [root@oldboyedu39 ~]#
注意事项
1.克隆的CentOS6虚拟机,首先要做的是:
² 清除网卡配置文件的UUID和MAC地址,否则克隆后网卡错乱
² 清空> /etc/udev/rules.d/70-persistent-net.rules,否则克隆后网卡错乱
² 最后关闭虚拟机,在虚拟机中使用halt命令关机。
2.克隆CentOS7可以直接克隆:
² 清除网卡配置文件的UUID和MAC地址(不清除网卡也能启动)
² 关机做克隆
1.8 KVM快照
创建快照(关机做快照节省空间) [root@oldboyedu39 ~]# virsh shutdown c72-moban 域 c72-moban 被关闭 [root@oldboyedu39 ~]# virsh shutdown c72-clone 域 c72-clone 被关闭 [root@oldboyedu39 ~]# [root@oldboyedu39 ~]# virsh shutdown c72-clone 创建快照 域 c72-clone 被关闭 [root@oldboyedu39 ~]# virsh snapshot-create-as c72-clone c72-clone-kuaizhao1 已生成域快照 c72-clone-kuaizhao1 [root@oldboyedu39 ~]# virsh snapshot-list c72-clone 查看快照 名称 生成时间 状态 ------------------------------------------------------------ c72-clone-kuaizhao1 2017-10-23 12:05:44 +0800 shutoff [root@oldboyedu39 ~]# [root@oldboyedu39 ~]# virsh snapshot-revert c72-clone c72-clone-kuaizhao1#恢复快照 virsh snapshot-delete c72-clone c72-clone-kuaizhao1 # 删除快照
1.9 KVM桥接网络
默认KVM的网络是NAT模式,那如何让KVM的网络和宿主机同网段呢?这就需要桥接网卡了
Bridge方式即虚拟网桥的网络连接方式,是客户机和子网里面的机器能够互相通信。可以使虚拟机成为网络中具有独立ip的主机。
桥接网络(也叫物理设备共享)被用作把一个物理设备复制到另一台虚拟机。网桥多用做高级设置,特别是主机多个网络接口的情况。
#四处需要修改c72-moban 00e0ff50-c410-40d8-a46e-8919199b2828 [root@oldboyedu39 ~]# cp /etc/sysconfig/network-scripts/{ifcfg-eth0,ifcfg-br0} #复制网卡 [root@oldboyedu39 ~]# cat>/etc/sysconfig/network-scripts/ifcfg-eth0< DEVICE=eth0 > TYPE=Ethernet > ONBOOT=yes > BRIDGE=br0 > EOF [root@oldboyedu39 ~]# [root@oldboyedu39 ~]# sed -i.ori 's#Ethernet#Bridge#;s#eth0#br0#g' /etc/sysconfig/network-scripts/ifcfg-br0 [root@oldboyedu39 ~]# diff /etc/sysconfig/network-scripts/ifcfg-br0{,.ori} 1c1 < TYPE=Bridge --- > TYPE=Ethernet 7c7 < NAME=br0 --- > NAME=eth0 9c9 < DEVICE=br0 ---猫 > DEVICE=eth0 [root@oldboyedu39 ~]# 并把ifcfg-br0配置文件的uuid删除 systemctl restart network [root@oldboyedu kvm_data]# brctl show bridge name bridge id STP enabled interfaces br0 8000.000c29450547 no eth0 virbr0 8000.fe5400e2f95e yes vnet0 新创建主机采用桥接网卡将 --network network=default换成--network bridge=br0。 对已经创建的主机,修改成桥接方式。修改配置文件
a.关闭虚拟机 b.virsh edit c72-moban 给虚拟机再次添加一块新的网卡,虚拟机需要运行状态。 virsh attach-interface c72-clone --type bridge --source br0 [root@kvm1 qemu]# virsh --help | grep bridge iface-bridge 生成桥接设备并为其附加一个现有网络设备 iface-unbridge 分离其辅助设备后取消定义桥接设备 [root@kvm1 qemu]# virsh iface-bridge eth0 br0