KVM 介绍(7):使用 libvirt 做 QEMU/KVM 快照和 Nova 实例的快照 (Nova Instances Snapshot Libvirt)...
學(xué)習(xí) KVM 的系列文章:
-
- (1)介紹和安裝
- (2)CPU 和 內(nèi)存虛擬化
- (3)I/O QEMU 全虛擬化和準(zhǔn)虛擬化(Para-virtulizaiton)
- (4)I/O PCI/PCIe設(shè)備直接分配和 SR-IOV
- (5)libvirt 介紹
- (6)Nova 通過 libvirt 管理 QEMU/KVM 虛機(jī)
- (7)快照 (snapshot)
- (8)遷移 (migration)
本文將梳理 QEMU/KVM 快照相關(guān)的知識(shí),以及在 OpenStack Nova 中使用 libvirt 來(lái)對(duì) QEMU/KVM 虛機(jī)做快照的過程。
1. QEMU/KVM 快照
1.1 概念
QEMU/KVM 快照的定義:快照就是將虛機(jī)在某一個(gè)時(shí)間點(diǎn)上的磁盤、內(nèi)存和設(shè)備狀態(tài)保存一下,以備將來(lái)之用。它包括以下幾類:
- 磁盤快照:磁盤的內(nèi)容(可能是虛機(jī)的全部磁盤或者部分磁盤)在某個(gè)時(shí)間點(diǎn)上被保存,然后可以被恢復(fù)。
- 磁盤數(shù)據(jù)的保存狀態(tài):
- 在一個(gè)運(yùn)行著的系統(tǒng)上,一個(gè)磁盤快照很可能只是崩潰一致的(crash-consistent) 而不是完整一致(clean)的,也是說(shuō)它所保存的磁盤狀態(tài)可能相當(dāng)于機(jī)器突然掉電時(shí)硬盤數(shù)據(jù)的狀態(tài),機(jī)器重啟后需要通過 fsck 或者別的工具來(lái)恢復(fù)到完整一致的狀態(tài)(類似于 Windows 機(jī)器在斷電后會(huì)執(zhí)行文件檢查)。(注:命令 qemu-img check -f qcow2 --output=qcow2 -r all filename-img.qcow2 可以對(duì) qcow2 和 vid 格式的鏡像做一致性檢查。)
- 對(duì)一個(gè)非運(yùn)行中的虛機(jī)來(lái)說(shuō),如果上次虛機(jī)關(guān)閉的時(shí)候磁盤是完整一致的,那么其被快照的磁盤快照也將是完整一致的。
- 磁盤快照有兩種:
- 內(nèi)部快照 - 使用單個(gè)的 qcow2 的文件來(lái)保存快照和快照之后的改動(dòng)。這種快照是 libvirt 的默認(rèn)行為,現(xiàn)在的支持很完善(創(chuàng)建、回滾和刪除),但是只能針對(duì) qcow2 格式的磁盤鏡像文件,而且其過程較慢等。
- 外部快照 - 快照是一個(gè)只讀文件,快照之后的修改是另一個(gè) qcow2 文件中。外置快照可以針對(duì)各種格式的磁盤鏡像文件。外置快照的結(jié)果是形成一個(gè) qcow2 文件鏈:original <- snap1 <- snap2 <- snap3。這里有文章詳細(xì)討論外置快照。
- 磁盤數(shù)據(jù)的保存狀態(tài):
- 內(nèi)存狀態(tài)(或者虛機(jī)狀態(tài)):只是保持內(nèi)存和虛機(jī)使用的其它資源的狀態(tài)。如果虛機(jī)狀態(tài)快照在做和恢復(fù)之間磁盤沒有被修改,那么虛機(jī)將保持一個(gè)持續(xù)的狀態(tài);如果被修改了,那么很可能導(dǎo)致數(shù)據(jù)corruption。
- 系統(tǒng)還原點(diǎn)(system checkpoint):虛機(jī)的所有磁盤的快照和內(nèi)存狀態(tài)快照的集合,可用于恢復(fù)完整的系統(tǒng)狀態(tài)(類似于系統(tǒng)休眠)。
關(guān)于?崩潰一致(crash-consistent)的附加說(shuō)明:
- 應(yīng)該盡量避免在虛機(jī)I/O繁忙的時(shí)候做快照。這種時(shí)候做快照不是可取的辦法。
- vmware 的做法是裝一個(gè) tools,它是個(gè) PV driver,可以在做快照的時(shí)候掛起系統(tǒng)
- 似乎 KVM 也有類似的實(shí)現(xiàn) QEMU Guest Agent,但是還不是很成熟,可參考?http://wiki.libvirt.org/page/Qemu_guest_agent
快照還可以分為 live snapshot(熱快照)和 Clod snapshot:
- Live snapshot:系統(tǒng)運(yùn)行狀態(tài)下做的快照
- Cold snapshot:系統(tǒng)停止?fàn)顟B(tài)下的快照
libvit 做 snapshot 的各個(gè) API:
| snapshot | 做快照的 libvirt API | 從快照恢復(fù)的 libvirt API | virsh 命令 |
| 磁盤快照 | virDomainSnapshotCreateXML(flags =?VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY?) | virDomainRevertToSnapshot | ?virsh snapshot-create/snapshot-revert |
| 內(nèi)存(狀態(tài))快照 | virDomainSave virDomainSaveFlags virDomainManagedSave | virDomainRestore virDomainRestoreFlags virDomainCreate virDomainCreateWithFlags | virsh save/restore |
| 系統(tǒng)檢查點(diǎn) | virDomainSnapshotCreateXML | virDomainRevertToSnapshot | ?virsh snapshot-create/snapshot-revert |
分別來(lái)看看這些 API 是如何工作的:
1.?virDomainSnapshotCreateXML (virDomainPtr domain, const char * xmlDesc, unsigned int flags)
作用:根據(jù) xmlDesc 指定的 snapshot xml 和 flags 來(lái)創(chuàng)建虛機(jī)的快照。
| flags 包含 | ?虛機(jī)處于運(yùn)行狀態(tài)時(shí)快照的做法 | 虛機(jī)處于關(guān)閉狀態(tài)時(shí)快照的做法 |
| 0 | 創(chuàng)建系統(tǒng)檢查點(diǎn),包括磁盤狀態(tài)和內(nèi)存狀態(tài)比如內(nèi)存內(nèi)容 | 保持關(guān)機(jī)時(shí)的磁盤狀態(tài) |
| VIR_DOMAIN_SNAPSHOT_CREATE_LIVE | 做快照期間,虛機(jī)將不會(huì)被 paused。這會(huì)增加內(nèi)存 dump file 的大小,但是可以減少系統(tǒng)停機(jī)時(shí)間。部分 Hypervisor 只在做外部的系統(tǒng)檢查點(diǎn)時(shí)才設(shè)置該 flag,這意味著普通快照還是需要暫停虛機(jī)。 | ? |
| VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY | 只做指定磁盤的快照。對(duì)應(yīng)運(yùn)行著的虛機(jī),磁盤快照可能是不完整的(類似于突然電源被拔了的情形)。 | 只做指定磁盤的快照。 |
其內(nèi)部實(shí)現(xiàn)根據(jù)虛機(jī)的運(yùn)行狀態(tài)有兩種情形:
- 對(duì)運(yùn)行著的虛機(jī),API 使用 QEMU Monitor 去做快照,磁盤鏡像文件必須是 qcow2 格式,虛機(jī)的 CPU 被停止,快照結(jié)束后會(huì)重新啟動(dòng)。
- 對(duì)停止著的虛機(jī),API 調(diào)用 qemu-img 方法來(lái)操作所有磁盤鏡像文件。
這里有其實(shí)現(xiàn)代碼,可見其基本的實(shí)現(xiàn)步驟:?
static virDomainSnapshotPtr qemuDomainSnapshotCreateXML {....call qemuDomainSnapshotCreateDiskActive{call qemuProcessStopCPUs # 停止 vCPUsfor each disk call qemuDomainSnapshotCreateSingleDiskActive{call qemuMonitorDiskSnapshot # 調(diào)用 QEMU Monitor 去為每個(gè)磁盤做snapshot}call qemuProcessStartCPUs # 啟動(dòng) vCPUs
}
.... }?
2.?virDomainSave?相關(guān)的幾個(gè) API
這幾個(gè)API 功能都比較類似:
| virDomainSave? | 該方法會(huì) suspend 一個(gè)運(yùn)行著的虛機(jī),然后保存期內(nèi)存內(nèi)容到一個(gè)文件中。成功調(diào)用以后,domain 將不會(huì)處于 running 狀態(tài)。使用?virDomainRestore 來(lái)恢復(fù)虛機(jī)。 |
| virDomainSaveFlags? | 類似于?virDomainSave?API,可使用幾個(gè) ?flags。一些 Hypervisor 在調(diào)用該方法前需要調(diào)用??virDomainBlockJobAbort() 方法來(lái)停止 block copy 操作。 |
| virDomainManagedSave? | 也類似于?virDomainSave?API。主要區(qū)別是 libvirt 將其內(nèi)存保存到一個(gè)受 libvirt 管理的文件中,因此libvirt 可以一直跟蹤 snapshot 的狀態(tài);當(dāng)調(diào)用 virDomainCreate/virDomainCreateWithFlags 方法重啟該?domain的時(shí)候,libvirt 會(huì)使用該受管文件,而不是一個(gè)空白的文件,這樣就可以 restore 該snapshot。 |
Features/SnapshotsMultipleDevices 這篇文章討論同時(shí)對(duì)多個(gè)磁盤做快照的問題。
1.2 使用 virsh 實(shí)驗(yàn)
1.2.1 virsh save 命令
對(duì)運(yùn)行中的 domain d-2 運(yùn)行 “virsh save” 命令。命令執(zhí)行完成后,d-2 變成 “shut off” 狀態(tài)。
看看 domain 的磁盤鏡像文件和 snapshot 文件:
內(nèi)存數(shù)據(jù)被保存到 raw 格式的文件中。
要恢復(fù)的時(shí)候,可以運(yùn)行 “vish restore d-2.snap1” 命令從保存的文件上恢復(fù)。
1.2.2 virsh snapshot-create/snapshort-create-as
先看看它的用法:
virsh # help snapshot-create-asNAMEsnapshot-create-as - Create a snapshot from a set of argsSYNOPSISsnapshot-create-as <domain> [<name>] [<description>] [--print-xml] [--no-metadata] [--halt] [--disk-only] [--reuse-external] [--quiesce] [--atomic] [--live] [--memspec <string>] [[--diskspec] <string>]...DESCRIPTIONCreate a snapshot (disk and RAM) from argumentsOPTIONS[--domain] <string> domain name, id or uuid[--name] <string> name of snapshot[--description] <string> description of snapshot--print-xml print XML document rather than create--no-metadata take snapshot but create no metadata #創(chuàng)建的快照不帶任何元數(shù)據(jù)--halt halt domain after snapshot is created #快照創(chuàng)建后虛機(jī)會(huì)關(guān)閉--disk-only capture disk state but not vm state #只對(duì)磁盤做快照,忽略其它參數(shù)--reuse-external reuse any existing external files--quiesce quiesce guest's file systems #libvirt 會(huì)通過 QEMU GA 嘗試去freeze和unfreeze客戶機(jī)已經(jīng)mounted的文件系統(tǒng);如果客戶機(jī)沒有安裝QEMU GA,則操作會(huì)失敗。--atomic require atomic operation #快照要么完全成功要么完全失敗,不允許部分成果。不是所有的VMM都支持。--live take a live snapshot #當(dāng)客戶機(jī)處于運(yùn)行狀態(tài)下做快照--memspec <string> memory attributes: [file=]name[,snapshot=type][--diskspec] <string> disk attributes: disk[,snapshot=type][,driver=type][,file=name]其中一些參數(shù),比如 --atomic,在一些老的 QEMU libary 上不支持,需要更新它到新的版本。根據(jù) 這篇文章,atomic 應(yīng)該是 QEMU 1.0 中加入的。
(1)默認(rèn)的話,該命令創(chuàng)建虛機(jī)的所有磁盤和內(nèi)存做內(nèi)部快照,創(chuàng)建快照時(shí)虛機(jī)處于 paused 狀態(tài),快照完成后變?yōu)?running 狀態(tài)。持續(xù)時(shí)間較長(zhǎng)。
<memory snapshot='internal'/><disks><disk name='vda' snapshot='internal'/><disk name='vdb' snapshot='internal'/><disk name='vdc' snapshot='internal'/></disks>?每個(gè)磁盤的鏡像文件都包含了 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.1lazy refcounts: false你可以運(yùn)行 snapshot-revert 命令回滾到指定的snapshot。
virsh # snapshot-revert instance-0000002e 1433950148根據(jù)?這篇文章,libvirt 將內(nèi)存狀態(tài)保存到某一個(gè)磁盤鏡像文件內(nèi) (”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” 參數(shù)來(lái)給內(nèi)存和磁盤外部快照。這時(shí)候,在獲取內(nèi)存狀態(tài)之前需要 Pause 虛機(jī),就會(huì)產(chǎn)生服務(wù)的 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 <memory snapshot='external' file='/home/s1/livesnap2mem'/><disks><disk name='vda' snapshot='external' type='file'><driver type='qcow2'/><source file='/home/s1/testvm/testvm1.livesnap2'/></disk></disks>(3)可以使用 “--disk-only” 參數(shù),這時(shí)會(huì)做所有磁盤的外部快照,但是不包含內(nèi)存的快照。不指定快照文件名字的話,會(huì)放在原來(lái)的磁盤文件所在的目錄中。多次快照后,會(huì)形成一個(gè)外部快照鏈,新的快照使用前一個(gè)快照的鏡像文件作為 backing file。
virsh # snapshot-list instance-0000002e --tree 1433950148 #內(nèi)部快照 1433950810 #內(nèi)部快照 1433950946 #內(nèi)部快照 snap1 #第一個(gè)外部快照|+- snap2 #第二個(gè)外部快照|+- 1433954941 #第三個(gè)外部快照|+- 1433954977 #第四個(gè)外部快照而第一個(gè)外部快照的鏡像文件是以虛機(jī)的原始鏡像文件作為 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 #虛機(jī)的 swap disk 原始鏡像文件 backing file format: qcow2 Format specific information:compat: 1.1lazy refcounts: false目前還不支持回滾到某一個(gè)extrenal disk snapshot。這篇文章?談到了一個(gè)workaround。
[root@rh65 osdomains]# virsh snapshot-revert d-2 1434467974
error: unsupported configuration: revert to external disk snapshot not supported yet
(4)還可以使用 “--live” 參數(shù)創(chuàng)建系統(tǒng)還原點(diǎn),包括磁盤、內(nèi)存和設(shè)備狀態(tài)等。使用這個(gè)參數(shù)時(shí),虛機(jī)不會(huì)被 Paused(那怎么實(shí)現(xiàn)的?)。其后果是增加了內(nèi)存 dump 文件的大小,但是減少了系統(tǒng)的 downtime。該參數(shù)只能用于做外部的系統(tǒng)還原點(diǎn)(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'/><disks><disk name='vda' snapshot='external' type='file'><driver type='qcow2'/><source file='/home/s1/testvm/testvm1.livesnap3'/></disk></disks>注意到加 “--live” 生成的快照和不加這個(gè)參數(shù)生成的快照不會(huì)被鏈在一起:
virsh # snapshot-list 0000002e --tree livesnap1 #沒加 --live|+- livesnap2 #沒加 --livelivesnap3 #加了 --live|+- livesnap4 #加了 --live不過,奇怪的是,使用 QEMU 2.3 的情況下,即使加了 --live 參數(shù),虛機(jī)還是會(huì)被短暫的 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 --allId Name State ----------------------------------------------------40 osvm1 running42 osvm2 running43 d-2 running[root@rh65 ~]# virsh list --allId Name State ----------------------------------------------------40 osvm1 running42 osvm2 running43 d-2 paused # 不是說(shuō)好我用 --live 你就不pause 虛機(jī)的么?這是腫了么。。[root@rh65 ~]# virsh list --allId Name State ----------------------------------------------------40 osvm1 running42 osvm2 running43 d-2 running?
綜上所述,對(duì)于?snapshot-create-as 命令來(lái)說(shuō),
| 參數(shù) | 結(jié)果 |
| <不使用額外的參數(shù)> | 所有磁盤和內(nèi)存的內(nèi)部的內(nèi)部快照 |
| --memspec snapshot=external --diskspec vda,snapshot=external ? | 磁盤和內(nèi)存的外部快照,虛機(jī)需要被暫停 |
| --live ?--memspec snapshot=external --diskspec vda,snapshot=external | 創(chuàng)建系統(tǒng)檢查點(diǎn)(包括磁盤和內(nèi)存的快照),而且虛機(jī)不會(huì)被暫停(?測(cè)試結(jié)果顯示還是會(huì)暫停,只是暫停時(shí)間比不使用 --live 要短一些) |
| --disk-only | 創(chuàng)建所有或者部分磁盤的外部快照 |
?可以使用 sanpshot-revert 命令來(lái)回滾到指定的系統(tǒng)還原點(diǎn),不過得使用 “-force” 參數(shù):
?
[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 還不支持直接刪除一個(gè)外部快照,可以參考 這篇文章?介紹的 workaround。
2. OpenStack 中的快照
OpenStack Snapshot 可分為下面的幾種情形:2.1 對(duì) Nova Instance 進(jìn)行快照
(1)對(duì)從鏡像文件啟動(dòng)的虛機(jī)做快照
- 只將運(yùn)行當(dāng)中的虛機(jī)的 Root disk (第一個(gè)vd 或者 hd disk) 做成 image,然后上傳到 glance 里面
- Live Snapshot:對(duì)滿足特定條件(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,以及能正常調(diào)用 libvirt.blockJobAbort ,其前提條件可參考這文章)的虛機(jī),會(huì)進(jìn)行 Live snapshot。Live Snapshot 允許用戶在虛機(jī)處于運(yùn)行狀態(tài)時(shí)不停機(jī)做快照。
- Cold Snapshot:對(duì)不能做 live snapshot 的虛機(jī)做 Cold snapshot。這種快照必須首先 Pause 虛機(jī)。
(2)對(duì)從卷啟動(dòng)的虛機(jī)做快照
- 對(duì)虛機(jī)的每個(gè)掛載的 volume 調(diào)用 cinder API 做 snapshot。
- Snapshot 出的 metadata 會(huì)保存到 glance 里面,但是不會(huì)有 snapshot 的 image 上傳到 Glance 里面。
- 這個(gè) snapshot 也會(huì)出現(xiàn)在 cinder 的數(shù)據(jù)庫(kù)里面,對(duì) cinder API 可見。
2.2 對(duì)卷做快照
- 調(diào)用 cinder driver api,對(duì) backend 中的 volume 進(jìn)行 snapshot。
- 這個(gè) snapshot 會(huì)出現(xiàn)在 cinder 的數(shù)據(jù)庫(kù)里面,對(duì) cinder API 可見。??
3. 從鏡像文件啟動(dòng)的 Nova 虛機(jī)做快照
? ? 嚴(yán)格地說(shuō),Nova 虛機(jī)的快照,并不是對(duì)虛機(jī)做完整的快照,而是對(duì)虛機(jī)的啟動(dòng)盤(root disk,即 vda 或者 hda)做快照生成 qcow2 格式的文件,并將其傳到 Glance 中,其作用也往往是方便使用快照生成的鏡像來(lái)部署新的虛機(jī)。Nova 快照分為 Live Snapshot (不停機(jī)快照)和 Clold Snapshot (停機(jī)快照)。
3.1 Nova Live Snapshot
滿足 2.1.1 中所述條件時(shí),運(yùn)行命令 ?”nova image-create <instance name or uuid> <name of new image>“ 后,Nova 會(huì)執(zhí)行 Live Snapshot。其過程如下:
(b)相當(dāng)于執(zhí)行 virsh blockjob <domain> <path> [--abort] [--async] [--pivot] [--info] [<bandwidth>] (c)執(zhí)行 'qemu-img convert -f qcow2 -o dest_fmt' 來(lái)將帶 backing file 的 qcow2 image 轉(zhuǎn)化成不帶 backing file 的 flat image。其中 dest_fmt 由 snapshot_image_format 決定,有效值是 raw, qcow2, vmdk, vdi,默認(rèn)值是 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
來(lái)看看其中的一個(gè)關(guān)鍵 API?int virDomainBlockRebase (virDomainPtr dom, const char * disk, const char * base, unsigned long bandwidth,unsigned int flags)
該 API 從 backing 文件中拷貝數(shù)據(jù),或者拷貝整個(gè) backing 文件到 @base 文件。 Nova 中的調(diào)用方式為: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) 默認(rèn)的話,該 API 會(huì)拷貝整個(gè)@disk 文件到 @base 文件,但是使用 ?VIR_DOMAIN_BLOCK_REBASE_SHALLOW 的話就只拷貝差異數(shù)據(jù)(top data)因?yàn)?@disk 和 @base 使用相同的 backing 文件。?VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT 表示需要使用已經(jīng)存在的 @base 文件因?yàn)?Nova 會(huì)預(yù)先創(chuàng)建好這個(gè)文件。簡(jiǎn)單的示意圖:
這里 有個(gè)過程的 PoC 代碼描述該過程。
這里 有該過程的完整 libvirt 日志分析。
這里 有文章講 Libvirt?Features/SnapshotsMultipleDevices。
3.2 Nova Cold Snapshot
當(dāng)虛機(jī)不在運(yùn)行中時(shí)或者不滿足 live snapshot 的條件的情況下,Nova 會(huì)執(zhí)行 Cold snapshot。其主要過程如下:
(1)當(dāng)虛機(jī)處于 running 或者 paused 狀態(tài)時(shí):
(2)調(diào)用?qemu-img convert 命令將 root disk 的鏡像文件轉(zhuǎn)化一個(gè)相同格式的鏡像文件。
(3)調(diào)用 virDomainCreateWithFlags? API?將虛機(jī)變?yōu)槌跏紶顟B(tài)
(4)將在步驟1 中卸載的 PCI 和 SR-IOV 設(shè)備重新掛載回來(lái)
(5)將元數(shù)據(jù)和 qcow2 文件傳到 Glance 中
4. 從 volume 啟動(dòng)的 Nova 實(shí)例的快照
(0)從卷啟動(dòng)虛機(jī),并且再掛載一個(gè)卷,然后運(yùn)行 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 獲取該虛機(jī)的塊設(shè)備( Block Devices Mapping)列表。
(2)對(duì)該列表中的每一個(gè)卷,依次調(diào)用 Cinder API 做快照。對(duì) LVM Driver 的 volume 來(lái)說(shuō),執(zhí)行的命令類似于 " 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 數(shù)據(jù), 因此其 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": | | # 分別是該虛機(jī)掛載的兩個(gè)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 只是元數(shù)據(jù), | | status | active | | updated_at | 2015-06-10T05:52:24 | +---------------------------------+----------------------------------------------------------------------------------+?5. 當(dāng)前 Nova snapshot 的局限
- Nova snapshot 其實(shí)只是提供一種創(chuàng)造系統(tǒng)盤鏡像的方法。不支持回滾至快照點(diǎn),只能采用該快照鏡像創(chuàng)建一個(gè)新的虛擬機(jī)。
- 在虛機(jī)是從 image boot 的時(shí)候,只對(duì)系統(tǒng)盤進(jìn)行快照,不支持內(nèi)存快照,不支持系統(tǒng)還原點(diǎn)?(blueprint:https://blueprints.launchpad.net/nova/+spec/live-snapshot-vms)
- Live Snapshot 需要用戶進(jìn)行一致性操作:http://www.sebastien-han.fr/blog/2012/12/10/openstack-perform-consistent-snapshots/
- 只支持虛擬機(jī)內(nèi)置(全量)快照,不支持外置(增量)快照。這與當(dāng)前快照的實(shí)現(xiàn)方式有關(guān),因?yàn)槭峭ㄟ^ image 進(jìn)行保存的。
- 從 image boot 的虛機(jī)的快照以 Image 方式保存到 Glance 中,而非以 Cinder 卷方式保存。
- 過程較長(zhǎng)(需要先通過存儲(chǔ)快照,然后抽取并上傳至 Glance),網(wǎng)絡(luò)開銷大。
那為什么 Nova 不實(shí)現(xiàn)虛機(jī)的快照而只是系統(tǒng)盤的快照呢?據(jù)說(shuō),社區(qū)關(guān)于這個(gè)功能有過討論,討論的結(jié)果是不加入這個(gè)功能,原因主要有幾點(diǎn):
- 這應(yīng)該是一種虛擬化技術(shù)的功能,不是云計(jì)算平臺(tái)的功能。
- openstack 由于底層要支持多種虛擬化的技術(shù),某些虛擬化技術(shù)實(shí)現(xiàn)這種功能比較困難。
- 創(chuàng)建的 VM state snapshot 會(huì)面臨 cpu feature 不兼容的問題。
- 目前 libvirt 對(duì) QEMU/KVM 虛機(jī)的外部快照的支持還不完善,即使更新到最新的 libvirt 版本,造成兼容性比較差。
轉(zhuǎn)載于:https://www.cnblogs.com/sammyliu/p/4468757.html
總結(jié)
以上是生活随笔為你收集整理的KVM 介绍(7):使用 libvirt 做 QEMU/KVM 快照和 Nova 实例的快照 (Nova Instances Snapshot Libvirt)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle数据库入门——初级系列教程
- 下一篇: 第三方网站实现绑定微信登陆