Bootstrap

虚拟化技术KVM入门学习

一、虚拟化技术概述

  虚拟化[Virtualization]技术最早出现在 20 世纪 60 年代的 IBM ⼤型机系统,在70年代的 System370 系列中逐渐流⾏起来,这些机器通过⼀种叫虚拟机监控器[Virtual Machine Monitor,VMM]的程序在物理硬件之上⽣成许多可以运⾏独⽴操作系统软件的虚拟机[Virtual Machine]实例。随着近年多核系统、集群、⽹格甚⾄云计算的⼴泛部署,虚拟化技术在商业应⽤上的优势⽇益体现,不仅降低了 IT 成本,⽽且还增强了系统安全性和可靠性,虚拟化的概念也逐渐深⼊到⼈们⽇常的⼯作与⽣活中。
  虚拟化是⼀个⼴义的术语,对于不同的⼈来说可能意味着不同的东⻄,这要取决他们所处的环境。在计算机科学领域中,虚拟化代表着对计算资源的抽象,⽽不仅仅局限于虚拟机的概念。例如对物理内存的抽象,产⽣了虚拟内存技术,使得应⽤程序认为其⾃身拥有连续可⽤的地址空间[Address Space],⽽实际上,应⽤程序的代码和数据可能是被分隔成多个碎⽚⻚或段),甚⾄被交换到磁盘、闪存等外部存储器上,即使物理内存不⾜,应⽤程序也能顺利执⾏。

二、主流虚拟化介绍

1、虚拟化技术主要分类

  • 平台虚拟化(Platform Virtualization)针对计算机和操作系统的虚拟化。
  • 资源虚拟化(Resource Virtualization)针对特定的系统资源的虚拟化,⽐如内存、存储、⽹络资源等。
  • 应⽤程序虚拟化(Application Virtualization)包括仿真、模拟、解释技术等。

