1. 程式人生 > >KVM(七)使用 libvirt 做 QEMU/KVM 快照和 Nova 實例的快照

KVM(七)使用 libvirt 做 QEMU/KVM 快照和 Nova 實例的快照

opera 虛機 abd tor app 知識 wap disk 初始

本文將梳理 QEMU/KVM 快照相關的知識,以及在 OpenStack Nova 中使用 libvirt 來對 QEMU/KVM 虛機做快照的過程。

1. QEMU/KVM 快照

1.1 概念

QEMU/KVM 快照的定義:

  • 磁盤快照:磁盤的內容(可能是虛機的全部磁盤或者部分磁盤)在某個時間點上被保存,然後可以被恢復。
    • 磁盤數據的保存狀態:
      • 在一個運行著的系統上,一個磁盤快照很可能只是崩潰一致的(crash-consistent) 而不是完整一致(clean)的,也是說它所保存的磁盤狀態可能相當於機器突然掉電時硬盤數據的狀態,機器重啟後需要通過 fsck 或者別的工具來恢復到完整一致的狀態(類似於 Windows 機器在斷電後會執行文件檢查)。
      • 對一個非運行中的虛機來說,如果上次虛機關閉的時候磁盤是完整一致的,那麽其被快照的磁盤快照也將是完整一致的。
    • 磁盤快照有兩種:
      • 內部快照 - 使用單個的 qcow2 的文件來保存快照和快照之後的改動。這種快照是 libvirt 的默認行為,現在的支持很完善(創建、回滾和刪除),但是只能針對 qcow2 格式的磁盤鏡像文件,而且其過程較慢等。
      • 外部快照 - 快照是一個只讀文件,快照之後的修改是另一個 qcow2 文件中。外置快照可以針對各種格式的磁盤鏡像文件。外置快照的結果是形成一個 qcow2 文件鏈:original <- snap1 <- snap2 <- snap3。這裏有文章詳細討論外置快照。
  • 內存狀態(或者虛機狀態):只是保持內存和虛機使用的其它資源的狀態。如果虛機狀態快照在做和恢復之間磁盤沒有被修改,那麽虛機將保持一個持續的狀態;如果被修改了,那麽很可能導致數據corruption。
  • 系統還原點(system checkpoint):虛機的所有磁盤的快照和內存狀態快照的集合,可用於恢復完整的系統狀態(類似於系統休眠)。

關於 崩潰一致(crash-consistent)的附加說明:

  • 應該盡量避免在虛機I/O繁忙的時候做快照。這種時候做快照不是可取的辦法。
  • vmware 的做法是裝一個 tools,它是個 PV driver,可以在做快照的時候掛起系統
  • 似乎 KVM 也有類似的實現 QEMU Guest Agent,但是還不是很成熟,可參考 http://wiki.libvirt.org/page/Qemu_guest_agent

快照還可以分為 live snapshot(熱快照)和 Clod snapshot:

  • Live snapshot:系統運行狀態下做的快照
  • Cold snapshot:系統停止狀態下的快照

libvit 做 snapshot 的各個 API:

snapshot 做快照的 libvirt API 從快照恢復的 libvirt API virsh 命令
磁盤快照 virDomainSnapshotCreateXML(flags = VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY ) virDomainRevertToSnapshot virsh snapshot-create/snapshot-revert
內存(狀態)快照

virDomainSave

virDomainSaveFlags

virDomainManagedSave

virDomainRestore

virDomainRestoreFlags

virDomainCreate

virDomainCreateWithFlags

virsh save/restore
系統檢查點 virDomainSnapshotCreateXML virDomainRevertToSnapshot virsh snapshot-create/snapshot-revert

分別來看看這些 API 是如何工作的:

1. virDomainSnapshotCreateXML (virDomainPtr domain, const char * xmlDesc, unsigned int flags)

作用:根據 xmlDesc 指定的 snapshot xml 和 flags 來創建虛機的快照。

