KVM介绍 虚拟化简史

Posted zengc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KVM介绍 虚拟化简史相关的知识,希望对你有一定的参考价值。

KVM介绍

技术分享图片

为什么需要CPU虚拟化

X86 操作系统是设计在直接运行在裸硬件设备上的,因此它们自动认为它们完全占有计算机

硬件。x86 架构提供四个特权级别给操作系统和应用程序来访问硬件。 Ring 是指 CPU 的

运行级别,Ring 0是高级别,Ring1次之,Ring2更次之…… 就 Linux+x86 来说, 操

作系统(内核)需要直接访问硬件和内存,因此它的代码需要运行在高运行级别  Ring0

上,这样它可以使用特权指令,控制中断、修改页表、访问设备等等。 

应用程序的代码运行在低运行级别上ring3上,不能做受控操作。如果要做,比如要访问

磁盘,写文件,那就要通过执行系统调用(函数),执行系统调用的时候,CPU的运行级别

会发生从ring3到ring0的切换,并跳转到系统调用对应的内核代码位置执行,这样内核就为

你完成了设备访问,完成之后再从ring0返回ring3。这个过程也称作用户态和内核态的切

换。

技术分享图片

那么,虚拟化在这里就遇到了一个难题,因为宿主操作系统是工作在 ring0 的,客户

操作系统就不能也在 ring0了,但是它不知道这一点,以前执行什么指令,现在还是执行什

么指令,但是没有执行权限是会出错的。所以这时候虚拟机管理程序(VMM)需要避免这件

事情发生。 虚机怎么通过VMM实现 Guest CPU 对硬件的访问,根据其原理不同有三种实现

技术:

1. 全虚拟化

2. 半虚拟化

3. 硬件辅助的虚拟化 

基于二进制翻译的全虚拟化(Full Virtualization with Binary Translation)

技术分享图片

客户操作系统运行在 Ring 1,它在执行特权指令时,会触发异常(CPU的机制,没权

限的指令会触发异常),然后 VMM 捕获这个异常,在异常里面做翻译,模拟,后返回到

客户操作系统内,客户操作系统认为自己的特权指令工作正常,继续运行。但是这个性能损

耗,就非常的大,简单的一条指令,执行完了事,现在却要通过复杂的异常处理过程。

异常 “捕获(trap)-翻译(handle)-模拟(emulate)” 过程:

技术分享图片

超虚拟化 (或者半虚拟化/操作系统辅助虚拟化)

 半虚拟化的思想就是,修改操作系统内核,替换掉不能虚拟化的指令,通过超级调

用(hypercall)直接和底层的虚拟化层hypervisor来通讯,hypervisor 同时也提供了超

级调用接口来满足其他关键内核操作,比如内存管理、中断和时间保持。

    这种做法省去了全虚拟化中的捕获和模拟,大大提高了效率。所以像XEN这种半虚拟

化技术,客户机操作系统都是有一个专门的定制内核版本,和x86、mips、arm这些内核版本

等价。这样以来,就不会有捕获异常、翻译、模拟的过程了,性能损耗非常低。这就是XEN

这种半虚拟化架构的优势。这也是为什么XEN只支持虚拟化Linux,无法虚拟化windows原

因,微软不改代码。

技术分享图片

硬件辅助的全虚拟化

 2005年后,CPU厂商Intel 和 AMD 开始支持虚拟化了。 Intel 引入了 Intel-VT

(Virtualization Technology)技术。 这种 CPU有 VMX root operation 和 VMX non

root operation两种模式,两种模式都支持Ring 0 ~ Ring 3 共 4个运行级别。这样,VMM

可以运行在 VMX root operation模式下,客户OS运行在VMX non-root operation模式下。

技术分享图片

而且两种操作模式可以互相转换。运行在 VMX root operation 模式下的 VMM 通过

显式调用 VMLAUNCH 或 VMRESUME 指令切换到VMX non-root operation模式,硬件自动加载

Guest OS 的上下文,于是Guest OS获得运行,这种转换称为VM entry。Guest OS 运行过程

中遇到需要 VMM 处理的事件,例如外部中断或缺页异常,或者主动调用 VMCALL 指令调用

VMM 的服务的时候(与系统调用类似),硬件自动挂起 Guest OS,切换到 VMX root

operation 模式,恢复 VMM 的运行,这种转换称为VM exit。VMX root operation 模式下

软件的行为与在没有 VT-x 技术的处理器上的行为基本一致;而VMX non-root operation

模式则有很大不同,主要的区别是此时运行某些指令或遇到某些事件时,发生VM exit。

也就说,硬件这层就做了些区分,这样全虚拟化下,那些靠“捕获异常-翻译-模拟”的实现

就不需要了。而且CPU厂商,支持虚拟化的力度越来越大,靠硬件辅助的全虚拟化技术的性

能逐渐逼近半虚拟化,再加上全虚拟化不需要修改客户操作系统这一优势,全虚拟化技术应

该是未来的发展趋势。

技术分享图片

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。它是完全开源的。官方网站:

http://www.linux-kvm.org/page/Main_Page

1.1 KVM 架构

  KVM 是基于虚拟化扩展(Intel VT 或者 AMD-V)的 X86 硬件的开源的 Linux 原生的全

