[譯] libvirt 虛機的生命周期 (Libvirt Virtual Machine Lifecycle)


 
這篇文章描述虛機生命周期的基本概念。其目的在於在一篇文章中提供完整的關於虛機創建、運行、停止、遷移和刪除的基礎知識。

1. 概念

先補充一下 Domain(域)、Virutal Machine(虛機)和 Guest OS (客戶機操作系統)三個術語的區別。這三個概念經常被相互使用,其實它們之間還是有些區別。

Oracel 的解釋 (資料來源):

  • Domain:資源的一個可配置集合,包括內存,虛擬CPU,網絡設備和磁盤設備。在 Domain 中運行(多個)虛擬機。一個 Domain 被分配虛擬資源,可以獨立地被啟動、停止和重啟。
  • Guest OS:運行在 domain 中的虛擬操作系統。一個 Guest OS 可以是部分虛擬化或者硬件虛擬化的。一個 Hypervisor上可以運行多個 Guest OS。
  • VM:Guest OS + 它相關的應用軟件。

libvirt 的解釋 (資料來源):

一個 libvirt Domain 是一個運行在虛擬機器上的操作系統的實例,它可以指一個運行着的虛擬機,或者用於啟動虛擬機的配置。

Xen 的解釋(資料來源):

對 Xen 來說,一個 domain 就是指一個虛擬機,其 domain 概念如下:

好吧,這些說法還是有細微差別,下文中的 Domain 就當是虛擬機吧。其它術語:

術語
解釋
Domain 域
一個運行在被虛擬化的機器上的,由 hypervisor 提供的操作系統實例
Hypervisor 虛機管理程序
一個虛擬化一個物理服務器為多個虛擬機的軟件層。
Node 節點
一個物理服務器。它可能有多種類型,比如存儲節點,集群節點和數據庫節點等。
Storage Pool 存儲池
一個存儲介質的集合,比如物理硬盤驅動器的集合。一個存儲池被細分為卷,卷會被分配給一個或者多個域。
Volume 卷
一個從存儲池中分配出來的存儲空間。一個卷可能會分配給一個或者多個域使用,並且往往被用作域內的虛擬硬盤驅動器。

1.1 XML 描述

Guest domain 是用 XML 配置來描述的。libvirt 使用 XML 文件格式來保存它的所有對象的配置,包括 domain,網絡、存儲和其它元素。這樣,用戶就可以使用任何他們喜歡使用的編輯器來編輯這些XML配置了。

比如,domain 中的設備使用 XML 元素 來表示其被分配的屬性和子元素的一個示例如下:

<domain type='qemu'>
   <name>demo</name>
   ...
   <devices>
      ...
      <disk type='file' device='disk'> ... </disk>
      <disk type='file' device='cdrom'> ... </disk>
      <input type='mouse' bus='ps2'/>
      ...
   </devices>
</domain>
libvirt 使用 XPath 技術來從XML 文檔中選擇node。 

1.2. 過渡性 Guest Domain VS 持久性 Guest Domain

Libivrt 區分兩種不同類型的 domain:短暫性的(transient )和持久性的(persistent)。

  • 短暫性 domain 只在 domain 被關機( shutdown) 或者所在的主機(host)被重啟(restart)之前存在。
  • 持久性 domain 會一直存在,直到被刪除。
 
無論它是什么類型,當一個 domain 被創建后,它的狀態可以被保存進一個文件。之后,只要該文件存在,這個 domain 的狀態就可以從無限次從該文件中被恢復( restored)。因此,即使是一個短暫性的domain,它也可以被反復地恢復。
 
創建短暫性的 domain 與創建持久性 domain 有一點不同。對持久性domain來說,它必須在其啟動前定義(define)好。而短暫性虛機可以被一次性被創建和啟動。操作兩種類型的domain的命令也有些區別。當性domain被創建和關閉時,其需要的所有部件(比如存儲、網絡、設備等)都必須提前被准備好。