flags 包含 虛機處於運行狀態時快照的做法 虛機處於關閉狀態時快照的做法
0 創建系統檢查點,包括磁盤狀態和內存狀態比如內存內容 保持關機時的磁盤狀態
VIR_DOMAIN_SNAPSHOT_CREATE_LIVE 做快照期間,虛機將不會被 paused。這會增加內存 dump file 的大小,但是可以減少系統停機時間。部分 Hypervisor 只在做外部的系統檢查點時才設置該 flag,這意味著普通快照還是需要暫停虛機。
VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY 只做指定磁盤的快照。對應運行著的虛機,磁盤快照可能是不完整的(類似於突然電源被拔了的情形)。 只做指定磁盤的快照。

其內部實現根據虛機的運行狀態有兩種情形:

  • 對運行著的虛機,API 使用 QEMU Monitor 去做快照,磁盤鏡像文件必須是 qcow2 格式,虛機的 CPU 被停止,快照結束後會重新啟動。
  • 對停止著的虛機,API 調用 qemu-img 方法來操作所有磁盤鏡像文件。

這裏有其實現代碼,可見其基本的實現步驟:

static virDomainSnapshotPtr qemuDomainSnapshotCreateXML
{
    ....
    call qemuDomainSnapshotCreateDiskActive
    {
        call qemuProcessStopCPUs # 停止 vCPUs for each disk call qemuDomainSnapshotCreateSingleDiskActive
        {
            call qemuMonitorDiskSnapshot # 調用 QEMU Monitor 去為每個磁盤做snapshot }
        call qemuProcessStartCPUs # 啟動 vCPUs  }  .... } 

2. virDomainSave 相關的幾個 API

這幾個API 功能都比較類似:

virDomainSave 該方法會 suspend 一個運行著的虛機,然後保存期內存內容到一個文件中。成功調用以後,domain 將不會處於 running 狀態。使用 virDomainRestore 來恢復虛機。
virDomainSaveFlags 類似於 virDomainSave API,可使用幾個 flags。一些 Hypervisor 在調用該方法前需要調用 virDomainBlockJobAbort() 方法來停止 block copy 操作。
virDomainManagedSave 也類似於 virDomainSave API。主要區別是 libvirt 將其內存保存到一個受 libvirt 管理的文件中,因此libvirt 可以一直跟蹤 snapshot 的狀態;當調用 virDomainCreate/virDomainCreateWithFlags 方法重啟該 domain的時候,libvirt 會使用該受管文件,而不是一個空白的文件,這樣就可以 restore 該snapshot。

Features/SnapshotsMultipleDevices 這篇文章討論同時對多個磁盤做快照的問題。

1.2 使用 virsh 實驗

1.2.1 virsh save 命令

對運行中的 domain d-2 運行 “virsh save” 命令。命令執行完成後,d-2 變成 “shut off” 狀態。

技術分享圖片

看看 domain 的磁盤鏡像文件和 snapshot 文件:

技術分享圖片

內存數據被保存到 raw 格式的文件中。

要恢復的時候,可以運行 “vish restore d-2.snap1” 命令從保存的文件上恢復。

1.2.2 virsh snapshot-create/snapshort-create-as

先看看它的用法:

virsh # help snapshot-create-as
  NAME
    snapshot-create-as - Create a snapshot from a set of args
 
  SYNOPSIS
    snapshot-create-as  [] [] [--print-xml] [--no-metadata] [--halt] [--disk-only] [--reuse-external] [--quiesce] [--atomic] [--live] [--memspec ] [[--diskspec] ]...
 
  DESCRIPTION
    Create a snapshot (disk and RAM) from arguments
 
  OPTIONS
    [--domain]   domain name, id or uuid
    [--name]   name of snapshot
    [--description]   description of snapshot
    --print-xml      print XML document rather than create
    --no-metadata    take snapshot but create no metadata
    --halt           halt domain after snapshot is created
    --disk-only      capture disk state but not vm state
    --reuse-external  reuse any existing external files
    --quiesce        quiesce guests file systems
    --atomic         require atomic operation
    --live           take a live snapshot
    --memspec   memory attributes: [file=]name[,snapshot=type]
    [--diskspec]   disk attributes: disk[,snapshot=type][,driver=type][,file=name]

其中一些參數,比如 --atomic,在一些老的 QEMU libary 上不支持,需要更新它到新的版本。根據 這篇文章,atomic 應該是 QEMU 1.0 中加入的。

(1)默認的話,該命令創建虛機的所有磁盤和內存做內部快照,創建快照時虛機處於 paused 狀態,快照完成後變為 running 狀態。持續時間較長。

<memory snapshot=internal/>
  
    <disk name=vda snapshot=internal/>
    <disk name=vdb snapshot=internal/>
    <disk name=vdc snapshot=internal/>
   

技術分享圖片

每個磁盤的鏡像文件都包含了 snapshot 的信息:

root@compute1:/var/lib/nova/instances/eddc46a8-e026-4b2c-af51-dfaa436fcc7b# qemu-img info disk
image: disk
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 43M
cluster_size: 65536
backing file: /var/lib/nova/instances/_base/fbad3d96a1727069346073e51d5bbb1824e76e34 Snapshot list:
ID        TAG                 VM SIZE                DATE       VM CLOCK
1         1433950148              41M 2015-06-10 23:29:08   05:16:55.007 Format specific information:
    compat: 1.1
    lazy refcounts: false 

你可以運行 snapshot-revert 命令回滾到指定的snapshot。

virsh # snapshot-revert instance-0000002e 1433950148

根據 這篇文章,libvirt 將內存狀態保存到某一個磁盤鏡像文件內 (”state is saved inside one of the disks (as in qemu‘s ‘savevm‘system checkpoint implementation). If needed in the future,we can also add an attribute pointing out _which_ disk saved the internal state; maybe disk=‘vda‘.)

(2)可以使用 “--memspec” 和 “--diskspec” 參數來給內存和磁盤外部快照。這時候,在獲取內存狀態之前需要 Pause 虛機,就會產生服務的 downtime。

virsh # snapshot-create-as 0000002e livesnap2  --memspec /home/s1/livesnap2mem,snapshot=external --diskspec vda,snapshot=external
Domain snapshot livesnap2 created
virsh # snapshot-dumpxml 0000002e livesnap2     <driver type=qcow2/>
      <source file=/home/s1/testvm/testvm1.livesnap2/>
    

(3)可以使用 “--disk-only” 參數,這時會做所有磁盤的外部快照,但是不包含內存的快照。不指定快照文件名字的話,會放在原來的磁盤文件所在的目錄中。多次快照後,會形成一個外部快照鏈,新的快照使用前一個快照的鏡像文件作為 backing file。

virsh # snapshot-list instance-0000002e --tree 1433950148 #內部快照 1433950810 #內部快照 1433950946 #內部快照 snap1 #第一個外部快照 |
  +- snap2 #第二個外部快照 |
      +- 1433954941 #第三個外部快照 |
          +- 1433954977 #第四個外部快照

而第一個外部快照的鏡像文件是以虛機的原始鏡像文件作為 backing file 的:

root@compute1:/var/lib/nova/instances/eddc46a8-e026-4b2c-af51-dfaa436fcc7b# qemu-img info disk.snap1
image: disk.snap1
file format: qcow2
virtual size: 30M (31457280 bytes)
disk size: 196K
cluster_size: 65536
backing file: /var/lib/nova/instances/eddc46a8-e026-4b2c-af51-dfaa436fcc7b/disk.swap #虛機的 swap disk 原始鏡像文件 backing file format: qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false

目前還不支持回滾到某一個extrenal disk snapshot。這篇文章 談到了一個workaround。

[root@rh65 osdomains]# virsh snapshot-revert d-2 1434467974
error: unsupported configuration: revert to external disk snapshot not supported yet

(4)還可以使用 “--live” 參數創建系統還原點,包括磁盤、內存和設備狀態等。使用這個參數時,虛機不會被 Paused(那怎麽實現的?)。其後果是增加了內存 dump 文件的大小,但是減少了系統的 downtime。該參數只能用於做外部的系統還原點(external checkpoint)。

virsh # snapshot-create-as 0000002e livesnap3  --memspec /home/s1/livesnap3mem,snapshot=external --diskspec vda,snapshot=external --live Domain snapshot livesnap3 created
virsh # snapshot-dumpxml 0000002e livesnap3  <memory snapshot=external file=/home/s1/livesnap3mem/>
  
    <disk name=vda snapshot=external type=file>
      <driver type=qcow2/>
      <source file=/home/s1/testvm/testvm1.livesnap3/>
    

註意到加 “--live” 生成的快照和不加這個參數生成的快照不會被鏈在一起:

virsh # snapshot-list 0000002e --tree livesnap1 #沒加 --live |
  +- livesnap2 #沒加 --live livesnap3 #加了 --live |
  +- livesnap4 #加了 --live

不過,奇怪的是,使用 QEMU 2.3 的情況下,即使加了 --live 參數,虛機還是會被短暫的 Paused 住:

[root@rh65 ~]# virsh snapshot-create-as d-2 --memspec /home/work/d-2/mem3,snapshot=external --diskspec hda,snapshot=external --live
Domain snapshot 1434478667 created
 
[root@rh65 ~]# virsh list --all
 Id    Name                           State ---------------------------------------------------- 40 osvm1                          running 42 osvm2                          running 43 d-2 running
 
[root@rh65 ~]# virsh list --all
 Id    Name                           State ---------------------------------------------------- 40 osvm1                          running 42 osvm2                          running 43    d-2 paused # 不是說好我用 --live 你就不pause 虛機的麽?這是腫了麽。。 [root@rh65 ~]# virsh list --all
 Id    Name                           State ---------------------------------------------------- 40 osvm1                          running 42 osvm2                          running 43 d-2 running

綜上所述,對於 snapshot-create-as 命令來說,

參數 結果
所有磁盤和內存的內部的內部快照
--memspec snapshot=external --diskspec vda,snapshot=external
磁盤和內存的外部快照,虛機需要被暫停
--live --memspec snapshot=external --diskspec vda,snapshot=external 創建系統檢查點(包括磁盤和內存的快照),而且虛機不會被暫停(?測試結果顯示還是會暫停,只是暫停時間比不使用 --live 要短一些)
--disk-only 創建所有或者部分磁盤的外部快照

可以使用 sanpshot-revert 命令來回滾到指定的系統還原點,不過得使用 “-force” 參數:

[root@rh65 ~]# virsh snapshot-revert d-2 1434478313 error: revert requires force: Target device address type none does not match source pci
 
[root@rh65 ~]# virsh snapshot-revert d-2 1434478313 --force
 
[root@rh65 ~]#

1.3 外部快照的刪除

目前 libvirt 還不支持直接刪除一個外部快照,可以參考 這篇文章 介紹的 workaround。

2. OpenStack 中的快照

OpenStack Snapshot 可分為下面的幾種情形:

2.1 對 Nova Instance 進行快照

(1)對從鏡像文件啟動的虛機做快照

  • 只將運行當中的虛機的 Root disk (第一個vd 或者 hd disk) 做成 image,然後上傳到 glance 裏面
  • Live Snapshot:對滿足特定條件(QEMU 1.3+ 和 Libvirt 1.0.0+,以及 source_format not in (‘lvm‘, ‘rbd‘) and not CONF.ephemeral_storage_encryption.enabled and not CONF.workarounds.disable_libvirt_livesnapshot,以及能正常調用 libvirt.blockJobAbort ,其前提條件可參考這文章)的虛機,會進行 Live snapshot。Live Snapshot 允許用戶在虛機處於運行狀態時不停機做快照。
  • Cold Snapshot:對不能做 live snapshot 的虛機做 Cold snapshot。這種快照必須首先 Pause 虛機。

(2)對從卷啟動的虛機做快照

  • 對虛機的每個掛載的 volume 調用 cinder API 做 snapshot。
  • Snapshot 出的 metadata 會保存到 glance 裏面,但是不會有 snapshot 的 image 上傳到 Glance 裏面。
  • 這個 snapshot 也會出現在 cinder 的數據庫裏面,對 cinder API 可見。

2.2 對卷做快照

  • 調用 cinder driver api,對 backend 中的 volume 進行 snapshot。
  • 這個 snapshot 會出現在 cinder 的數據庫裏面,對 cinder API 可見。

3. 從鏡像文件啟動的 Nova 虛機做快照

嚴格地說,Nova 虛機的快照,並不是對虛機做完整的快照,而是對虛機的啟動盤(root disk,即 vda 或者 hda)做快照生成 qcow2 格式的文件,並將其傳到 Glance 中,其作用也往往是方便使用快照生成的鏡像來部署新的虛機。Nova 快照分為 Live Snapshot (不停機快照)和 Clold Snapshot (停機快照)。

3.1 Nova Live Snapshot

滿足 2.1.1 中所述條件時,運行命令 ”nova image-create “ 後,Nova 會執行 Live Snapshot。其過程如下:

  1. 找到虛機的 root disk (vda 或者 hda)。
  2. 在 CONF.libvirt.snapshots_directory 指定的文件夾(默認為 /var/lib/nova/instances/snapshots)中創建一個臨時文件夾,在其中創建一個 qcow2 格式的 delta 文件,其文件名為 uuid 字符串,該文件的 backing file 和 root disk 文件的 backing file 相同 (下面步驟 a)。
  3. 調用 virDomainGetXMLDesc 來保存 domain 的 xml 配置。
  4. 調用 virDomainBlockJobAbort 來停止對 root disk 的活動塊操作 (Cancel the active block job on the given disk)。
  5. 調用 virDomainUndefine 來將 domain 變為 transimit 類型的,這是因為 BlockRebase API 不能針對 Persistent domain 調用。
  6. 調用 virDomainBlockRebase 來將 root disk image 文件中不同的數據拷貝到 delta disk file 中。(下面步驟 b)
  7. 步驟 6 是一個持續的過程,因為可能有應用正在向該磁盤寫數據。Nova 每隔 0.5 秒調用 virDomainBlockJobInfo API 來檢查拷貝是否結束。
  8. 拷貝結束後,調用 virDomainBlockJobAbort 來終止數據拷貝。
  9. 調用 virDomainDefineXML 將domain 由 transimisit 該回到 persistent。
  10. 調用 qemu-img convert 命令將 delta image 文件和 backing file 變為一個 qcow2 文件 (下面步驟 c)
  11. 將 image 的元數據和 qcow2 文件傳到 Glance 中。
(a)執行  qemu-img create -f qcow2 (qemu-img create 創建一個基於鏡像1的鏡像2,鏡像2的文件將基於鏡像1,鏡像2中的文件將基於鏡像1中的。在鏡像2中所作的任何讀寫操作都不會影響到鏡像1. 鏡像1可以被其他鏡像當做backing file. 但是要確保鏡像1不要被修改)。比如: qemu-img create -f qcow2 -o backing_file=/var/lib/nova/instances/_base/ed39541b2c77cd7b069558570fa1dff4fda4f678,size=21474836480 /var/lib/nova/instances/snapshots/tmpzfjdJS/7f8d11be9ff647f6b7a0a643fad1f030.delta 
(b)相當於執行 virsh blockjob   [--abort] [--async] [--pivot] [--info] []
(c)執行 qemu-img convert -f qcow2 -o dest_fmt 來將帶 backing file 的 qcow2 image 轉化成不帶 backing file 的 flat image。其中 dest_fmt 由 snapshot_image_format 決定,有效值是 raw, qcow2, vmdk, vdi,默認值是 source image 的 format。比如: qemu-img convert -f qcow2 -O qcow2 /var/lib/nova/instances/snapshots/tmpzfjdJS/7f8d11be9ff647f6b7a0a643fad1f030.delta /var/lib/nova/instances/snapshots/tmpzfjdJS/7f8d11be9ff647f6b7a0a643fad1f030

來看看其中的一個關鍵 API int virDomainBlockRebase (virDomainPtr dom, const char * disk, const char * base, unsigned long bandwidth,unsigned int flags)

該 API 從 backing 文件中拷貝數據,或者拷貝整個 backing 文件到  @base 文件。
Nova 中的調用方式為:domain.blockRebase(disk_path, disk_delta, 0,libvirt.VIR_DOMAIN_BLOCK_REBASE_COPY |libvirt.VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |libvirt.VIR_DOMAIN_BLOCK_REBASE_SHALLOW)
默認的話,該 API 會拷貝整個@disk 文件到 @base 文件,但是使用  VIR_DOMAIN_BLOCK_REBASE_SHALLOW 的話就只拷貝差異數據(top data)因為 @disk 和 @base 使用相同的 backing 文件。 VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT 表示需要使用已經存在的 @base 文件因為 Nova 會預先創建好這個文件。

簡單的示意圖

技術分享圖片

這裏 有個過程的 PoC 代碼描述該過程。

這裏 有該過程的完整 libvirt 日誌分析。

這裏 有文章講 Libvirt Features/SnapshotsMultipleDevices。

3.2 Nova Cold Snapshot

當虛機不在運行中時或者不滿足 live snapshot 的條件的情況下,Nova 會執行 Cold snapshot。其主要過程如下:

(1)當虛機處於 running 或者 paused 狀態時:

  1. detach PCI devices
  2. detach SR-IOV devices
  3. 調用 virDomainManagedSave API 來將虛機 suspend 並且將內存狀態保存到磁盤文件中。

(2)調用 qemu-img convert 命令將 root disk 的鏡像文件轉化一個相同格式的鏡像文件。

(3)調用 virDomainCreateWithFlags API 將虛機變為初始狀態

(4)將在步驟1 中卸載的 PCI 和 SR-IOV 設備重新掛載回來

(5)將元數據和 qcow2 文件傳到 Glance 中

4. 從 volume 啟動的 Nova 實例的快照

(0)從卷啟動虛機,並且再掛載一個卷,然後運行 nova image-create 命令。

| image                                | Attempt to boot from volume - no image supplied                                                  |
| key_name                             | -                                                                                                |
| metadata                             | {}                                                                                               |
| name                                 | vm10                                                                                             |
| os-extended-volumes:volumes_attached | [{"id": "26446902-5a56-4c79-b839-a8e13a66dc7a"}, {"id": "de127d46-ed92-471d-b18b-e89953c305fd"}]

(1)從 DB 獲取該虛機的塊設備( Block Devices Mapping)列表。

(2)對該列表中的每一個卷,依次調用 Cinder API 做快照。對 LVM Driver 的 volume 來說,執行的命令類似於 " lvcreate --size 100M --snapshot --name snap /dev/vg00/lvol1“。

s1@controller:~$ cinder snapshot-list +--------------------------------------+--------------------------------------+-----------+------------------------+------+
|                  ID                  |              Volume ID               |   Status  |          Name          | Size |
+--------------------------------------+--------------------------------------+-----------+------------------------+------+
| a7c591fb-3413-4548-abd8-86753da3158b | de127d46-ed92-471d-b18b-e89953c305fd | available | snapshot for vm10-snap | 1 |
| d1277ea9-e972-4dd4-89c0-0b9d74956247 | 26446902-5a56-4c79-b839-a8e13a66dc7a | available | snapshot for vm10-snap | 1 |
+--------------------------------------+--------------------------------------+-----------+------------------------+------+

(3)將快照的 metadata 放到 Glance 中。(註:該 image 只是一些屬性的集合,比如 block device mapping, kernel 和 ramdisk IDs 等,它並沒有 image 數據, 因此其 size 為 0。)

s1@controller:~$ glance image-show e86cc562-349c-48cb-a81c-896584accde3 +---------------------------------+----------------------------------------------------------------------------------+
| Property                        | Value                                                                            |
+---------------------------------+----------------------------------------------------------------------------------+
| Property bdm_v2 | True                                                                             |
| Property block_device_mapping | [{"guest_format": null, "boot_index": 0, "no_device": null, "snapshot_id":       |
| # 分別是該虛機掛載的兩個volume 的   | "d1277ea9-e972-4dd4-89c0-0b9d74956247", "delete_on_termination": null,           |
| snapshot 的信息 | "disk_bus": "virtio", "image_id": null, "source_type": "snapshot",               |
|                                 | "device_type": "disk", "volume_id": null, "destination_type": "volume",          |
|                                 | "volume_size": null}, {"guest_format": null, "boot_index": null, "no_device":    |
|                                 | null, "snapshot_id": "a7c591fb-3413-4548-abd8-86753da3158b",                     |
|                                 | "delete_on_termination": null, "disk_bus": null, "image_id": null,               |
|                                 | "source_type": "snapshot", "device_type": null, "volume_id": null,               |
|                                 | "destination_type": "volume", "volume_size": null}]                              |
| Property checksum | 64d7c1cd2b6f60c92c14662941cb7913                                                 |
| Property container_format | bare                                                                             |
| Property disk_format | qcow2                                                                            |
| Property image_id | bb9318db-5554-4857-a309-268c6653b9ff                                             |
| Property image_name | image                                                                            |
| Property min_disk | 0 |
| Property min_ram | 0 |
| Property root_device_name | /dev/vda                                                                         |
| Property size | 13167616 |
| created_at                      | 2015-06-10T05:52:24 |
| deleted                         | False                                                                            |
| id                              | e86cc562-349c-48cb-a81c-896584accde3                                             |
| is_public                       | False                                                                            |
| min_disk                        | 0 |
| min_ram                         | 0 |
| name                            | vm10-snap                                                                        |
| owner                           | 74c8ada23a3449f888d9e19b76d13aab                                                 |
| protected | False                                                                            |
| size                            | 0 # 這裏 size 是 0,表明該 image 只是元數據, |
| status                          | active                                                                           |
| updated_at                      | 2015-06-10T05:52:24 |
+---------------------------------+----------------------------------------------------------------------------------+ 

5. 當前 Nova snapshot 的局限

  • Nova snapshot 其實只是提供一種創造系統盤鏡像的方法。不支持回滾至快照點,只能采用該快照鏡像創建一個新的虛擬機。
  • 在虛機是從 image boot 的時候,只對系統盤進行快照,不支持內存快照,不支持系統還原點 (blueprint:https://blueprints.launchpad.net/nova/+spec/live-snapshot-vms)
  • Live Snapshot 需要用戶進行一致性操作:http://www.sebastien-han.fr/blog/2012/12/10/openstack-perform-consistent-snapshots/
  • 只支持虛擬機內置(全量)快照,不支持外置(增量)快照。這與當前快照的實現方式有關,因為是通過 image 進行保存的。
  • 從 image boot 的虛機的快照以 Image 方式保存到 Glance 中,而非以 Cinder 卷方式保存。
  • 過程較長(需要先通過存儲快照,然後抽取並上傳至 Glance),網絡開銷大。

那為什麽 Nova 不實現虛機的快照而只是系統盤的快照呢?據說,社區關於這個功能有過討論,討論的結果是不加入這個功能,原因主要有幾點:

  • 這應該是一種虛擬化技術的功能,不是雲計算平臺的功能。
  • openstack 由於底層要支持多種虛擬化的技術,某些虛擬化技術實現這種功能比較困難。
  • 創建的 VM state snapshot 會面臨 cpu feature 不兼容的問題。
  • 目前 libvirt 對 QEMU/KVM 虛機的外部快照的支持還不完善,即使更新到最新的 libvirt 版本,造成兼容性比較差。

這裏 也有很多的討論。

KVM(七)使用 libvirt 做 QEMU/KVM 快照和 Nova 實例的快照