虚拟化解决方案。KVM 中,虚拟机被实现为常规的 Linux 进程,由标准 Linux 调度程序

进行调度;虚机的每个虚拟 CPU 被实现为一个常规的 Linux 进程。这使得 KVM 能够使用

Linux 内核的已有功能。但是,KVM 本身不执行任何硬件模拟,需要客户空间程序通过 内

核模块/dev/kvm 接口设置一个客户机虚拟服务器的地址空间,向它提供模拟的 I/O,并将

它的视频显示映射回宿主的显示屏。目前这个应用程序是 QEMU。

Linux 上的用户空间、内核空间和虚机:

技术分享图片

Guest:客户机系统,包括CPU(vCPU)、内存、驱动(Console、网卡、I/O 设备驱动

等),被 KVM 置于一种受限制的 CPU 模式下运行。

KVM:运行在内核空间,提供CPU 和内存的虚级化,以及客户机的 I/O 拦截。Guest 的 I/O

被 KVM 拦截后,交给 QEMU 处理。

QEMU:修改过的为KVM虚机使用的QEMU代码,运行在用户空间,提供硬件I/O虚拟化,通过

IOCTL /dev/kvm 设备和 KVM 交互。

KVM 是实现拦截虚机的 I/O 请求的原理:

现代CPU本身实现了对特殊指令的截获和重定向的硬件支持,甚至新的硬件会提供额外

的资源来帮助软件实现对关键硬件资源的虚拟化从而提高性能。以 X86 平台为例,支持虚

拟化技术的 CPU  带有特别优化过的指令集来控制虚拟化过程。通过这些指令集,VMM 很

容易将客户机置于一种受限制的模式下运行,一旦客户机视图访问物理资源,硬件会暂停客

户机的运行,将控制权交回给 VMM 处理。VMM 还可以利用硬件的虚级化增强机制,将客户

机在受限模式下对一些特定资源的访问,完全由硬件重定向到 VMM 指定的虚拟资源,整个

过程不需要暂停客户机的运行和 VMM 的参与。由于虚拟化硬件提供全新的架构,支持操作

系统直接在上面运行,无需进行二进制转换,减少了相关的性能开销,极大简化了VMM的设

计,使得VMM性能更加强大。从 2005 年开始,Intel 在其处理器产品线中推广 Intel

Virtualization Technology 即 IntelVT 技术。

QEMU-KVM:

其实QEMU原本不是KVM的一部分,它自己就是一个纯软件实现的虚拟化系统,所以其性

能低下。但是,QEMU代码中包含整套的虚拟机实现,包括处理器虚拟化,内存虚拟化,以及

KVM需要使用到的虚拟设备模拟(网卡、显卡、存储控制器和硬盘等)。为了简化代码,KVM

在 QEMU 的基础上做了修改。VM 运行期间,QEMU 会通过 KVM 模块提供的系统调用进入内

核,由 KVM 负责将虚拟机置于处理的特殊模式运行。遇到虚机进行 I/O 操作,KVM 会从上

次的系统调用出口处返回 QEMU,由QEMU来负责解析和模拟这些设备。从QEMU的角度看,也

可以说是QEMU使用了KVM模块的虚拟化功能,为自己的虚机提供了硬件虚拟化加速。除此以

外,虚机的配置和创建、虚机运行所依赖的虚拟设备、虚机运行时的用户环境和交互,以及

一些虚机的特定技术比如动态迁移,都是QEMU自己实现的。

KVM

KVM内核模块在运行时按需加载进入内核空间运行。KVM本身不执行任何设备模拟,需要

QEMU通过 /dev/kvm 接口设置一个GUEST OS的地址空间,向它提供模拟的 I/O设备,并将它

的视频显示映射回宿主机的显示屏。它是KVM虚机的核心部分,其主要功能是初始化CPU硬

件,打开虚拟化模式,然后将虚拟客户机运行在虚拟机模式下,并对虚机的运行提供一定的

支持。以在Intel上运行为例,KVM模块被加载的时候,它:

首先初始化内部的数据结构;

做好准备后,KVM 模块检测当前的 CPU,然后打开CPU控制及存取CR4的虚拟化模式开

关,并通过执行VMXON指令将宿主操作系统置于虚拟化模式的根模式;

后,KVM模块创建特殊设备文件/dev/kvm并等待来自用户空间的指令。

接下来的虚机的创建和运行将是QEMU和KVM相互配合的过程。两者的通信接口主要是一

系列针对特殊设备文件/dev/kvm的IOCTL调用。其中重要的是创建虚机。它可以理解成KVM

为了某个特定的虚机创建对应的内核数据结构,同时,KVM 返回一个文件句柄来代表所创建

的虚机。

 针对该句柄的调用可以对虚机做相应地管理,比如创建用户空间虚拟地址和客户机物

理地址、真实物理地址之间的映射关系,再比如创建多个vCPU。KVM为每一个vCPU生成对应

的文件句柄,对其相应地IOCTL 调用,就可以对vCPU进行管理。其中重要的就是“执行虚

拟处理器”。通过它,虚机在KVM的支持下,被置于虚拟化模式的非根模式下,开始执行二

进制指令。在非根模式下,所有敏感的二进制指令都被CPU捕捉到,CPU在保存现场之后自动

