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可以處理幾種不同的磁盤映像格式。首選格式為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 是新的給特定設備的接口。

 

全虛擬化 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 關於磁盤設備和網絡的主要選項

-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 性能的目的。

純軟件模擬的設備和 Virtio 設備的區別:virtio 省去了純模擬模式下的異常捕獲環節,Guest OS 可以和 QEMU 的 I/O 模塊直接通信。

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的應用程序接口。

Libvirt API 的實現

libvirt API 的實現是在各個 Hypervisor driver 和 Storage dirver 內。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-kvm</emulator>
    <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)或者半虛擬化驅動都使用 <disk> 元素來定義。 方式:
<disk type='**' device='**'>。其中:
  • ”type“ 用來指定device source 的類型:"file", "block", "dir", "network", 或者 "volume"。具體的 source  由 <source> 標簽定義。
  • ”device“ 用來指定 device target 的類型:"floppy", "disk", "cdrom", and "lun", 默認為 "disk" 。具體的 target 由 <target> 標簽定義。

(1)”volume“ 類型的 disk
    <disk type='volume' device='disk'>
      <driver name='qemu' type='raw'/>
      <source pool='blk-pool0' volume='blk-pool0-vol0'/>
      <target dev='hdk' bus='ide'/>
    </disk>
(2)”file“ 類型的 disk
    <disk type='file' snapshot='external'>
      <driver name="tap" type="aio" cache="default"/>
      <source file='/var/lib/xen/images/fv0' startupPolicy='optional' />
      <target dev='hda' bus='ide'/>
    </disk>
(3)”block“ 類型的 disk
   <disk type='block' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <target dev='hdd' bus='ide' tray='open'/>
      <readonly/>
    </disk>
(4)”network“ 類型的 disk
復制代碼
 <disk type='network' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source protocol="http" name="url_path">
        <host name="hostname" port="80"/>
      </source>
      <target dev='hde' bus='ide' tray='open'/>
      <readonly/>
    </disk> 
復制代碼
 
Host device assignment (主機設備分配)

復制代碼
   <hostdev mode='subsystem' type='usb'> #USB 設備直接分配
      <source startupPolicy='optional'>
        <vendor id='0x1234'/>
        <product id='0xbeef'/>
      </source>
      <boot order='2'/>
    </hostdev>
    <hostdev mode='subsystem' type='pci' managed='yes'> #PCI 設備直接分配
      <source>
        <address domain='0x0000' bus='0x06' slot='0x02' function='0x0'/>
      </source>
      <boot order='1'/>
      <rom bar='on' file='/etc/fake/boot.bin'/>
    </hostdev>
復制代碼
 
Network interface (網卡)
有幾種 interface 類型:
(1)type = ‘network’ 定義一個連接 Virtual network 的 interface
復制代碼
<devices>
    <interface type='network'>
      <source network='default'/> #虛擬網絡的名稱為 ‘default’
    </interface>
    ...
    <interface type='network'>
      <source network='default' portgroup='engineering'/>
      <target dev='vnet7'/>
      <mac address="00:11:22:33:44:55"/>
      <virtualport>
        <parameters instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
      </virtualport>

    </interface>
  </devices>
復制代碼
#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。
復制代碼
    <interface type='bridge'> #連接到 br0
      <source bridge='br0'/>
    </interface>
    <interface type='bridge'> #連接到br1
      <source bridge='br1'/>
      <target dev='vnet7'/>
      <mac address="00:11:22:33:44:55"/>
    </interface>
    <interface type='bridge'> #連接到 Open vSwithc bridge ovsbr
      <source bridge='ovsbr'/>
      <virtualport type='openvswitch'>
        <parameters profileid='menial' interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
      </virtualport>
    </interface>
復制代碼
#virsh:attach-interface --domain d-2 --type bridge --source virbr0 --mac 52:22:33:44:55:66 --config
(3)type=‘ethernet’ 定義一個使用指定腳本連接到 LAN 的 interface
<devices>
    <interface type='ethernet'>
      <target dev='vnet7'/>
      <script path='/etc/qemu-ifup-mynet'/>
    </interface>
  </devices>
