QEMU-KVM虚拟化:存储

以下命令行亲自执行有效,执行环境:

Compiled against library: libvirt 4.5.0
Using library: libvirt 4.5.0
Using API: QEMU 4.5.0
Running hypervisor: QEMU 1.5.3

QEMU存储虚拟化结构栈

QEMU-KVM虚拟化:存储_第1张图片

QEMU可以处理几种不同的磁盘映像格式。首选格式为raw或qcow2。Raw是一种非常简单的格式,它将文件系统中的字节逐字节存储在文件中。大多数其他仿真器都支持此格式。Qcow2是QEMU自己的图像格式,对小图像很有用。并且支持磁盘映像压缩以及捕获磁盘映像状态的快照。

从QEMU的存储协议栈来说,应用程序和虚拟机内核的工作类似于裸机。虚拟机通过硬件仿真(Hardware emulation)与QEMU交互,并将IO执行情况的控制流和数据流交互给QEMU,QEMU代表虚拟机对磁盘镜像文件执行I/O操作。而从主机内核层面上,主机内核会将虚拟机I/O视为一种用户空间的应用程序IO请求进行正常的执行处理。

硬件仿真(Hardware emulation)主要有3种:

  • Virtio 是准虚拟化存储接口,提供较好的性能,virtio_blk 是准虚拟化块设备接口。
  • IDE 是 QEMU 全虚拟化接口,提供最好的兼容性,但是性能最差。
  • SCSI 是新的给特定设备的接口。

QEMU-KVM虚拟化:存储_第2张图片

 

全虚拟化 I/O

过程:
  1. 客户机的设备驱动程序发起 I/O 请求操作请求
  2. KVM 模块中的 I/O 操作捕获代码拦截这次 I/O 请求
  3. 经过处理后将本次 I/O 请求的信息放到 I/O 共享页 (sharing page),并通知用户空间的 QEMU 程序。
  4. QEMU 程序获得 I/O 操作的具体信息之后,交由硬件模拟代码来模拟出本次 I/O 操作。
  5. 完成之后,QEMU 将结果放回 I/O 共享页,并通知 KMV 模块中的 I/O 操作捕获代码。
  6. KVM 模块的捕获代码读取 I/O 共享页中的操作结果,并把结果放回客户机。 

QEMU-KVM虚拟化:存储_第3张图片

qemu-kvm 关于磁盘设备和网络的主要选项

-drive option[,option[,option[,...]]]:定义一个硬盘设备;可用子选项有很多。
    file=/path/to/somefile:硬件映像文件路径;
    if=interface:指定硬盘设备所连接的接口类型,即控制器类型,如ide、scsi、sd、mtd、floppy、pflash及virtio等;
    index=index:设定同一种控制器类型中不同设备的索引号,即标识号;
    media=media:定义介质类型为硬盘(disk)还是光盘(cdrom);    
    format=format:指定映像文件的格式,具体格式可参见qemu-img命令;
-boot [order=drives][,once=drives][,menu=on|off]:定义启动设备的引导次序,每种设备使用一个字符表示;不同的架构所支持的设备及其表示字符不尽相同,在x86 PC架构上,a、b表示软驱、c表示第一块硬盘,d表示第一个光驱设备,n-p表示网络适配器;默认为硬盘设备(-boot order=dc,once=d)

详情:libvirt 虚机的生命周期 (Libvirt Virtual Machine Lifecycle)

I/O 全虚拟化和准虚拟化 [KVM I/O QEMU Full-Virtualizaiton Para-virtualization]
https://www.cnblogs.com/sammyliu/p/4543657.html
libvirt 介绍 [ Libvrit for KVM/QEMU ]
https://www.cnblogs.com/sammyliu/p/4558638.html
Nova 通过 libvirt 管理 QEMU/KVM 虚机 [Nova Libvirt QEMU/KVM Domain]
https://www.cnblogs.com/sammyliu/p/4568188.html
使用 libvirt 做 QEMU/KVM 快照和 Nova 实例的快照 (Nova Instances Snapshot Libvirt)
https://www.cnblogs.com/sammyliu/p/4468757.html
使用 libvirt 迁移 QEMU/KVM 虚机和 Nova 虚机 [Nova Libvirt QEMU/KVM Live Migration]
https://www.cnblogs.com/sammyliu/p/4572287.html