切换到根模式,由KVM决定如何处理。

 除了CPU的虚拟化,内存虚拟化也由KVM实现。实际上,内存虚拟化往往是一个虚机实

现中复杂的部分。CPU 中的内存管理单元MMU是通过页表的形式将程序运行的虚拟地址转

换成实际物理地址。在虚拟机模式下,MMU的页表则必须在一次查询的时候完成两次地址转

换。因为除了将客户机程序的虚拟地址转换了客户机的物理地址外,还要将客户机物理地址

转化成真实物理地址。 KVM 虚机的创建过程

技术分享图片

技术分享图片

可见:

(1)qemu-kvm 通过对/dev/kvm的一系列 ICOTL 命令控制虚机。

(2)一个 KVM 虚机即一个 Linux qemu-kvm进程,与其他Linux进程一样被Linux 进程调

度器调度。

(3)KVM虚机包括虚拟内存、虚拟CPU和虚机 I/O设备,其中,内存和 CPU 的虚拟化由 KVM

内核模块负责实现,I/O 设备的虚拟化由QEMU负责实现。

(3)KVM客户机系统的内存是qumu-kvm 进程的地址空间的一部分。

(4)KVM虚机的vCPU 作为线程运行在 qemu-kvm进程的上下文中。

vCPU、QEMU 进程、LInux 进程调度和物理CPU之间的逻辑关系:

技术分享图片

因为CPU中的虚拟化功能的支持,并不存在虚拟的 CPU,KVM Guest代码是运行在物理 CPU

之上。

     KVM实现客户机内存的方式是,利用mmap系统调用,在QEMU主线程的虚拟地址空间

中申明一段连续的大小的空间用于客户机物理内存映射。

在有两个虚机的情况下,情形是这样的:

技术分享图片

可见,KVM为了在一台机器上运行多个虚拟机,需要增加一个新的内存虚拟化层, 也就是说,必须虚拟 MMU(Memory Management Unit) 来支持客户操作系统,来实 现 VA -> PA -> MA 的翻译。客户操作系统继续控制虚拟地址到客户内存物理地址的映射

(VA -> PA),但是客户操作系统不能直接访问实际机器内存,因此VMM 需要负责映射客户

物理内存到实际机器内存 (PA -> MA)。

VMM 内存虚拟化的实现方式:

? 软件方式:通过软件实现内存地址的翻译,比如 Shadow page table (影子页表)技

? 硬件实现:基于CPU的辅助虚拟化功能,比如AMD的NPT和Intel的EPT技术

KVM 中,虚机的物理内存即为qemu-kvm进程所占用的内存空间。KVM使用CPU辅助的内存虚拟

化方式。在Intel和AMD平台,其内存虚拟化的实现方式分别为:

? AMD 平台上的 NPT (Nested Page Tables) 技术

? Intel 平台上的 EPT (Extended Page Tables)技术 KVM的整体结构:

从GUI到Linux内核,包括以下五个组件:

1) virt-manager

一个用来管理VM的GUI/CUI用户接口;它使用libvirt api 调用VM的各种功能。

2) libvirt

一个工具及接口,作为较通用的服务器虚拟化软件,它支持Xen,VMware ESXi/GSX,当然,

还有QEMU/KVM。

3) QEMU

一个和KVM内核模块交互的模拟器,处理多种客户机系统请求如I/O;一个QEMU进程对应一个

客户机系统。

4) KVM内核模块

从狭义上来说,KVM是一个Linux内核模块,处理客户机系统的VM Exits和执行VM Entry指

令。

5) Linux内核

既然QEMU作为一个普通的用户进程运行,相应客户机系统的调度就由Linux内核自己来处

理。

所有的组件都是开放源码软件(OSS)。

技术分享图片

KVM 的功能列表

KVM 所支持的功能包括:

支持CPU 和 memory 超分(Overcommit)

支持半虚拟化I/O (virtio)

 支持热插拔(cpu,块设备、网络设备等)

支持对称多处理(Symmetric Multi-Processing,缩写为 SMP )

 支持实时迁移(Live Migration)

支持 PCI 设备直接分配和单根I/O虚拟化(SR-IOV)

支持内核同页合并(KSM )

支持NUMA (Non-Uniform Memory Access,非一致存储访问结构 ) KVM 工具集合

libvirt:操作和管理KVM虚机的虚拟化API,使用 C 语言编写,可以由 Python,Ruby,

Perl, php, Java 等语言调用。可以操作包括 KVM,vmware,XEN,Hyper-v, LXC 等

Hypervisor。

Virsh:基于libvirt 的命令行工具(CLI)

Virt-Manager:基于libvirt的GUI工具

virt-v2v:虚机格式迁移工具

virt-* 工具:包括Virt-install (创建KVM虚机的命令行工具),Virt-viewer (连接

到虚机屏幕的工具),Virt-clone(虚机克隆工具),virt-top 等

sVirt:安全工具和selinux相关

 

图形界面操作:

KVM(Kernel-based Virtual Machine) http://www.linux-kvm.org/ ,基于内核的虚拟机,配合 QEMU(处理器虚拟软件),需要CPU支持虚拟化技术(并且在Bios里打开虚拟化选项),效率可达到物 理机的80%以上。

 

查看cpu是否支持

 # grep -E ‘svm|vmx‘ /proc/cpuinfo

 vmx is for Intel processors - svm is for AMD processors