1.3 Domain 狀態

 一個 Guest domain 可能處於的狀態:
  • Undified (未定義的):這是起始狀態。這時 libvirt 不會知道 domain 的任何信息,因為這時候 domain尚未被定義或者創建。
  • Defined (定義了的)/ Stopped (停止的):domain 已經被定義,但是不在運行(running)。只有持久性 domains 才能處於該狀態。當一個短暫性 domain 被停止或者關機時,它就不存在了。
  • Running (運行中的):domain 被創建而且啟動了,無論是短暫性domain還是持久性domain。任何處於該狀態的 domain 都已經在主機的 hypervisor 中被執行了。
  • Paused (中止了的):Hypervisor 上對該 domain 的運行被掛起(suspended)了。它的狀態被臨時保存(比如到內存中),直到它被繼續(resumed)。domain 本身不知道它處於是否被中止狀態。
  • Saved (保存了的):類似中止(Paused) 狀態,除了domain 的狀態被保存在持久性存儲比如硬盤上。處於該狀態上的 domain 可以被恢復 (restored)。
 
下圖描述了 domain 的狀態機。方框表示狀態,箭頭表示使得狀態變更的命令。
 
Image:Vm lifecycle graph.png
  從改圖中可以看出,對持久性 domain,shtudown 命令可以將其從運行(running) 狀態變為定義(defined)狀態;對短暫性 domain 而言,它會從運行(running) 狀態變為變為未定義(undefined) 狀態。 

1.4 快照

一個快照是虛機的操作系統和它的所有應用(applications )在某個時刻的視圖。在虛擬化領域,提供可以被恢復的虛機快照是個非常基本的功能。快照允許用戶保存虛機在某個時刻的狀態,然后在將來某個時候回滾到該狀態。基本的用例包括,創建快照、安裝新的應用、更新或者升級,然后回滾到之前的某個時間點。顯然,在快照生成之后發生的任何操作都不會包含在快照中。一個快照不會持續更新。它只表示虛機的某個時間上的狀態。 

1.5 遷移 

一個運行中的 domain 或者虛機可以被遷移到另一個主機上,只要虛機的存儲是在主機之間共享的,並且目標主機的CPU能夠支持虛機的CPU模式。根據類型和應用,虛機遷移可以不導致虛機上運行的服務的中斷。 

Libvirt 支持多種不同的遷移模式:
  • Standard (標准模式):該模式下,一個 domain 的資源在從源主機遷移到目標主機時,它會處於被掛起(suspended)狀態。遷移結束后,虛機在新的主機上繼續運行。遷移所花的時間和 domain 的內存大小直接相關。
  • Live vs non-live(實時 VS 非實時模式):當使用實時遷移模式時,domain 不會被中止,它的所有服務都繼續運行。一開始,目的主機上的 domain 或者虛機會處於停止狀態,而且在domain的狀態在網絡傳輸的過程中,domain 在目的主機上實際上是不可見的。實時遷移和它上面所運行的應用的類型有直接關系的。當實時遷移一個 domain 時,它已經被分配的內存會被發送到目的主機,與此同時,其內存的任何改變都會被監視(watched)然后也會被發到目的主機。原主機上的 domain 會一直保持它的狀態,直到兩個節點上的 domain 的內存達到完全達到一致了。這時,目的主機上的 domain 變為 active 狀態,原主機上的 domain 變為 passive 或者不可見狀態。
  • Peer-to-peer (對等模式):該模式下,當原主機和目的主機能夠直接通信。
  • Tunnelled (隧道模式) :該模式下,在原主機和目的主機之間會建立一個隧道 (tunnel),比如 SSH 隧道。兩個主機之間的所有通信都會經過該隧道。
  • Direct (直接模式):該模式下,libivrt 使用 hypervisor 來發起遷移,遷移過程完全被 hypervisor 控制。這種模式下,源主機和目的主機的 hypervisor 往往是可以直接交互的(比如,原主機和目的主機上的 Xen 能夠直接交互,而不需要libvirt 的干預)

遷移要求:

  • 使用路徑和位置相同的共享存儲
  • 兩個物理主機上的 hypervisor 的版本完全相同
  • 相同的網絡配置
  • 目的主機上有相同的或者更好的CPU。CPU必須來自同一生產廠家,目的主機上的 CPU flags 必須是原主機上的CPU flags 的超集。
這里有個成功遷移所需要的 checklist:  here

1.6 刪除 domain 時的數據安全性

 一些應用可能會存儲敏感數據,這些數據必須被安全地處理。在任何文件系統中都一樣,當一個虛機從一個系統中被刪除的時候,只是文件系統的指針被刪除。存儲介質上的數據塊任然存在,只是它們在文件系統中被標識為空。當然,這取決於你的文件系統。我們希望,當一個應用處理這種敏感數據的時候,這些機器必須物理上被安全保護,而且網絡防護也必須是被防護的。安全在任何時候都很重要。
 

2. 任務 (Tasks)

2.1 創建一個 domain  

為了運行一個 domain,首先必須創建一個 domain。有很多方式可以創建一個 domain。
(1) 這篇文章描述了使用 Virtual Machine Manager GUI 來創建一個domain。
(2)下面的代碼使用 virt-install 命令來創建一個 domain:
# virt-install \
             --connect qemu:///system \
             --virt-type kvm \
             --name MyNewVM \
             --ram 512 \
             --disk path=/var/lib/libvirt/images/MyNewVM.img,size=8 \
             --vnc \
             --cdrom /var/lib/libvirt/images/Fedora-14-x86_64-Live-KDE.iso \
             --network network=default,mac=52:54:00:9c:94:3b \
             --os-variant fedora14

該命令創建一個名為 'MyNewVM' 的 domain,它有 512M 內存和8G磁盤空間,使用KVM。你可以閱讀該命令的手冊。 

(3)最后一種方式是創建 domain 和 卷 (volume)的 XML 定義,然后使用 virsh 的 vol-create 和 define 命令。

卷 (volume)會被加入一個池(pool)中。默認的話,一個名為  "default" 的池會存在。這是一個目錄類型的池,它的意思是所有的卷都以文件形式存在於一個目錄中。詳細信息,你可以讀  this page 。

一個卷的 XML定義例子(new_volume.xml):
<volume>
 <name>sparse.img</name>
 <capacity unit="G">10</capacity>
</volume>
它定義了一個容量為 10G 的卷。使用如下命令來在 'default' 池中創建該卷:
# virsh vol-create default new_volume.xml
Domain 的 XML 定義的例子 (MyNewVM.xml) 如下:
<domain type='kvm'>
  <name>MyNewVM</name>
  <currentMemory>524288</currentMemory>
  <memory>524288</memory>
  <uuid>30d18a08-d6d8-d5d4-f675-8c42c11d6c62</uuid>
  <os>
    <type arch='x86_64'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/><apic/><pae/>
  </features>
  <clock offset="utc"/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <vcpu>1</vcpu>
  <devices>
    <emulator>/usr/bin/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/MyNewVM.img'/>
      <target dev='vda' bus='virtio'/>
    </disk>
    <disk type='block' device='cdrom'>
      <target dev='hdc' bus='ide'/>
      <readonly/>
    </disk>
    <interface type='network'>
      <source network='default'/>
      <mac address='52:54:00:9c:94:3b'/>
      <model type='virtio'/>
    </interface>
    <input type='tablet' bus='usb'/>
    <graphics type='vnc' port='-1'/>
    <console type='pty'/>
    <sound model='ac97'/>
    <video>
      <model type='cirrus'/>
    </video>
  </devices>
</domain>

定義一個持久性的domain:

# virsh define MyNewVM.xml

Domain 的 XML 格式有很多的可選元素你可能覺得有用。因此,可以閱讀 this page ,它包含完整的參考。 

2.2 編輯一個 domain

 可以使用任何編輯器來編輯一個 domain。你需要設置 $VISUAL or $EDITOR 環境變量來指定編輯器,然后運行:
# virsh edit <domain>

如果這些變量都不存在,默認會使用 vi。當編輯器關閉的時候,libvirt 會自動檢查其變化並應用這些改變。你也可以在 Virtual Machine Manager 編輯 domain。

2.3 啟動一個domain

  當一個 domain 被創建后,你可以啟動它。你可以使用Virtual Machine Manager,或者運行 virsh start <domain> 命令,比如:
# virsh start MyNewVM
該命令可能從零啟動(boot up)一個 domain 或者從之前保存的一個狀態上恢復 domain。請閱讀 virsh 的 managedsave 命令 。重要的是,如果它的任何部件比如 network 還沒有起來的話,一個 domain 不會被啟動起來。
 
就像之前提到的那樣,一個 transient domain 可以不需要提前定義(define)而直接被啟動:
# virsh create /path/to/MyNewVM.xml

2.4 停止或者重啟(reboot)domain

停止一個運行中的 domain:

# virsh shutdown <domain>

重啟一個持久性的 domain:

# virsh reboot <domain>
注意:重啟一個暫時性的 domain 是不可能的,因為當它被關閉 (shutdown)后它就變成了 undefined 狀態。

粗野的關機(inelegant shutdown),等同於直接拔電源:

# virsh destroy <domain>
 
Stopping 是指中止一個運行着的domain 的過程。包括兩個方法: shutdown 和 destroy。
  • shutdown 是個優雅(graceful)的停止過程,它會發一個信號給 domain 的操作系統,通知它立刻關機。domain 只有在 OS 成功關閉后才停止。該過程類似於在物理機器上運行 shutdown 命令。
  • destroy 是立刻中止 domain。該過程類似於拔掉物理機器的電源。 

2.5 中止(Pause)domain

使用 suspend 命令來中止一個domain:

# virsh suspend <domain>

當一個虛機處於掛起( suspended) 狀態時,它會繼續占用系統內存,但不會占用處理器資源。這時候也不會有磁盤和網絡IO操作。 

2.6 繼續(unpause/resume)domain

使用 resume 命令來繼續一個domain:

# virsh resume <domain> 
  • Suspend and resume 是指將一個domain 臨時性的保存到內存中的過程。一段時間后,可以繼續該 domain 到其原始的運行狀態。Suspend 不保存 domain 的內存到持久性文件。 
  • Save 和 restore 是指將一個運行着的 domain 的狀態保存到文件,以及從文件中恢復的過程。
需要指出的是,save/restore 只會保存內存狀態,不會保存存儲狀態。因此,當一個虛機被恢復時,其所使用的存儲必須和虛機被保存時的存儲狀態一致。對基礎性使用來說,這意味着虛機只能從被保存的文件中恢復一次。要運行多次恢復,應用需要在虛機被保存時生成一個快照,然后在恢復虛機時恢復快照。libvirt 將來的一個改進會在保存內存狀態的同時進行自動化的快照。 

2.7 對domain做快照

使用 snapshot-create 命令來對 domain 做快照:

# virsh snapshot-create <domain>

2.8 列表domain 所有的快照

使用 snapshot-list 命令來獲取 domain 的所有快照列表:

# virsh snapshot-list <domain>

結果比如:

 Name                 Creation Time             State
---------------------------------------------------
 1295973577           2011-01-25 17:39:37 +0100 running
 1295978837           2011-01-25 19:07:17 +0100 running

2.9 從快照恢復一個domain

使用 snapshot-restore 命令來從一個快照恢復一個domain:

# virsh snapshot-restore <domain> <snapshotname>

2.10 刪除domain 的一個快照

使用 snapshot-delete 命令來刪除一個快照:

# virsh snapshot-delete <domain> <snapshotname>

2.11 遷移 (Migration )

 Libvirt 支持 domain 的遷移。這意味着你可以把 domain 經過網絡從一個主機遷移到另一個主機。遷移的兩種主要模式:
  • 普通遷移(Plain migration):原主機開通一個與目的主機的 TCP 連接來發送遷移的數據。如果TCP 端口沒有被指定,那么 libvirt 會自己在 49152-49215 區間內選擇一個端口。因此你需要在目的主機的防火牆上開啟該端口。
  • 隧道遷移(Tunneled migration):原主機創建一個與目的主機之間的連接隧道。它允許加密數據流。它不需要額外的防火牆操作,但是只在 qemu 0.12+ 和 libvirt 0.7.2 以后才支持。
要進行成功的遷移,很多事情要做。比如,存儲設置。被遷移的 domain 的所有卷都必須保存在同樣的路徑上。讀   this page 來獲取完整的check list。我們建議你使用  secure migration。當遷移前的檢查都完成后,可以使用migrate 命令來進行遷移:
# virsh migrate <domain> <remote host URI> --migrateuri tcp://<remote host>:<port>

2.12 刪除一個domain

使用virsh 的 undefine 命令來刪除一個 domain:

# virsh undefine <domain>

同樣地,你也可以在 Virtual Machine Manager 中刪除一個 domain。可以閱讀這篇文章.


免責聲明!

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



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