KVM/QEMU 的 vitio 实现采用在 Guest OS 内核中安装前端驱动 (Front-end driver)和在 QEMU 中实现后端驱动(Back-end)的方式。前后端驱动通过 vring 直接通信,这就绕过了经过 KVM 内核模块的过程,达到提高 I/O 性能的目的。

QEMU-KVM虚拟化:存储_第4张图片

纯软件模拟的设备和 Virtio 设备的区别:virtio 省去了纯模拟模式下的异常捕获环节,Guest OS 可以和 QEMU 的 I/O 模块直接通信。

QEMU-KVM虚拟化:存储_第5张图片

Libvirt

为什么需要Libvirt?

  1. Hypervisor 比如 qemu-kvm 的命令行虚拟机管理工具参数众多,难于使用。
  2. Hypervisor 种类众多,没有统一的编程接口来管理它们,这对云环境来说非常重要。
  3. 没有统一的方式来方便地定义虚拟机相关的各种可管理对象。

Libvirt提供了什么?

  1. 它提供统一、稳定、开放的源代码的应用程序接口(API)、守护进程 (libvirtd)和和一个默认命令行管理工具(virsh)。
  2. 它提供了对虚拟化客户机和它的虚拟化设备、网络和存储的管理。
  3. 它提供了一套较为稳定的C语言应用程序接口。目前,在其他一些流行的编程语言中也提供了对libvirt的绑定,在Python、Perl、Java、Ruby、PHP、OCaml等高级编程语言中已经有libvirt的程序库可以直接使用。
  4. 它对多种不同的 Hypervisor 的支持是通过一种基于驱动程序的架构来实现的。libvirt 对不同的 Hypervisor 提供了不同的驱动,包括 Xen 的驱动,对QEMU/KVM 有 QEMU 驱动,VMware 驱动等。在 libvirt 源代码中,可以很容易找到 qemu_driver.c、xen_driver.c、xenapi_driver.c、vmware_driver.c、vbox_driver.c 这样的驱动程序源代码文件。
  5. 它作为中间适配层,让底层 Hypervisor 对上层用户空间的管理工具是可以做到完全透明的,因为 libvirt 屏蔽了底层各种 Hypervisor 的细节,为上层管理工具提供了一个统一的、较稳定的接口(API)。
  6. 它使用 XML 来定义各种虚拟机相关的受管理对象。

     目前,libvirt 已经成为使用最为广泛的对各种虚拟机进行管理的工具和应用程序接口(API),而且一些常用的虚拟机管理工具(如virsh、virt-install、virt-manager等)和云计算框架平台(如OpenStack、OpenNebula、Eucalyptus等)都在底层使用libvirt的应用程序接口。

QEMU-KVM虚拟化:存储_第6张图片

Libvirt API 的实现

libvirt API 的实现是在各个 Hypervisor driver 和 Storage dirver 内。Hypervisor 驱动包括:

  • LXC - Linux Containers
  • OpenVZ
  • QEMU
  • Test - Used for testing
  • UML - User Mode Linux
  • VirtualBox
  • VMware ESX
  • VMware Workstation/Player
  • Xen
  • Microsoft Hyper-V
  • IBM PowerVM (phyp)
  • Parallels
  • Bhyve - The BSD Hypervisor

Libvirti API 所管理的主要对象

 
对象 解释
Domain (域) 指运行在由Hypervisor提供的虚拟机器上的一个操作系统实例(常常是指一个虚拟机)或者用来启动虚机的配置。
Hypervisor 一个虚拟化主机的软件层
Node (主机) 一台物理服务器。
Storage pool (存储池) 一组存储媒介的集合,比如物理硬盘驱动器。一个存储池被划分为小的容器称作卷。卷会被分给一个或者多个虚机。
Volume (卷) 一个从存储池分配的存储空间。一个卷会被分给一个或者多个域,常常成为域里的虚拟硬盘。
 