安装虚拟化软件

# yum install qemu qemu-img qemu-kvm  libvirt libvirt-python libguestfs-tools  virt-install

图形化工具:

 # yum install virt-manager virt-viewer

 开启 libvirtd 服务:

# systemctl enable libvirtd && systemctl start libvirtd

 

KVM的安装:(前提:关闭selinux 防火墙)

1、如果是用VMware Workstation做实验,建立的虚拟机的CPU要勾选虚拟化功能,这样虚拟

机才会支持KVM虚拟化

技术分享图片

1、创建虚拟机之前的准备工作:

2、mkdir /mykvm

3、cd /mykvm

4、mkdir iso

5、mkdir svm

6、导入光盘 dd if=/dev/sr0 of=/mykvm/iso/centos7.iso

技术分享图片

1. 操作系统安装介质:ISO文件,并上传到系统的/iso目录下

[[email protected] ~]# ls /iso/

技术分享图片

 

2、使用virt-manager图形界面创建

virt-manager是基于libvirt的图形化虚拟机管理软件。在命令行中以root身份输入

virt-manager命令,出现virt-manager管理界面

技术分享图片

技术分享图片

技术分享图片

技术分享图片

技术分享图片

 

技术分享图片

技术分享图片

创建存储卷,其实就是KVM虚拟机的硬盘文件,选择刚建的“vm”存

储卷,点击新建卷,设置名字和大小。

技术分享图片

创建存储卷,其实就是KVM虚拟机的硬盘文件,选择刚建的“vm”存

储卷,点击新建卷,设置名字和大小。

技术分享图片

选择“浏览”,选择镜像文件

技术分享图片

选择内存和CPU设置

技术分享图片

选择虚拟机存储硬盘,选择刚刚创建的硬盘文件。

技术分享图片

网络使用默认的NAT网络即可

技术分享图片

单击完成后,虚拟机就开始创建,然后按照操作系统即可

技术分享图片

 

 

KVM命令行安装

 

第一种方式:

 

 

 

qemu-img创建磁盘文件

通过文件管理可以直接查看、修改、复制虚拟机的内部文件。例如,当系统因为配置文件无法启动

时,可以直接修改虚拟机的文件。虚拟机磁盘文件主要有raw和qcow2格式。raw格式性能最好,速度最

快,它的缺点就是不支持一些新的功能,如支持镜像,zlib磁盘压缩,AES加密等。要使用镜像功能,磁

盘格式必须为qcow2。

raw格式的话,速度稍微快点,在高版本的qemu-kvm中,几乎不比qcow2的格式快,而qcow2格式节

省空间,可动态增长,在公有云中广泛使用,建议使用qcow2。所有有时候,我们需要将raw格式的磁盘

转换成qcow2格式。

创建一个raw格式的磁盘文件

[[email protected] kvm-vm]# qemu-img create /kvm-vm/vmtest01.img 8G

Formatting ‘/kvm-vm/vmtest01.img‘, fmt=raw size=8589934592

查看一下

[[email protected] kvm-vm]# ls -lh

总用量 3.0G

-rw-------. 1 qemu qemu  11G 9月  28 22:40 centos7-vm001.qcow2

-rw-r--r--. 1 qemu qemu 1.3G 9月  29 09:28 centos7-vm002.qcow2

drwx------. 2 root root  16K 9月  27 10:45 lost+found

-rw-r--r--. 1 root root 8.0G 9月  29 09:27 vmtest01.img

 

[[email protected] kvm-vm]# qemu-img info vmtest01.img

image: vmtest01.img

file format: raw

virtual size: 8.0G (8589934592 bytes)

disk size: 0

虽然通过ls命令看到磁盘为8G,但是实际空间大小为0,所以通过qemu-img创建的磁盘为稀疏模式

磁盘。

技术分享图片

virt-install命令参数:

通用选项:

    -n NAME, --name=NAME  虚拟机名称

    -r MEMORY, --ram=MEMORY  以MB为单位为客户端事件分配的内存

    --vcpus=VCPUS       配置虚拟机的虚拟CPU(vcpu)数量,如:

                        --vcpus 5

                        --vcpus 5, maxcpus=10

                        --vcpus socket=2,cores=4,threads=2

    --cpuset=CPUSET     Set which physical CPUs domain can use.

    --cpu=CPU           CPU型号及功能,如:--cpu coreduo,+x2apic

    --description=DESCRIPTION  在生成的XML中保存的可读VM描述。

    --security=SECURITY      设定域安全驱动器配置。

    --numatune=NUMATUNE       为域进程调整NUMA策略。

