簡介: Libvirt 庫是一種實現 Linux 虛擬化功能的 Linux® API,它支持各類虛擬機監控程序,包括 Xen 和 KVM,以及 QEMU 和用於其餘操做系統的一些虛擬產品。本文主要探討 libvirt 及其用途和架構。php
講到向外擴展計算(好比雲計算),libvirt 多是您從未據說過的最重要的庫之一。libvirt 提供一種虛擬機監控程序不可知的 API 來安全管理運行於主機上的來賓操做系統。libvirt 自己 不是一種工具, 它是一種能夠創建工具來管理來賓操做系統的 API。libvirt 自己構建於一種抽象的概念之上。它爲受支持的虛擬機監控程序實現的經常使用功能提供通用的 API。libvirt 起初是專門爲 Xen 設計的一種管理 API,後來被擴展爲可支持多個虛擬機監控程序。 html
基本架構 python
首先讓咱們從用例模型視角來展開對 libvirt 的討論,而後深刻探究其架構和用途。libvirt 以一組 API 的形式存在,旨在供管理應用程序使用(見圖 1 )。libvirt 經過一種特定於虛擬機監控程序的機制與每一個有效虛擬機監控程序進行通訊,以完成 API 請求。文章後面我將探討如何經過 QEMU 來實現該功能。react
圖中還顯示了 libvirt 所用術語對照。這些術語很重要,由於在對 API 命名時會用到它們。兩個根本區別在於,libvirt 將物理主機稱做節點,未來賓操做系統稱做域。這裏須要注意的是,libvirt(及其應用程序)在宿主 Linux 操做系統(域 0)中運行。linux
控制方式shell
使用 libvirt,咱們有兩種不一樣的控制方式。第一種如 圖 1 所示,其中管理應用程序和域位於同一節點上。 在本例中,管理應用程序經過 libvirt 工做,以控制本地域。當管理應用程序和域位於不一樣節點上時,便產生了另外一種控制方式。在本例中須要進行遠程通訊(參見 圖 2)。該模式使用一種運行於遠程節點上、名爲 libvirtd 的特殊守護進程。當在新節點上安裝 libvirt 時該程序會自動啓動,且可自動肯定本地虛擬機監控程序併爲其安裝驅動程序(稍後討論)。該管理應用程序經過一種通用協議從本地 libvirt 鏈接到遠程 libvirtd。對於 QEMU,協議在 QEMU 監視器處結束。QEMU 包含一個監測控制檯,它容許檢查運行中的來賓操做系統並控制虛擬機(VM)各部分。編程
爲支持各類虛擬機監控程序的可擴展性,libvirt 實施一種基於驅動程序的架構,該架構容許一種通用的 API 以通用方式爲大量潛在的虛擬機監控程序提供服務。這意味着,一些虛擬機監控程序的某些專業功能在 API 中不可見。另外,有些虛擬機監控程序可能不能實施全部 API 功能,於是在特定驅動程序內被定義爲不受支持。圖 3 展現了 libvirt API 與相關驅動程序的層次結構。這裏也須要注意,libvirtd 提供從遠程應用程序訪問本地域的方式。服務器
在撰寫此文時,libvirt 爲表 1 所列的虛擬機監控程序實現了驅動程序。隨着新的虛擬機監控程序在開源社區出現,其餘驅動程序無疑也將可用。 網絡
虛擬機監控程序 | 描述 |
---|---|
Xen | 面向 IA-32,IA-64 和 PowerPC 970 架構的虛擬機監控程序 |
QEMU | 面向各類架構的平臺仿真器 |
Kernel-based Virtual Machine (KVM) | Linux 平臺仿真器 |
Linux Containers(LXC) | 用於操做系統虛擬化的 Linux(輕量級)容器 |
OpenVZ | 基於 Linux 內核的操做系統級虛擬化 |
VirtualBox | x86 虛擬化虛擬機監控程序 |
User Mode Linux | 面向各類架構的 Linux 平臺仿真器 |
Test | 面向僞虛擬機監控程序的測試驅動器 |
Storage | 存儲池驅動器(本地磁盤,網絡磁盤,iSCSI 卷) |
上面已經介紹了 libvirt 的一些架構,接下來看一下如何使用 libvirt 虛擬化 API 的一些示例。首先介紹一種名爲 virsh(虛擬 shell)的應用程序,它構建於 libvirt 之上。該 shell 容許以交互(基於 shell)方式使用多個 libvirt 功能。在本節中,我使用 virsh 演示了一些 VM 操做。
第一步是要定義域配置文件(以下面的 清單 1 所示)。該代碼指定了定義域所需的全部選項 — 從虛擬機監控程序(仿真器)到域使用的資源以及外圍配置(好比網絡)。注意,這只是個簡單的配置,libvirt 真正支持的屬性更加多樣化。例如,您能夠指定 BIOS 和主機引導程序,域要使用的資源,以及要用到的設備 — 從軟盤和 CD-ROM 到 USB 和 PCI 設備。
域配置文件定義該 QEMU 域要使用的一些基本元數據,包括域名、最大內存、初始可用內存(當前)以及該域可用的虛擬處理器數量。您不須要本身分配 Universally Unique Idenifier (UUID),而是讓 libvirt 分配。您須要爲該平臺定義要仿真的機器類型 — 在本例中是被徹底虛擬化(hvm)的 686 處理器。您須要爲域定義仿真器的位置(以備須要支持多個同類型仿真器時使用)和虛擬磁盤。這裏注意要指明 VM,它是以 Virtual Machine Disk(VMDK)格式存在的 ReactOS 操做系統。最後,要指定默認網絡設置,並使用面向圖形的 Virtual Network Computing (VNC)。
<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
命令和域配置文件:
mtj@mtj-desktop:~/libvtest$ virsh create react-qemu.xml Connecting to uri: qemu:///system Domain ReactOS-on-QEMU created from react-qemu.xml mtj@mtj-desktop:~/libvtest$ |
這裏要注意用於鏈接到域(qemu:///system
)的 Universal Resource Indicator (URI)。該本地 URI 鏈接到本地 QEMU 驅動程序的系統模式守護進程上。要經過主機 shinchan 上的 Secure Shell (SSH) 協議鏈接到遠程 QEMU 虛擬機監控程序,可使用 URL qemu+ssh://shinchan/。
下一步,您可使用 virsh 內的 list
命令列出給定主機上的活動域。這樣作能夠列出活動域,域 ID,以及它們的狀態,以下所示:
mtj@mtj-desktop:~/libvtest$ virsh list Connecting to uri: qemu:///system Id Name State ---------------------------------- 1 ReactOS-on-QEMU running mtj@mtj-desktop:~/libvtest$ |
注意,這裏定義的名稱是在域配置文件元數據中定義過的名稱。能夠看到,該域的域名是 1 且正在運行中。
您也可使用 suspend
命令停止域。該命令可中止處於調度中的域,不過該域仍存在於內存中,可快速恢復運行。下面的例子展現瞭如何停止域,執行列表查看狀態,而後從新啓動域:
mtj@mtj-desktop:~/libvtest$ virsh suspend 1 Connecting to uri: qemu:///system Domain 1 suspended mtj@mtj-desktop:~/libvtest$ virsh list Connecting to uri: qemu:///system Id Name State ---------------------------------- 1 ReactOS-on-QEMU paused mtj@mtj-desktop:~/libvtest$ virsh resume 1 Connecting to uri: qemu:///system Domain 1 resumed mtj@mtj-desktop:~/libvtest$ |
virsh 工具也支持許多其餘命令,好比保存域的命令(save
),恢復已存域的命令(restore
),從新啓動域的命令(reboot
),以及其餘命令。您還能夠從運行中的域(dumpxml
)建立域配置文件。
到目前爲止,咱們已經啓動並操做了域,可是如何鏈接域來查看當前活動域呢?這能夠經過 VNC 實現。要建立表示特定域圖形桌面的窗口,可使用 VNC:
mtj@mtj-desktop:~/libvtest$ xvnc4viewer 127.0.0.1 0 |
上一個例子說明了如何使用命令行工具 virsh 實現對域的控制。如今咱們看一個使用 Python 來控制域的例子。Python 是受 libvirt 支持的腳本語言,它向 libvirt API 提供徹底面向對象的接口。
在本例中,我研究了一些基本操做,與以前用 virsh 工具(list
、suspend
、resume
等)展現的操做相似。Python 示例腳本見 清單 6。在本例中,咱們從導入 libvirt 模塊開始。而後鏈接到本地 QEMU 虛擬機監控程序。從這裏開始,重複可用的域 ID;對每一個 ID 建立一個域對象,而後停止,繼續,最後刪除該域。
import libvirt conn = 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 所示。
mtj@mtj-desktop:~/libvtest$ python libvtest.py Dom ReactOS-on-QEMU State 1 Dom ReactOS-on-QEMU State 3 (after suspend) Dom ReactOS-on-QEMU State 1 (after resume) mtj@mtj-desktop:~/libvtest$ |
高級 libvirt API 可劃分爲 5 個 API 部分:虛擬機監控程序鏈接 API、域 API、網絡 API、存儲卷 API 以及存儲池 API。
爲給定虛擬機監控程序建立鏈接後會產生全部 libvirt 通訊(例如,清單 6 中所示的 open
調用)。該鏈接爲全部其餘要使用的 API 提供路徑。在 C
API 中,該行爲經過 virConnectOpen
調用(以及其餘進行認證的調用)提供。這些函數的返回值是一個 virConnectPtr
對象,它表明到虛擬機監控程序的一個鏈接。該對象做爲全部其餘管理功能的基礎,是對給定虛擬機監控程序進行併發 API 調用所必需的語句。重要的併發調用是 virConnectGetCapabilities
和 virNodeGetInfo
,前者返回虛擬機監控程序和驅動程序的功能,後者獲取有關節點的信息。該信息以 XML 文檔的形式返回,這樣經過解析即可瞭解可能發生的行爲。
進入虛擬機監控程序後,即可以使用一組 API 調用函數重複使用該虛擬機監控程序上的各類資源。virConnectListDomains
API 調用函數返回一列域標識符,它們表明該虛擬機監控程序上的活動域。
API 實現大量針對域的函數。要探究或管理域,首先須要一個 virDomainPtr
對象。您可經過多種方式得到該句柄(使用 ID、UUID 或域名)。繼續來看重複域的例子,您可使用該函數返回的索引表並調用 virDomainLookupByID
來獲取域句柄。有了該域句柄,就能夠執行不少操做,從探究域(virDomainGetUUID
、virDomainGetInfo
、virDomainGetXMLDesc
、virDomainMemoryPeek
)到控制域(virDomainCreate
、virDomainSuspend
、virDomainResume
、virDomainDestroy
和 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 之上。其中一個有趣的應用程序就是 virsh(這裏所示),它是一種虛擬 shell。還有一種名爲 virt-install 的應用程序,它可用於從多個操做系統發行版供應新域。virt-clone 可用於從另外一個 VM 複製 VM(既包括操做系統複製也包括磁盤複製)。一些高級應用程序包括多用途桌面管理工具 virt-manager 和安全鏈接到 VM 圖形控制檯的輕量級工具 virt-viewer。
構建於 libvirt 之上的一種最重要的工具名爲 oVirt。oVirt VM 管理應用程序旨在管理單個節點上的單個 VM 或多個主機上的大量 VM。除了能夠簡化大量主機和 VM 的管理以外,它還可用於跨平臺和架構自動化集羣,負載平衡和工做。
從這篇簡短的文章能夠看出,libvirt 是一種用來構建應用程序的強大庫,可以跨系統的大型網絡在不一樣的虛擬機監控程序環境中管理域。鑑於雲計算的日漸流行,libvirt 無疑也會隨之發展,不斷得到新的應用程序和用戶。撰寫本文時,libvirt 也僅有四年的發展史,所以在大規模可伸縮計算領域中相對較新。libvirt 未來確定會有很大發展。
學習
得到產品和技術
討論