2、平台虚拟化技术分类

  我们通常所说的虚拟化主要是指平台虚拟化技术,通过使⽤控制程序(Control Program,也被称为Virtual Machine Monitor 或Hypervisor),隐藏特定计算平台的实际物理特性,为⽤户提供抽象的、统⼀的、模拟的计算环境(称为虚拟机)。虚拟机中运⾏的操作系统被称为客户机操作系统(Guest OS),运⾏虚拟机监控器的操作系统被称为主机操作系统(Host OS),当然某些虚拟机监控器可以脱离操作系统直接运⾏在硬件之上(如 VMWARE 的 ESX 产品)。运⾏虚拟机的真实系统我们称之为主机系统。

  • 操作系统级虚拟化(Operating System Level Virtualization)
      在传统操作系统中,所有⽤户的进程本质上是在同⼀个操作系统的实例中运⾏,因此内核或应⽤程序的缺陷可能影响到其它进程。操作系统级虚拟化是⼀种在服务器操作系统中使⽤的轻量级的虚拟化技术,内核通过创建多个虚拟的操作系统实例(内核和库)来隔离不同的进程,不同实例中的进程完全不了解对⽅的存在。
      ⽐较著名的有 Solaris Container,FreeBSD Jail 和 OpenVZ 等。
  • 部分虚拟化(Partial Virtualization)
      VMM 只模拟部分底层硬件,因此客户机操作系统不做修改是⽆法在虚拟机中运⾏的,其它程序可能也需要进⾏修改。在历史上,部分虚拟化是通往全虚拟化道路上的重要⾥程碑,最早出现在第⼀代的分时系统 CTSS 和 IBM M44/44X 实验性的分⻚系统中。
  • 全虚拟化(Full Virtualization)
      全虚拟化是指虚拟机模拟了完整的底层硬件,包括处理器、物理内存、时钟、外设等,使得为原始硬件设计的操作系统或其它系统软件完全不做任何修改就可以在虚拟机中运⾏。
      操作系统与真实硬件之间的交互可以看成是通过⼀个预先规定的硬件接⼝进⾏的。全虚拟化 VMM 以完整模拟硬件的⽅式提供全部接⼝(同时还必须模拟特权指令的执⾏过程)。举例⽽⾔,x86 体系结构中,对于操作系统切换进程⻚表的操作,真实硬件通过提供⼀个特权CR3 寄存器来实现该接⼝,操作系统只需执⾏ "mov pgtable,%%cr3"汇编指令即可。
      全虚拟化 VMM 必须完整地模拟该接⼝执⾏的全过程。如果硬件不提供虚拟化的特殊⽀持,那么这个模拟过程将会⼗分复杂:⼀般⽽⾔,VMM 必须运⾏在最⾼优先级来完全控制主机系统,⽽ Guest OS 需要降级运⾏,从⽽不能执⾏特权操作。当 Guest OS 执⾏前⾯的特权汇编指令时,主机系统产⽣异常(General Protection Exception),执⾏控制权重新从 Guest OS转到 VMM ⼿中。VMM 事先分配⼀个变量作为影⼦ CR3 寄存器给 Guest OS,将 pgtable 代表的客户机物理地址(Guest Physical Address)填⼊影⼦ CR3 寄存器,然后 VMM 还需要pgtable 翻译成主机物理地址(Host Physical Address)并填⼊物理 CR3 寄存器,最后返回到 Guest OS中。随后 VMM 还将处理复杂的 Guest OS 缺⻚异常(Page Fault)。
      ⽐较著名的全虚拟化 VMM 有 Microsoft Virtual PC、VMware Workstation、Sun VirtualBox、Parallels Desktop for Mac 和QEMU
  • 超虚拟化(Paravirtualization)
      这是⼀种修改 Guest OS 部分访问特权状态的代码以便直接与 VMM 交互的技术。在超虚拟化虚拟机中,部分硬件接⼝以软件的形式提供给客户机操作系统,这可以通过 Hypercall(VMM提供给 Guest OS 的直接调⽤,与系统调⽤类似)的⽅式来提供。例如,Guest OS 把切换⻚表的代码修改为调⽤ Hypercall 来直接完成修改影⼦ CR3 寄存器和翻译地址的⼯作。由于不需要产⽣额外的异常和模拟部分硬件执⾏流程,超虚拟化可以⼤幅度提⾼性能,⽐较著名的VMM 有 Denali、Xen。
  • 硬件辅助虚拟化(Hardware-Assisted Virtualization)
      硬件辅助虚拟化是指借助硬件(主要是主机处理器)的⽀持来实现⾼效的全虚拟化。例如有了Intel-VT 技术的⽀持,Guest OS 和 VMM 的执⾏环境⾃动地完全隔离开来,Guest OS 有⾃⼰的"“套寄存器”,可以直接运⾏在最⾼级别。因此在上⾯的例⼦中,Guest OS 能够执⾏修改⻚表的汇编指令。Intel-VT 和 AMD-V 是⽬前 x86 体系结构上可⽤的两种硬件辅助虚拟化技术。

  这种分类并不是绝对的,⼀个优秀的虚拟化软件往往融合了多项技术。例如 VMware Workstation是⼀个著名的全虚拟化的 VMM,但是它使⽤了⼀种被称为动态⼆进制翻译的技术把对特权状态的访问转换成对影⼦状态的操作,从⽽避免了低效的 Trap-And-Emulate 的处理⽅式,这与超虚拟化相似,只不过超虚拟化是静态地修改程序代码。对于超虚拟化⽽⾔,如果能利⽤硬件特性,那么虚拟机的管理将会⼤⼤简化,同时还能保持较⾼的性能。

三、KVM虚拟化技术简介

1、KVM架构及解析