安装方法选项:

    -c CDROM, --cdrom=CDROM   光驱安装介质

    -l LOCATION, --location=LOCATION

              安装源(例如:nfs:host:/path、http://host/path、ftp://host/path)

    --pxe              使用 PXE 协议从网络引导

    --import            在磁盘映像中构建客户机

    --livecd            将光驱介质视为 Live CD

    -x EXTRA, --extra-args=EXTRA

                   附加到使用--location引导的内核的参数

    --os-type=DISTRO_TYPE

                                 操作系统类型,‘linux‘、‘unix‘、‘windows‘

    --os-variant=DISTRO_VARIANT

          操作系统版本,如: ‘fedora6‘,‘rhel5‘, ‘solaris10‘, ‘win2k‘

    --boot=BOOTOPTS     自选配置后安装引导顺序、菜单、永久kernel引导,等等。

存储配置:

    --disk=DISKOPTS     用各种选项指定存储。 Ex.

    --disk path=/my/existing/disk

    --disk path=/my/new/disk,size=5 (单位GB)

    --disk vol=poolname:volname,device=cdrom,bus=scsi,...

    --nodisks           不要为该客户端设置任何磁盘。

    --filesystem=FILESYSTEMS

      将主机目录传递给虚拟机。例如:

      --filesystem /my/source/dir,/dir/in/guest

       --filesystem template_name,/,type=template

联网配置:

    -w NETWORK, --network=NETWORK

    配置客户网络接口。 Ex:

     --network bridge=mybr0

     --network network=my_libvirt_virtual_net

     --network network=mynet,model=virtio,mac=00:11...

      --nonetworks    不要为该客体创建网络接口。

图形配置:

    --graphics=GRAPHICS

       配置虚拟机显示设置。例如:

   --graphics vnc

   --graphics spice,port=5901,tlsport=5902

   --graphics none

    --graphics vnc,password=foobar,port=5910,keymap=ja

   --noautoconsole     不要自动尝试连接到客户端控制台

设备选项:

    --serial=SERIALS    配置虚拟机串口设备

    --parallel=PARALLELS   配置虚拟机并口设备

    --channel=CHANNELS    配置虚拟机沟通频道

    --console=CONSOLES    配置虚拟机与主机之间的文本控制台连接

    --host-device=HOSTDEVS    配置与客户相连的物理主机设备

    --soundhw=SOUNDHW      配置客户声音设备仿真

    --watchdog=WATCHDOG  配置虚拟机 watchdog 设备

    --video=VIDEO        配置虚拟机视频硬件。

    --smartcard=SMARTCARD   配置虚拟机智能卡设备。

例如:--smartcard mode=passthrough

    --redirdev=REDIRDEV Configure a guest redirection device.

    例如:--redirdev usb,type=tcp,server=192.168.1.1:4000

 

虚拟化平台选项:

    -v, --hvm          客户端应该是一个全虚拟客户端

    -p, --paravirt        这个客户端是一个半虚拟客户端

    --container         This guest should be a container guest

    --virt-type=HV_TYPE     要使用的管理程序名称(kvm、qemu、xen)

    --arch=ARCH          模拟的 CPU 构架

    --machine=MACHINE   The machine type to emulate

    --noacpi   为全虚拟客户端禁用 ACPI(在 os-type/os-variant db 中覆盖数值)

    -u UUID, --uuid=UUID    客户端 UUID。

其它选项:

    --autostart            引导主机时自动启动域。

    --print-xml          输出所生成域的XML,而不是定义虚拟机。

    --print-step=XMLSTEP       输出具体安装步骤

    --noreboot            完成安装后不要引导虚拟机。

    --wait=WAIT           要等待的时间(以分钟为单位)

    --dry-run         完成安装步骤,但不要创建设备或者定义虚拟机。

    --force        对任意应用程序提示强制回答‘yes’,终止其它提示

    -q, --quiet             禁止无错误输出

    --prompt              要求用户为模糊情况或者需要的选项输入

-d, --debug             输入故障排除信息

 

1、纯命令行安装kvm的操作系统 

技术分享图片

技术分享图片

技术分享图片

技术分享图片

技术分享图片

技术分享图片

技术分享图片

全部c (如上图所述)

技术分享图片

然后按b安装

 

第二种:Vnc安装

技术分享图片

管理虚拟机:

1、libvirt架构概述:

   libvirt是用来管理虚拟机或虚拟化功能的软件集合,主要包括:libvirt API,

libvirtd进程和virsh工具集三部分。最初的目的是为不同的hypervisor提供统一的管理接

口。

   libvirtd该后台进程主要实现以下功能:

  (1)远程代理

       所有remote client发送来的命令,由该进程监测执行

  (2)本地环境初始化

      libvirt服务的启停,用户connection的响应等

 (3)根据环境注册各种Driver(qemu, xen, storage…)的实现

     不同虚拟化技术以Driver的形式实现,由于libvirt对外提供的是统一的接口,

所以各个Driver就是实现这些接口,即将Driver注册到libvirt中

技术分享图片

查看libvirtd服务状态:

[[email protected] ~]# systemctl status libvirtd

 

如果libvirtd服务停止运行,那么你将不能管理虚拟机,也就是不能使用virt-manager

等工具来管理虚拟机。

虚拟机的所有配置是放置在一个xml文件中,位置在/etc/libvirt/qemu/目录中

 

3、使用virsh来管理虚拟机

     virsh是使用libvirt management API构建的管理工具

     virsh的名称的含义是virtualization shell。它有两种工作模式:

     立即模式

技术分享图片

常用命令总结:

技术分享图片

技术分享图片

KVM基本功能管理:

1)查看命令帮助

 技术分享图片

2)查看KVM的配置文件存放目录

 技术分享图片

3)查看虚拟机状态

[[email protected] ~]# virsh list --all

 Id    名称                         状态

---------------------------------------------------

 2     vm002                        running

 3     centos7.0                      running

4)虚拟机关机与关机

 