(4)type=‘direct’ 定義一個直接連到物理網卡(Direct attachment to physical interface)的 interface:需要 Linux macvtap 驅動支持
    <interface type='direct' trustGuestRxFilters='no'>
      <source dev='eth0' mode='vepa'/>
    </interface>
(5)type=‘hostdev’ 定義一個由主機PCI 網卡直接分配(PCI Passthrough)的 interface: 分配主機上的網卡給虛機
復制代碼
<devices>
    <interface type='hostdev' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
      </source>
      <mac address='52:54:00:6d:90:02'/>
      <virtualport type='802.1Qbh'>
        <parameters profileid='finance'/>
      </virtualport>
    </interface>
  </devices>
復制代碼
 
network (網絡)
<bridge name="virbr0" stp="on" delay="5" macTableManager="libvirt"/>
<domain name="example.com" localOnly="no"/>
<forward mode="nat" dev="eth0"/>

1. bridge:定義一個用於構造該虛擬網絡的網橋。 

2. domain:定義 DHCP server 的 DNS domain。

3. forward: 定義虛擬網絡直接連到物理 LAN 的方式. ”mode“指轉發模式。

 (1) mode=‘nat’:所有連接到該虛擬網絡的虛擬的網絡都會經過物理機器的網卡,並轉換成物理網卡的地址。

復制代碼
<network>
        <name>default</name>
        <bridge name="virbr0" />
        <forward mode="nat"/>
        <ip address="192.168.122.1" netmask="255.255.255.0">
          <dhcp>
            <range start="192.168.122.2" end="192.168.122.254" />
          </dhcp>
        </ip>
        <ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" />
      </network>
復制代碼

也可以指定公共的IP地址和端口號。

<forward mode='nat'><nat><address start='1.2.3.4' end='1.2.3.10'/> </nat> </forward>
<forward mode='nat'><nat><port start='500' end='1000'/></nat></forward>
(2) mode=‘route’:類似於 NAT,但是不使用NAT,而是使用routing table。  
復制代碼
      <network>
        <name>local</name>
        <bridge name="virbr1" />
        <forward mode="route" dev="eth1"/>
        <ip address="192.168.122.1" netmask="255.255.255.0">
          <dhcp>
            <range start="192.168.122.2" end="192.168.122.254" />
          </dhcp>
        </ip>
        <ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" />
      </network>
復制代碼
(3) mode=‘bridge’:使用不受libvirt管理的bridge,比如主機上已有的bridge;open vswitch bridge;使用 macvtap's "bridge"  模式
      <network>
        <name>host-bridge</name>
        <forward mode="bridge"/>
        <bridge name="br0"/>
      </network>
(4) mode=‘passthrough’:使用 a macvtap "direct" connection in "passthrough" mode 指定主機上的特定網卡用於虛擬網絡   
復制代碼
 <forward mode='passthrough'>
    <interface dev='eth10'/>
    <interface dev='eth11'/>
    <interface dev='eth12'/>
    <interface dev='eth13'/>
    <interface dev='eth14'/>
  </forward>
復制代碼
(5) mode=‘hostdev’:直接分配主機上的網絡設備。
<forward mode='hostdev' managed='yes'>
    <driver name='vfio'/>
    <address type='pci' domain='0' bus='4' slot='0' function='1'/>
    <address type='pci' domain='0' bus='4' slot='0' function='2'/>
    <address type='pci' domain='0' bus='4' slot='0' function='3'/>
  </forward>
 

詳細的 XML 定義說明在 https://libvirt.org/format.html

鏡像文件管理工具qemu-img

qemu支持的鏡像文件格式
可以通過qemu-img -h查看其支持的鏡像格式,支持20多中格式:blkdebug blkverify bochs cloop cow tftp ftps ftp https http dmg nbd parallels qcow qcow2 qed host_cdrom host_floppy host_device file raw sleepdog vdi vmdk vpc vvfat。這里主要介紹一下raw和qcow2格式

qemu-img有很多命令,包括下面常用的

info
  查看鏡像的信息
create
  創建鏡像