在这里插入图片描述

  • 解析:
      从rhel6开始使⽤,红帽公司直接把KVM的模块做成了内核的⼀部分。
      xen⽤在rhel6之前的企业版中默认内核不⽀持,需要重新安装带xen功能的内核
      KVM 针对运⾏在 x86 硬件上的、驻留在内核中的虚拟化基础结构。KVM 是第⼀个成为原⽣ Linux 内核(2.6.20)的⼀部分的hypervisor,它是由 Avi Kivity 开发和维护的,现在归 Red Hat 所有。
      这个 hypervisor 提供 x86 虚拟化,同时拥有到 PowerPC® 和 IA64 的通道。另外,KVM 最近还添加了对对称多处理(SMP)主机(和来宾)的⽀持,并且⽀持企业级特性,⽐如活动迁移(允许来宾操作系统在物理服务器之间迁移)。
       KVM 是作为内核模块实现的,因此 Linux 只要加载该模块就会成为⼀个hypervisor。KVM 为⽀持hypervisor 指令的硬件平台提供完整的虚拟化(⽐如 Intel Virtualization Technology [Intel VT] 或AMD Virtualization [AMD-V] 产品)。KVM 还⽀持准虚拟化来宾操作系统,包括 Linux 和 Windows。
      这种技术由两个组件实现。第⼀个是可加载的 KVM 模块,当在 Linux 内核安装该模块之后,它就可以管理虚拟化硬件,并通过 /proc ⽂件系统公开其功能。第⼆个组件⽤于 PC 平台模拟,它是由修改版QEMU 提供的。QEMU 作为⽤户空间进程执⾏,并且在来宾操作系统请求⽅⾯与内核协调。
      当新的操作系统在 KVM 上启动时(通过⼀个称为 KVM 的实⽤程序),它就成为宿主操作系统的⼀个进程,因此就可以像其他进程⼀样调度它。但与传统的 Linux 进程不⼀样,来宾操作系统被 hypervisor标识为处于 “来宾” 模式(独⽴于内核和⽤户模式)。
      每个来宾操作系统都是通过 /dev/KVM 设备映射的,它们拥有⾃⼰的虚拟地址空间,该空间映射到主机内核的物理地址空间。如前所述,KVM 使⽤底层硬件的虚拟化⽀持来提供完整的(原⽣)虚拟化。I/O请求通过主机内核映射到在主机上(hypervisor)执⾏的 QEMU 进程。
      KVM 在 Linux 环境中以主机的⽅式运⾏,不过只要底层硬件虚拟化⽀持,它就能够⽀持⼤量的来宾操作系统。

四、KVM软件安装

1、环境准备

  • 安装一台图形界面的虚拟机,
    内存大于等于8G:主机电脑内存为8G给于虚拟机内存在它自身以下,所以使用可能会卡;
    开启虚拟化引擎:一般支持勾线第一选项(虚拟化Intel VT-x或AMD-V/RVI),如果在检查CPU是否支持时报错在勾选第二选项和第三选项;
    在这里插入图片描述
    准备好环境之后启动虚拟机。

2、查看CPU是否支持VT技术

[root@localhost ~]# cat /proc/cpuinfo | grep -E 'vmx|svm'
#vmx是指当前cpu支持的是Intel的虚拟化。svm指支持的AMD的虚拟化。

3、清理环境,卸载原有KVM

#将原有的kvm卸载
[root@localhost ~]# yum remove `rpm -qa | egrep 'qemu|virt|KVM'` -y
#删除原kvm的磁盘镜像存储的目录和配置文件目录
[root@localhost ~]# rm -rf /var/lib/libvirt /etc/libvirt/

4、安装软件

在centos7安装

#查看版本
[root@localhost run]# uname -r
3.10.0-1160.81.1.el7.x86_64
#安装软件及依赖
[root@localhost run]# yum install *qemu* *virt* librbd1-devel -y

注:qemu-KVM:主包  
  libvirt:API接⼝  
  virt-manager:图形管理程序
  在kvm技术中,应用到的其实就是qemu+kvm

5、启动服务

#启动服务
[root@localhost run]# systemctl start libvirtd
#查看服务状态
[root@localhost run]# systemctl status libvirtd
#设置为开机自启
[root@localhost run]# systemctl enable libvirtd

6、查看kvm模块加载

[root@localhost ~]# lsmod | grep kvm
kvm_intel             188793  0 
kvm                   653928  1 kvm_intel
irqbypass              13503  1 kvm

五、Guest OS安装

安装方式:

  • 图形方式(相对简单,重点);
  • 文本模式(需要现场配置虚拟机规格);
  • 命令⾏模式(重中之重 最常⽤ 模板镜像+配置⽂件 ⽅式配置规格);
  • 通过⻜机驾驶舱(相当于web界面的应用)安装和管理虚拟机。
    飞机驾驶舱安装:
#下载
[root@localhost ~]# yum install -y cockpit
#启动服务
[root@localhost ~]# systemctl start cockpit

注:cockpit默认服务端口为9090,访问:主机ip:9090
在这里插入图片描述

1、图形模式安装Guest OS

安装前需要注意:
安装前把飞机驾驶舱服务关掉: systemctl stop cockpit.socket
在开始前需上传一个镜像:

[root@localhost ~]# ll
总用量 4415488
-rw-r--r-- 1 root root 4521459712 21 18:36 CentOS-7-x86_64-DVD-1708.iso

打开虚拟机图形界面安装,若没有相关命令可以使用yum下载

[root@localhost ~]# virt-manager 

也可以使用任务栏上的菜单打开
在这里插入图片描述
打开弹出程序窗口
在这里插入图片描述
  然后新建虚拟机,根据窗口提示步骤一步步安装,这里实验选择的是“本地安装介质”,选择镜像文件,设置内存和CPU核数,设置存储大小(注意存储大小至少大于2G),命名虚拟机名称并选择网络方式(实验选择的默认方式NAT),设置完成,等待进入虚拟机进行安装配置,到这里就跟安装VMware一样了。

注:我这里安装过程在点击完成时弹窗提示了一个这样的错:“无法完成安装:'不支持的配置:CPUmode ‘custom’ for x86_64 kvm domain onx86_64 host is not supported by hypervisor” 我的解决方法是直接重启系统,然后重新来就行了.

2、完全文本方式安装

极端情况:服务器没有图形 客户端也没有图形

#virt-install --connect qemu:///system -n vm6 -r 512 --disk path=/virhost/vmware/vm6.img,size=7 --os-type=linux --os-variant=rhel6 --vcpus=1 --network bridge=br0 --location=http://127.0.0.1/rhel6u4 -x console=ttyS0 --nographics

#virt-install --connect qemu:///system -n vm9 -r 2048 --disk path=/var/lib/libvirt/images/vm9.img,size=7 --os-type=linux --os-variant=centos7.0 --vcpus=1 --location=ftp://192.168.100.230/centos7u3 -x console=ttyS0 --nographics

注释:–coonect 表示连接qemu:///system(你的系统); -n 表示给安装的虚拟机取名 vm9; -r 表示以兆为单位给于内存2048;
–disk path= 表示镜像文件存放的路径; size 表示磁盘大小; --os-type=表示系统类型;–os-variant表示系统版本; --vcpus表示指定CPU核数; --location表示指定安装服务器及路径目录; -x console表示分配的终端; --nographics表示安装模式(这个参数是指没有图形界面的)。
注意:⽤这种⽅式安装的操作系统,⼤⼩写会胡乱变化,不影响远程操作;
   内存必须2G以上。

查看KVM⽀持的OS版本:

[root@localhost ~]# man virt-install
#查看参数词条
[root@localhost ~]# osinfo-query os | grep centos
#查看支持版本

排错:
安装过程中:
⼿动配置IP地址
到url位置找不到路径,要返回去⼿动选择url,重新配置url为ftp://192.168.100.230/rhel6u4,这⾥的ip不要写127.0.0.1⽽是br0的ip 给虚拟机指定的内存必须⼤于2048M,不然报错如下:
dracut-initqueue[552]: /sbin/dmsquash-live-root: line 273: printf:
write error: No space left on device
逃脱符:
Escape character is ^]

3、命令行模式安装

虚拟机组成部分:
1.虚拟机配置文件

[root@localhost ~]# ls /etc/libvirt/qemu
networks  vm1.xml

2.储存虚拟机的介质

[root@localhost ~]# ll /var/lib/libvirt/images/
总用量 5243908
-rw------- 1 qemu qemu 5369757696 22 15:10 vm1.qcow2

根据配置文件创建虚拟机

