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

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

本文將梳理 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 guest's 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 的資訊:

[email protected]:/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 的:

[email protected]:/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。

[[email protected] 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 住:

 

[[email protected] ~]# virsh snapshot-create-as d-2 --memspec /home/work/d-2/mem3,snapshot=external --diskspec hda,snapshot=external --live
Domain snapshot 1434478667 created
 
[[email protected] ~]# virsh list --all
 Id    Name                           State ---------------------------------------------------- 40 osvm1                          running 42 osvm2                          running 43 d-2 running
 
[[email protected] ~]# virsh list --all
 Id    Name                           State ---------------------------------------------------- 40 osvm1                          running 42 osvm2                          running 43    d-2 paused # 不是說好我用 --live 你就不pause 虛機的麼?這是腫了麼。。 [[email protected] ~]# 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” 引數:

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

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“。

[email protected]:~$ 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。)

[email protected]:~$ 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 版本,造成相容性比較差。

 這裡 也有很多的討論。