[[email protected] ~]# virsh shutdown vm002

域 vm002 被关闭

[[email protected] ~]# virsh start vm002

域 vm002 已开始

5)强制虚拟机系统关闭电源

 [[email protected] ~]# virsh destroy vm002

 

[[email protected] ~]# virsh list --all

 Id    名称                         状态

---------------------------------------------------

 3     centos7.0                      running

 -     vm002                          关闭

6)挂起虚拟机

[[email protected] ~]# virsh suspend vm002

域 vm002 被挂起

 

[[email protected] ~]# virsh list --all

 Id    名称                         状态

---------------------------------------------------

 3     centos7.0                      running

 5     vm002                          暂停

7)恢复虚拟机

[[email protected] ~]# virsh resume vm002

域 vm002 被重新恢复

 

[[email protected] ~]# virsh list --all

 Id    名称                         状态

 3     centos7.0                      running

 5     vm002                        running

 

8)导出虚拟机配置

 [[email protected] ~]# virsh dumpxml vm002 > /etc/libvirt/qemu/vm002-bak.xml

9)虚拟机的删除与添加

 

删除虚拟机

[[email protected] ~]# virsh shutdown vm002

域 vm002 被关闭

 

[[email protected] ~]# virsh undefine vm002

域 vm002 已经被取消定义

 

 

10)修改虚拟机配置信息(两种)

 

直接修改配置文件

[[email protected] ~]# vim /etc/libvirt/qemu/vm002.xml

通过virsh命令修改

[[email protected] ~]# virsh edit vm002

11)创建一个新虚拟机配置

技术分享图片

技术分享图片

技术分享图片

技术分享图片

(末尾随便修改一位)

技术分享图片

末尾随便修改一位

技术分享图片

 

KVM虚拟机快照

 

快照实际上做的是虚拟机的XML配置文件,默认快照XML文件

在/var/lib/libvirt/qemu/snapshot/虚拟机名/下,快照只支持qcow2磁盘格式的系统。

1) 对虚拟机vm002做快照

[[email protected] ~]# virsh snapshot-create vm002

已生成域快照 1507040414

 

2) 查看快照信息

[[email protected] ~]# virsh snapshot-list vm002

 名称               生成时间              状态

-----------------------------------------------------------

 1507040414           2017-10-03 22:20:14 +0800 shutoff

 firsh_snap           2017-10-03 22:26:49 +0800 shutoff

 

3) 查看当前快照信息

[[email protected] ~]# virsh snapshot-current vm002

<domainsnapshot>

  <name>firsh_snap</name>   //快照版本号

  <state>shutoff</state>

  <parent>

    <name>1507040414</name>

  </parent>

  <creationTime>1507040809</creationTime>

  <memory snapshot=‘no‘/>

4) 恢复虚拟机状态到1507040414

[[email protected] ~]# virsh snapshot-revert vm002 1507040414

 

KVM的存储选项有多种,包括虚拟磁盘文件、基于文件系统的存储和基于设备的存储。

 

技术分享图片

virsh中和存储池相关的命令

pool-autostart          自动启动某个池

pool-build            建立池

pool-create-as          从一组变量中创建一个池

pool-create            从一个 XML 文件中创建一个池

pool-define-as          在一组变量中定义池

pool-define            在一个XML文件中定义(但不启动)一个池或修改

已有池

pool-delete            删除池

pool-destroy           销毁(删除)池

pool-dumpxml           将池信息保存到XML文档中

pool-edit             为存储池编辑 XML 配置

pool-info             查看存储池信息

pool-list             列出池

pool-name             将池 UUID 转换为池名称

pool-refresh            刷新池

pool-start              启动一个(以前定义的)非活跃的池

pool-undefine           取消定义一个不活跃的池

pool-uuid              把一个池名称转换为池 UUID

 

virsh中的和存储卷相关命令

    vol-clone             克隆卷。

    vol-create-as           从一组变量中创建卷

    vol-create             从一个 XML 文件创建一个卷

    vol-create-from           生成卷,使用另一个卷作为输入。

    vol-delete              删除卷

    vol-download            将卷内容下载到文件中

    vol-dumpxml             保存卷信息到XML文档中

    vol-info              查看存储卷信息

    vol-key               根据卷名或路径返回卷的key

    vol-list              列出卷

    vol-name              根据给定卷key或者路径返回卷名

    vol-path              根据卷名或key返回卷路径

    vol-pool              为给定密钥或者路径返回存储池

    vol-resize             重新定义卷大小

    vol-upload             将文件内容上传到卷中

    vol-wipe              擦除卷

例如:

查看系统中的存储池

virsh # pool-list --details

 Name  State    Autostart  Persistent   Capacity  Allocation  Available

-----------------------------------------------------------------------

 iso   running  yes        yes         38.28 GiB   11.28 GiB  27.00 GiB

 vms   running  yes        yes         38.28 GiB   11.28 GiB  27.00 GiB

查看vm存储池的信息

[[email protected] ~]# virsh pool-info vm

名称:       vm

UUID:       f97233cf-7cde-4f3d-a6a7-381ca4730493

状态:       running

持久:       是

自动启动: 否

容量:       78.62 GiB

分配:       8.38 GiB

可用:       70.23 GiB

查看vm存储池中的卷信息

[[email protected] ~]# virsh vol-list vm

 名称               路径

                                 

---------------------------------------------------------------------------

-

 base-centos7.qcow2   /kvm-vm/base-centos7.qcow2

             

 centos7-vm001.qcow2  /kvm-vm/centos7-vm001.qcow2             

 centos7-vm002.qcow2  /kvm-vm/centos7-vm002.qcow2             

 lost+found           /kvm-vm/lost+found

                     

 oa-disk0.qcow2       /kvm-vm/oa-disk0.qcow2

                 

 vm003.qcow2          /kvm-vm/vm003.qcow2

                    

 vmtest01.img         /kvm-vm/vmtest01.img

                   

 vmtest01.qcow2       /kvm-vm/vmtest01.qcow2

 

(基于目录的创建池)

创建基于目录的存储池    dir:Filesystem  Directrory

通过virsh创建

[[email protected] ~]# virsh pool-define-as test dir --target "/guest_images/"

 

如果创建的存储池的目录不存在的时候,需要先通过pool-build命令构建然后才能启

动成功

[[email protected] ~]# virsh pool-list --all

 名称               状态     自动开始

------------------------------------------

 default               活动      是       

 test                不活跃      否       

 vm                 活动     否       

 vm_iso               活动     是

[[email protected] ~]# virsh pool-start test

池 test 已启动

[[email protected] ~]# virsh pool-autostart test

池 test 标记为自动启动

[[email protected] ~]# virsh pool-list

 名称               状态     自动开始

------------------------------------------

 default              活动     是       

 test                活动     是       

 vm                 活动     否       

 vm_iso               活动     是

 

创建基于LVM的存储池  logical: LVM Volume Group

 

基于LVM的存储池要求使用全部磁盘分区

创建存储池时,首先准备一个vg,vg中不需要创建lv,有两种情况

使用现有的VG  kvmvg

创建新的VG  kvmvg

 

Target Path:新的卷组名

Source Path:存储设备的位置

Build Pool:会创建新的VG

创建                               卷组    池

virsh # pool-define-as  kvmvg  logical  --source-name=kvmvg --target=/dev/kvmvg

基于netfs存储池

技术分享图片

 

创建存储卷

存储卷概述

存储池被分隔为存储卷

存储卷

文件

块设备 (如物理分区、LVM逻辑卷等)

Libvirt管理的其他类型存储的抽象

技术分享图片

列出存储池

[[email protected] ~]# virsh pool-list

 名称               状态     自动开始

------------------------------------------

 default              活动     是       

 nfs2                活动     是       

 storage02              活动     是       

 vm                 活动     否       

 vm_iso               活动     是       

 

查看具体存储池vm的信息

[[email protected] ~]# virsh pool-info vm

名称:       vm

UUID:       f97233cf-7cde-4f3d-a6a7-381ca4730493

状态:       running

持久:       是

自动启动: 否

容量:       78.62 GiB

分配:       8.38 GiB

可用:       70.23 GiB

 

 

查看存储池VM中的卷

[[email protected] ~]# virsh vol-list vm

 名称               路径

                                 

---------------------------------------------------------------------------

-

 base-centos7.qcow2   /kvm-vm/base-centos7.qcow2

             

 centos7-vm001.qcow2  /kvm-vm/centos7-vm001.qcow2             

 centos7-vm002.qcow2  /kvm-vm/centos7-vm002.qcow2 

技术分享图片

 

 

Redhat/CentOS配置网桥的常用方法:

nmcli

nmcli connection add con-name br0 type bridge ifname br0  //添加网桥

技术分享图片

nmcli connection add type bridge-slave con-name ens32 ifname ens32 master

br5  //桥接物理网卡

技术分享图片

nmcli connection up ens32  //激活连接

dhclient br0

技术分享图片

 

 

KVM迁移

 静态迁移(冷迁移)     对于静态迁移,你可以在宿主机上保存一个完整的客户机镜像快照,然后在宿主机中关闭或 者暂停该客户机,然后将该客户机的镜像文件复制到另一台宿主机中,使用在源主机中启动该客户 机时的命令来启动复制过来的镜像。 动态迁移(热迁移)     如果源宿主机和目的宿主机共享存储系统,则只需要通过网络发送客户机的 vCPU 执行状 态、内存中的内容、虚机设备的状态到目的主机上。否则,还需要将客户机的磁盘存储发到目的主 机上。共享存储系统指的是源和目的虚机的镜像文件目录是在一个共享的存储上的。

在基于共享存储系统时,KVM 动态迁移的具体过程为:

1、迁移开始时,客户机依然在宿主机上运行,与此同时,客户机的内存页被传输到目的主机上。

2、QEMU/KVM 会监控并记录下迁移过程中所有已被传输的内存页的任何修改,并在所有内存页都传

输完成后即开始传输在前面过程中内存页的更改内容。

3、QEMU/KVM 会估计迁移过程中的传输速度,当剩余的内存数据量能够在一个可以设定的时间周期

(默认 30 毫秒)内传输完成时,QEMU/KVM 会关闭源宿主机上的客户机,再将剩余的数据量传输

到目的主机上,最后传输过来的内存内容在目的宿主机上恢复客户机的运行状态。

4、至此,KVM 的动态迁移操作就完成了。迁移后的客户机尽可能与迁移前一致,除非目的主机上