对象的管理模型

对象名称 对象 Python 类 描述
Connect 与 Hypervisor的连接
virConnectPtr
在调用任何 API 去管理一个本地或者远端的Hypervisor前,必须建立和这个Hypervisor的连接。
Domain Guest domain
virDomainPtr
用于列举和管理已有的虚机,或者创建新的虚机。唯一标识:ID,Name,UUID。一个域可能是暂时性的或者持久性的。暂时性的域只能在它运行期间被管理。持久性的域在主机上保存了它的配置。
Virtual Network 虚拟网络
virNetworkPtr
用于管理虚机的网络设备。唯一标识:Name,UUID。一个虚拟网络可能是暂时性的或者持久性的。每个主机上安装libvirt后,它都有一个默认的网络设备“default”。它向该主机上运行的虚机提供DHCP服务,以及通过NAT连接到主机上。
Storage Pool 存储池
virStoragePoolPtr
用于管理虚拟机内的所有存储,包括 local disk, logical volume group, iSCSI target, FibreChannel HBA and local/network file system。唯一标识:Name,UUID。一个存储池可能是暂时性的或者持久性的。Pool 的 type 可以是  dirfsnetfsdiskiscsilogicalscsi,mpathrbdsheepdoggluster 或者 zfs。
Storage Volume   存储卷
virStorageVolPtr
用于管理一个存储池内的存储块,包括一个池内分配的块、磁盘分区、逻辑卷、SCSI/iSCSI Lun,或者一个本地或者网络文件系统内的文件等。唯一标识:Name,Key,Path。
Host device  主机设备
virNodeDevPtr
用于管理主机上的物理硬件设备,包括 the physical USB or PCI devices and logical devices these provide, such as a NIC, disk, disk
controller, sound card, etc。唯一标识:Name。

Libvirt XML 定义

Libvirt 使用 XML 来定义各种对象,例如

  <devices>
    <emulator>/usr/libexec/qemu-kvmemulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/data/centos7.raw'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <target dev='hda' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    disk>

 

其中,与 OpenStack Nova 关系比较密切的有:

disk (磁盘) 任何磁盘设备,包括软盘(floppy)、硬盘(hard disk)、光驱(cdrom)或者半虚拟化驱动都使用 元素来定义。 方式:
。其中:
  • ”type“ 用来指定device source 的类型:"file", "block", "dir", "network", 或者 "volume"。具体的 source  由 标签定义。
  • ”device“ 用来指定 device target 的类型:"floppy", "disk", "cdrom", and "lun", 默认为 "disk" 。具体的 target 由 标签定义。

(1)”volume“ 类型的 disk
    
      
      
      
    
(2)”file“ 类型的 disk
    
      
      
      
    
(3)”block“ 类型的 disk
   
      
      
      
    
(4)”network“ 类型的 disk
复制代码
 
      
      
        
      
      
      
     
复制代码
 
Host device assignment (主机设备分配)

复制代码
    #USB 设备直接分配
      
        
        
      
      
    
     #PCI 设备直接分配
      
        
复制代码
 
Network interface (网卡)
有几种 interface 类型:
(1)type = ‘network’ 定义一个连接 Virtual network 的 interface
复制代码

    
       #虚拟网络的名称为 ‘default’
    
    ...
    
      
      
      
      
        
      

    
  
复制代码
#virsh:attach-interface --domain d-2 --type network --source isolatednet1 --mac 52:53:00:4b:75:6f --config
(2)type=‘birdge’ 定义一个 Bridge to LAN(桥接到物理网络)的interface:前提是主机上存在一个 bridge,该 bridge 已经连到物理LAN。
复制代码
     #连接到 br0
      
    
     #连接到br1
      
      
      
    
     #连接到 Open vSwithc bridge ovsbr
      
      
        
      
    
复制代码
#virsh:attach-interface --domain d-2 --type bridge --source virbr0 --mac 52:22:33:44:55:66 --config
(3)type=‘ethernet’ 定义一个使用指定脚本连接到 LAN 的 interface

    
      
      
                    
                    

你可能感兴趣的:(QEMU-KVM虚拟化:存储)