1.需要有磁盘镜像文件
[root@localhost ~]# cd /etc/libvirt/qemu/
[root@localhost qemu]# cp vm1.xml vm2.xml 
2.需要有配置⽂件
[root@localhost qemu]# cd /var/lib/libvirt/images/
[root@localhost images]# cp vm1.qcow2 vm2.img
3.配置⽂件需要修改必要的内容
[root@localhost ~]# vim /etc/libvirt/qemu/vm2.xml
<domain type='KVM'>    
<name>vm2</name>                           #修改虚拟机名称
<uuid>72535aa9-08b5-49ec-9ef9-0d48a2b2ff4d</uuid>      #修改设备唯一标识编号
<memory unit='KiB'>1024000</memory>
<currentMemory unit='KiB'>1024000</currentMemory>     #内存(可选更改)
<vcpu placement='static'>2</vcpu>                     #CPU核数(可选更改)
<os>
    <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
  </features>
  <cpu mode='custom' match='exact' check='partial'>
    <model fallback='allow'>Broadwell-noTSX-IBRS</model>
    <feature policy='require' name='md-clear'/>
    <feature policy='require' name='spec-ctrl'/>
    <feature policy='require' name='ssbd'/>
  </cpu>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
 <suspend-to-mem enabled='no'/>
 <suspend-to-disk enabled='no'/>
</pm>
<devices>
 <emulator>/usr/libexec/qemu-KVM</emulator>
 <disk type='file' device='disk'>
 <driver name='qemu' type='qcow2'/>
 <source file='/var/lib/libvirt/images/vm2.img'/>     #修改磁盘镜像文件名
 <target dev='vda' bus='virtio'/>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x06'
function='0x0'/>
 </disk>
 <disk type='file' device='disk'>
 <driver name='qemu' type='qcow2'/>
 <source file='/var/lib/libvirt/images/vm2-1.img'/>
 <target dev='vda' bus='virtio'/>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x16'
function='0x0'/>
 </disk>
 <controller type='usb' index='0' model='ich9-ehci1'>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
function='0x7'/>
 </controller>
 <controller type='usb' index='0' model='ich9-uhci1'>
 <master startport='0'/>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
function='0x0' multifunction='on'/>
 </controller>
 <controller type='usb' index='0' model='ich9-uhci2'>
 <master startport='2'/>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
function='0x1'/>
 </controller>
 <controller type='usb' index='0' model='ich9-uhci3'>
 <master startport='4'/>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x04'
function='0x2'/>
 </controller>
 <controller type='pci' index='0' model='pci-root'/>
 <controller type='virtio-serial' index='0'>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x05'
function='0x0'/>
 </controller>
 <interface type='network'>
 <mac address='52:54:00:c9:19:9b'/>      #修改Mac地址,不要地址冲突(注意只能修改后三段)
 <source network='default'/>
 <model type='virtio'/>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x03'
function='0x0'/>
 </interface>
 <serial type='pty'>
 <target type='isa-serial' port='0'>
 <model name='isa-serial'/>
 </target>
 </serial>
 <console type='pty'>
 <target type='serial' port='0'/>
 </console>
 <channel type='unix'>
 <target type='virtio' name='org.qemu.guest_agent.0'/>
 <address type='virtio-serial' controller='0' bus='0' port='1'/>
  <input type='mouse' bus='ps2'/>
 <input type='keyboard' bus='ps2'/>
 <memballoon model='virtio'>
 <address type='pci' domain='0x0000' bus='0x00' slot='0x07'
function='0x0'/>
 </memballoon>
</devices>
</domain> 
4.创建虚拟机
[root@localhost ~]# virsh define /etc/libvirt/qemu/vm2.xml
5.重启libvitd
[root@localhost images]# systemctl restart libvirtd.service 
6.宿主机开启路由转发
#编辑conf文件,在末行添加net.ipv4.ip_forward = 1
[root@localhost images]# vim /etc/sysctl.conf 
#输入命令使其生效
[root@localhost images]# sysctl -p
net.ipv4.ip_forward = 1

最后我们再使用virt-manager打开管理窗口查看vm2,启动看安装是否成功。

学习视频:
https://www.bilibili.com/video/BV11p4y1U7Na?p=1&vd_source=92ffd157bfd8ef398f23be5c7aba4d65

;