缺少一些配置,比如网桥等。 注意,当客户机中内存使用率非常大而且修改频繁时,内存中数据不断被修改的速度大于KVM能够 传输的内存速度时,动态迁移的过程是完成不了的,这时候只能静态迁移。 关于实时迁移的效率,业界不少人提出了改进的建议,比如通过使用内存压缩技术,减少需要传输 的内存的大小

迁移注意事项:

1、最好迁移的服务器cpu品牌一样

2、64位只能在64位宿主机间迁移,32位可以迁移32位和64位宿主机

3、宿主机名字不能冲突

4、目的宿主机和源宿主机软件配置尽可能的相同,如 有相同的桥接网卡,资源池等。

5、两台迁移的主机 cat /proc/cpuinfo |grep nx 的设置是相同的

 NX,全名为“No eXecute”,即“禁止运行”,是应用在CPU的一种技术,用作把存储器

区域分隔为只供存储处理器指令集,或只供数据使用。任何使用NX技术的存储器,代表仅供数据使

用,因此处理器的指令集并不能在这些区域存储。这种技术可防止大多数的缓冲溢出攻击,即一些

恶意程序,把自身的恶意指令集放在其他程序的数据存储区并运行,从而把整台计算机控制。

静态迁移   (冷)  

1.拷贝镜像文件和虚拟机配置文件

  2.重新定义此虚拟机

 

 

动态迁移: (热)

  1. 创建共享存储    
  2. 2.两台机器挂载共享存储(手工挂载;使用资源池)   
  3. 3.启动动态迁移   
  4. 4.创建迁移后的虚拟机配置文件   
  5. 5.重新定义虚拟机

 

 案例实施步骤如下:

1、设置主机名、/etc/hosts 互相解析,保证网络连接

2、两台主机的KVM连接NFS共享存储

3、在源主机的KVM中新建虚拟机并安装操作系统

4、连接KVM,并进行迁移。

 

virsh migrate命令帮助

# virsh migrate --help

  [--domain] <string>  域名,id 或 uuid

 [--desturi] <string>  客户端(常规迁移)或者源(p2p 迁移)中看到到目的地主机连 接 URI   

 --live           热迁移    

 --offline        离线迁移    

 --p2p            点对点迁移  

  --direct         直接迁移

  --tunnelled      管道迁移  

   --persistent     目的地中的持久 VM     

--undefinesource  在源中取消定义 VM     

--suspend        部启用目的地主机中的域    

 --copy-storage-all  使用全磁盘复制的非共享存储进行迁移   

  --copy-storage-inc  使用增值复制(源和目的地共享同一基础映像)的非共享存储进行

 迁移

  --change-protection  迁移结束前不得对域进行任何配置更改     

--unsafe         即使不安全也要强制迁移    

 --verbose        显示迁移进程    

--compressed 实时迁移过程中压缩重复的页    

 --auto-converge  force convergence during live migration    

 --rdma-pin-all   support memory pinning during RDMA live migration    

 --abort-on-error  在迁移过程中忽略软错误     

--migrateuri <string>  迁移 URI, 通常可省略    

 --graphicsuri <string>  无空隙图形迁移中使用的图形 URI  

 --listen-address <string>  listen address that destination should bind to for  incoming migration --dname <string>  在迁移过长中重新命名为一个新名称(如果支持)     

--timeout <number>  如果 live 迁移超时(以秒计)则强制虚拟机挂起    

 --xml <string>   包含为目标更新的 XML 的文件名    

冷:# virsh migrate --live --unsafe --verbose mynfs_vm1  qemu+ssh://192.168.145.30/system

热迁移:

技术分享图片

 

 

NFS:为了配合以后的虚拟机迁移,可以将虚拟机统一放在NFS等文件服务器上

(nfs添加一块网卡)

 

服务器 centos7 yum install rpcbind nfs-utils  (kvm、NFS都装)

KVM: systemctl start rpcbind (enable)

NFS:  systemctl srart rpcbind (enable)

   Systemctl start nfs-service.service(enable)

 

KVM:  vim/etc/sysconfig/nfs (端口启动)

技术分享图片

 

NFS:pvcreate /dev/sdb

     Vgcreate nfsvg /dev/sdb

Lvcreate -n nfslv1 -l 卷组号 /dev/sdb

 

mkdir/mnt/nfs

mount /dev/nfsvg/nfslv1  /mnt/nfs

mkfs.xfs /dev/nfsvg/nfslv1 (格式化)

   Vim /etc/fstab

   /dev/nfsvg/nfslv1  xfs defaults 0 0

   mount -a   mount |grep  ‘/mnt’

   Vim /etc/exports

   /mnt/nfs/  *(sync_no_root_squash)

   exportfs -av

    

KVM: showmount -e 192.168.118.119

     Mount -t nfs  192.168.118.119:/mnt/nfs/ /media

     Cd /media

     Touch 1.txt

进NFS /mnf/nfs就可以看到

以上是关于KVM介绍 虚拟化简史的主要内容,如果未能解决你的问题,请参考以下文章

KVM简介及安装

kvm介绍 转载

Linux KVM 虚拟化技术

初识KVM之1——虚拟化介绍及创建KVM虚拟机

Linux桌面虚拟化技术KVM介绍及其安装

kvm介绍