check
  檢查鏡像
convert
  轉化鏡像的格式,(raw,qcow ……)
snapshot
  管理鏡像的快照
rebase
  在已有的鏡像的基礎上創建新的鏡像
resize
  增加或減小鏡像大小

create創建鏡像

qemu-img create [-f fmt] [-o options] filename [size]
對於qcow2,-o支持的參數包括compat\backing-file\backing-fmt\encryption\cluster_size\prellocation
qemu-img create -f raw /data/centos7.raw 10G

convert 轉化鏡像文件格式

qemu-img convert [-c] [-f fmt] [-O output_fmt] [-o options] filename output_filename
[-c]表示是否對文件進行壓縮
[-o options]可以指定后端鏡像文件(保證源和目標的后端一致)、文件大小、是否加密等
qemu-img convert -c -O qcow2 vm2.raw vm2.qcow2

snapshot管理鏡像文件終端 快照
qemu-img snapshot [-l| -a snapshot| -c snapshot| -d snapshot] filename
[-l]列出所有快照
[-a]使用某一個快照
[-c]創建一個快照
[-d]刪除一個快照

查看快照
qemu-img snapshot -l /images/vm2.qcow2
注意:只有qcow2才支持快照

打快照
qemu-img snapshot -c booting vm2.qcow2

從快照恢復:
qemu-img snapshot -a 1 /images/vm2.qcow2
然后從kvm啟動這個虛擬機,會發現虛擬機又在打快照時的狀態了

刪除快照:
qemu-img snapshot -d 2 /images/vm2.qcow

resize 改變鏡像文件大小

qemu-img rebase [-f fmt] [-t cache] [-p] [-u] -b backing-file [-F backing-fmt] filename
只有qcow2和qed格式支持
qemu-img resize filename [+/-]size
size支持K M G T 單位
qemu-img resize vm2.raw +2GB

qemu-kvm存儲配置

qemu-kvm創建和開啟虛機的存儲配置
存儲配置主要涉及三部分
(1)指定存儲器
(2)設置啟動順序
(3)詳細配置存儲驅動器(設置存儲驅動器的詳細屬性,先略過)

指定存儲器,主要是指指定客戶機的IDE設備、軟盤設備、CD-ROM、Flash存儲器、SD卡具體使用哪個鏡像文件
配置客戶機的啟動順序,在指定了各個存儲器設備后,可以指定客戶機在啟動的時候選擇啟動設備的順序

qemu-kvm ... -boot [order=a|b|c|d|n][,once=drivces][,menu=on|off]
[,splash=filename][,splash-time=sp-time]
a|b分別表示第1、2軟驅,c表示第一個硬盤,d表示cd-rom;
once表示第一次啟動的啟動順序;
menu設置開機交互界面;
splash ,splash-time設置開機bios顯示的圖片和時間
詳細配置存儲驅動器

-drive option[,option[,option.....]]
為客戶機添加一個新的存儲驅動器,可以指定對應的鏡像文件、接口類型、
媒介類型、快照、緩存等

qemu-kvm創建虛擬機

qemu-kvm -name c1 -smp 2 -m 128 -cpu host -drive file=/data/VMs/c1/c1.img,if=virtio,media=disk,cache=writeback,format=qcow2 -net nic,macaddr=52:54:00:00:00:11,model=virtio -net tap,script=/etc/qemu-ifup -vnc :0 

virt-install創建虛擬機

# 默認網絡
virt-install --virt-type kvm --name centos7 --ram 1024 --cdrom=/home/CentOS-7-x86_64-Minimal-2003.iso --disk path=/data/centos7.raw --network network=default --graphics vnc,listen=0.0.0.0 --noautoconsole
# 橋接網絡:
virt-install --virt-type kvm --name openstack-middleware1 --ram 4096 --vcpus 4 --cdrom=/usr/local/src/CentOS-7-x86_64-Minimal-1511.iso --disk path=/var/lib/libvirt/images/CentOS-7-x86_64-GenericCloud-1511-ok.qcow2 --network bridge=br0 --graphics vnc,listen=0.0.0.0 --noautoconsole

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM