Libvirt 虛擬化庫剖析

來源:互聯網
上載者:User

標籤:des   style   http   java   使用   strong   

講到向外擴充計算(比如雲端運算),libvirt 可能是您從未聽說過的最重要的庫之一。libvirt 提供一種Hypervisor不可知的 API 來安全管理運行於主機上的客體作業系統。libvirt 本身不是一種工具, 它是一種可以建立工具來管理客體作業系統的 API。libvirt 本身構建於一種抽象的概念之上。它為受支援的Hypervisor實現的常用功能提供通用的 API。libvirt 起初是專門為 Xen 設計的一種管理 API,後來被擴充為可支援多個Hypervisor。

基本架構

首先讓我們從用例模型視角來展開對 libvirt 的討論,然後深入探究其架構和用途。libvirt 以一組 API 的形式存在,旨在供管理應用程式使用(見圖 1 )。libvirt 通過一種特定於Hypervisor的機制與每個有效Hypervisor進行通訊,以完成 API 請求。文章後面我將探討如何通過 QEMU 來實現該功能。

圖 1. libvirt 比較和用例模型

圖中還顯示了 libvirt 所用術語對照。這些術語很重要,因為在對 API 命名時會用到它們。兩個根本區別在於,libvirt 將物理主機稱作節點,將客體作業系統稱作。這裡需要注意的是,libvirt(及其應用程式)在宿主 Linux 作業系統(域 0)中運行。

控制方式

使用 libvirt,我們有兩種不同的控制方式。第一種如 圖 1 所示,其中管理應用程式和域位於同一節點上。 在本例中,管理應用程式通過 libvirt 工作,以控制本地區。當管理應用程式和域位於不同節點上時,便產生了另一種控制方式。在本例中需要進行遠程通訊(參見 圖 2)。該模式使用一種運行於遠程節點上、名為 libvirtd 的特殊守護進程。當在新節點上安裝 libvirt 時該程式會自動啟動,且可自動確定本地Hypervisor並為其安裝驅動程式(稍後討論)。該管理應用程式通過一種通用協議從本地 libvirt 串連到遠程 libvirtd。對於 QEMU,協議在 QEMU 監視器處結束。QEMU 包含一個監測控制台,它允許檢查運行中的客體作業系統並控制虛擬機器(VM)各部分。

圖 2. 使用 libvirtd 控制遠程Hypervisor

Hypervisor支援

為支援各種Hypervisor的可擴充性,libvirt 實施一種基於驅動程式的架構,該架構允許一種通用的 API 以通用方式為大量潛在的Hypervisor提供服務。這意味著,一些Hypervisor的某些專業功能在 API 中不可見。另外,有些Hypervisor可能不能實施所有 API 功能,因而在特定驅動程式內被定義為不受支援。圖 3 展示了 libvirt API 與相關驅動程式的階層。這裡也需要注意,libvirtd 提供從遠程應用程式訪問本地區的方式。

圖 3. 基於驅動程式的 libvirt 架構

在撰寫此文時,libvirt 為表 1 所列的Hypervisor實現了驅動程式。隨著新的Hypervisor在開源社區出現,其他驅動程式無疑也將可用。

表 1. libvirt 支援的Hypervisor
Hypervisor 描述
Xen 面向 IA-32,IA-64 和 PowerPC 970 架構的Hypervisor
QEMU 面向各種架構的平台模擬器
Kernel-based Virtual Machine (KVM) Linux 平台模擬器
Linux Containers(LXC) 用於作業系統虛擬化的 Linux(輕量級)容器
OpenVZ 基於 Linux 核心的作業系統級虛擬化
VirtualBox x86 虛擬化Hypervisor
User Mode Linux 面向各種架構的 Linux 平台模擬器
Test 面向偽Hypervisor的測試磁碟機
Storage 儲存池磁碟機(本地磁碟,網路磁碟,iSCSI 卷)
 

回頁首

libvirt 和虛擬 shell

上面已經介紹了 libvirt 的一些架構,接下來看一下如何使用 libvirt 虛擬化 API 的一些樣本。首先介紹一種名為 virsh(虛擬 shell)的應用程式,它構建於 libvirt 之上。該 shell 允許以互動(基於 shell)方式使用多個 libvirt 功能。在本節中,我使用 virsh 示範了一些 VM 操作。

第一步是要定義網域設定檔案(如下面的 清單 1 所示)。該代碼指定了定義域所需的所有選項 — 從Hypervisor(模擬器)到域使用的資源以及外圍配置(比如網路)。注意,這隻是個簡單的配置,libvirt 真正支援的屬性更加多樣化。例如,您可以指定 BIOS 和主機引導程式,域要使用的資源,以及要用到的裝置 — 從磁碟片和 CD-ROM 到 USB 和 PCI 裝置。

網域設定檔案定義該 QEMU 域要使用的一些基本中繼資料,包括網域名稱、最大記憶體、初始可用記憶體(當前)以及該域可用的虛擬處理器數量。您不需要自己分配 Universally Unique Idenifier (UUID),而是讓 libvirt 分配。您需要為該平台定義要模擬的機器類型 — 在本例中是被完全虛擬化(hvm)的 686 處理器。您需要為域定義模擬器的位置(以備需要支援多個同類型模擬器時使用)和虛擬磁碟。這裡注意要指明 VM,它是以 Virtual Machine Disk(VMDK)格式存在的 ReactOS 作業系統。最後,要指定預設網路設定,並使用面向圖形的 Virtual Network Computing (VNC)。

清單 1. 網域設定檔案
<xml version="1.0"?><domain type=‘qemu‘>  <name>ReactOS-on-QEMU<name>  <uuid<uuid>  <memory>131072<memory>  <currentMemory>131072<currentMemory>  <vcpu>1<vcpu>  <os>    <type arch=‘i686‘ machine=‘pc‘>hvm<type>  <os>  <devices>    <emulator>usr/bin/qemu<emulator>    <disk type=‘file‘ device=‘disk‘>      <source file=‘/home/mtj/libvtest/ReactOS.vmdk‘/>      <target dev=‘hda‘/>    <disk>    <interface type=‘network‘>      <source network=‘default‘/>    <interface>    <graphics type=‘vnc‘ port=‘-1‘/>  <devices><domain>

完成了網域設定檔案之後,現在開始使用 virsh 工具啟動域。virsh 工具為要執行的特定動作採用命令參數。在啟動新域時,使用 create 命令和網域設定檔案:

清單 2. 啟動新域
[email protected]:~/libvtest$ virsh create react-qemu.xmlConnecting to uri: qemu:///systemDomain ReactOS-on-QEMU created from react-qemu.xml[email protected]:~/libvtest$

這裡要注意用於串連到域(qemu:///system)的 Universal Resource Indicator (URI)。該本地 URI 串連到本地 QEMU 驅動程式的系統模式守護進程上。要通過主機 shinchan 上的 Secure Shell (SSH) 協議串連到遠程 QEMU Hypervisor,可以使用 URL qemu+ssh://shinchan/。

下一步,您可以使用 virsh 內的 list 命令列出給定主機上的活動域。這樣做可以列出活動域,域 ID,以及它們的狀態,如下所示:

清單 3. 列出活動域
[email protected]:~/libvtest$ virsh listConnecting to uri: qemu:///system Id Name                 State----------------------------------  1 ReactOS-on-QEMU      running[email protected]:~/libvtest$

注意,這裡定義的名稱是在網域設定檔案中繼資料中定義過的名稱。可以看到,該域的網域名稱是 1 且正在運行中。

您也可以使用 suspend 命令中止域。該命令可停止處於調度中的域,不過該域仍存在於記憶體中,可快速恢複運行。下面的例子展示了如何中止域,執行列表查看狀態,然後重新啟動域:

清單 4. 中止域,檢查狀態,並重新啟動
[email protected]:~/libvtest$ virsh suspend 1Connecting to uri: qemu:///systemDomain 1 suspended[email protected]:~/libvtest$ virsh listConnecting to uri: qemu:///system Id Name                 State----------------------------------  1 ReactOS-on-QEMU      paused[email protected]:~/libvtest$ virsh resume 1Connecting to uri: qemu:///systemDomain 1 resumed[email protected]:~/libvtest$

virsh 工具也支援許多其他命令,比如儲存域的命令(save),恢複已存域的命令(restore),重新啟動域的命令(reboot),以及其他命令。您還可以從運行中的域(dumpxml)建立網域設定檔案。

到目前為止,我們已經啟動並操作了域,但是如何串連域來查看當前活動域呢?這可以通過 VNC 實現。要建立表示特定域圖形案頭的視窗,可以使用 VNC:

清單 5. 串連到域
[email protected]:~/libvtest$ xvnc4viewer 127.0.0.1 0
 

回頁首

libvirt 和 Python

上一個例子說明了如何使用命令列工具 virsh 實現對域的控制。現在我們看一個使用 Python 來控制域的例子。Python 是受 libvirt 支援的指令碼語言,它向 libvirt API 提供完全物件導向的介面。

在本例中,我研究了一些基本操作,與之前用 virsh 工具(listsuspendresume 等)展示的操作類似。Python 樣本指令碼見 清單 6。在本例中,我們從匯入 libvirt 模組開始。然後串連到本地 QEMU Hypervisor。從這裡開始,重複可用的域 ID;對每個 ID 建立一個域對象,然後中止,繼續,最後刪除該域。

清單 6. 用於控制域的樣本 Python 指令碼(libvtest.py)
import libvirtconn = libvirt.open(‘qemu:///system‘)for id in conn.listDomainsID():dom = conn.lookupByID(id)print "Dom %s  State %s" % ( dom.name(), dom.info()[0] )dom.suspend()print "Dom %s  State %s (after suspend)" % ( dom.name(), dom.info()[0] )dom.resume()print "Dom %s  State %s (after resume)" % ( dom.name(), dom.info()[0] )dom.destroy()

雖然這隻是個簡單樣本,我們仍然可以看到 libvirt 通過 Python 提供的強大功能。通過一個簡單的指令碼就能夠重複所有本地 QEMU 域,發行有關域的資訊,然後控制域。該指令碼的結果如 清單 7 所示。

清單 7. 清單 6 中的 Python 指令碼輸出的結果
[email protected]:~/libvtest$ python libvtest.pyDom ReactOS-on-QEMU  State 1Dom ReactOS-on-QEMU  State 3 (after suspend)Dom ReactOS-on-QEMU  State 1 (after resume)[email protected]:~/libvtest$
 

回頁首

API 概述

進階 libvirt API 可劃分為 5 個 API 部分:Hypervisor串連 API、域 API、網路功能 API、儲存卷 API 以及儲存池 API。

為給定Hypervisor建立串連後會產生所有 libvirt 通訊(例如,清單 6 中所示的 open 調用)。該串連為所有其他要使用的 API 提供路徑。在C API 中,該行為通過 virConnectOpen 調用(以及其他進行認證的調用)提供。這些函數的傳回值是一個 virConnectPtr 對象,它代表到Hypervisor的一個串連。該對象作為所有其他管理功能的基礎,是對給定Hypervisor進行並發 API 呼叫所必需的語句。重要的並發調用是 virConnectGetCapabilities 和 virNodeGetInfo,前者返回Hypervisor和驅動程式的功能,後者擷取有關節點的資訊。該資訊以 XML 文檔的形式返回,這樣通過解析便可瞭解可能發生的行為。

進入Hypervisor後,便可以使用一組 API 呼叫函數重複使用該Hypervisor上的各種資源。virConnectListDomains API 呼叫函數返回一列域標識符,它們代表該Hypervisor上的活動域。

API 實現大量針對域的函數。要探究或管理域,首先需要一個 virDomainPtr 對象。您可通過多種方式獲得該控制代碼(使用 ID、UUID 或網域名稱)。繼續來看重複域的例子,您可以使用該函數返回的索引表並調用 virDomainLookupByID 來擷取域控制代碼。有了該域控制代碼,就可以執行很多操作,從探究域(virDomainGetUUIDvirDomainGetInfovirDomainGetXMLDescvirDomainMemoryPeek)到控制域(virDomainCreatevirDomainSuspendvirDomainResumevirDomainDestroy 和 virDomainMigrate)。

您還可使用 API 管理並檢查虛擬網路和儲存資源。建立了 API 模型之後,需要一個 virNetworkPtr 對象來管理並檢查虛擬網路,且需要一個virStoragePoolPtr(儲存池)或 virStorageVolPtr(卷)對象來管理這些資源。

API 還支援一種事件機制,您可使用該機制註冊為在特定事件(比如域的啟動、中止、恢複或停止)發生時獲得通知。

 

回頁首

語言綁定

libvirt 庫用 C (支援 C++)實現,且包含對 Python 的直接支援。不過它還支援大量語言綁定。目前已經對 Ruby、Java™ 語言,Perl 和 OCaml 實施了綁定。在從 C# 調用 libvirt 方面我們已做了大量工作。libvirt 支援最流行的系統程式設計語言(C 和 C++)、多種指令碼語言、甚至一種統一的函數型語言(Objective caml)。因此,不管您側重何種語言,libvirt 都會提供一種路徑來協助您控制域。

 

回頁首

使用 libvirt 的應用程式

僅從本文已經展示的一小部分功能上便可看出 libvirt 提供的強大功能。且如您所願,有大量應用程式正成功構建於 libvirt 之上。其中一個有趣的應用程式就是 virsh(這裡所示),它是一種虛擬 shell。還有一種名為 virt-install 的應用程式,它可用於從多個作業系統發行版供應新域。virt-clone 可用於從另一個 VM 複製 VM(既包括作業系統複製也包括磁碟複製)。一些進階應用程式程式包括多用途案頭管理工具 virt-manager 和安全連線到 VM 圖形控制台的輕量級工具 virt-viewer。

構建於 libvirt 之上的一種最重要的工具名為 oVirt。oVirt VM 管理應用程式旨在管理單個節點上的單個 VM 或多個主機上的大量 VM。除了可以簡化大量主機和 VM 的管理之外,它還可用於跨平台和架構自動化叢集,Server Load Balancer和工作。

 深入探究

從這篇簡短的文章可以看出,libvirt 是一種用來構建應用程式的強大庫,能夠跨系統的大型網路在不同的Hypervisor環境中管理域。鑒於雲端運算的日漸流行,libvirt 無疑也會隨之發展,不斷獲得新的應用程式和使用者。撰寫本文時,libvirt 也僅有四年的發展史,因此在大規模可伸縮計算領域中相對較新。libvirt 將來肯定會有很大發展。

 

來自:http://www.ibm.com/developerworks/cn/linux/l-libvirt/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.