python调用libvirt_libvirt
虛擬化是目前市場上大多數服務器操作系統的標準設備。在 Linux? 的世界里,服務器虛擬化有兩個主要選擇:基于 Kernel 的虛擬機 (KVM) 和 Xen。KVM 是 Red Hat 和其他公司采用的主要技術。雖然 Citrix 擁有 Xen,但是大多數核心功能是向外公開的。
虛擬機管理器(VMM 或 virt-manager )項目為管理 KVM 和 Xen 虛擬機 (VM) 實例的創建和運行提供了一個工具。VMM 是用 Python 編寫的,它使用 GTK+ 庫來完成圖形用戶界面的構造。真實的構造是通過 libvirt 庫完成的,本系列文章中會用到這個庫。雖然 libvirt 是由 Red Hat 贊助研發的產品,但它是為一個開源項目,可通過 GNU Lesser General Public License 獲得。
libvirt 由幾個不同的部分組成,其中包括應用程序編程接口 (API) 庫、一個守護進程 (libvirtd),以及一個默認命令行實用工具 (virsh)。出于本文的目的,所有測試均使用 Ubuntu Server version 11.04 完成。 安裝與設置 部分介紹了我通過配置服務器來開發此處展示的腳本的所有步驟。第 1 部分介紹了 libvirt 和 KVM 虛擬化的基礎知識,以及引發您的興趣的一些命令行腳本。第 2 部分將深入探討如何使用 libvirt 、Python 和 wxPython 構建您自己的虛擬化管理工具。
準備開始
在深入研究實際代碼示例之前,先讓我們復習一些關于虛擬化和 KVM 的術語和概念。當您在 Ubuntu Server 11.04 等服務器上安裝 KVM 時,同時也在創建一個 虛擬化主機 或 虛擬機管理程序 。這意味著,您的服務器可以管理運行在 KVM 主機上的多個來賓操作系統 (guest operating system)。每個惟一的來賓均被稱為一個 域 和函數,它們以與您期望的大致相同的方式出現在個人機器上的單個服務器實例中。您可以通過安全外殼 (SSH) 或虛擬網絡計算連接至服務器,就像連接至物理機器一樣。
雖然 KVM 的功能與虛擬機管理程序或來賓管理器相似,但是 QEMU 提供了實際的機器仿真,這意味著 QEMU 可以執行目標機器的本機指令集。對于 x86 來賓操作系統,該執行會轉換成為底層硬件上的直接執行的本機指令。對于其他架構,如 ARM,必須執行轉換進程。KVM 和 QEMU 的組合提供了虛擬化所有目前可用以及某些不再可用的操作系統所需的所有支持函數。
來賓域 包含若干個文件,其中包括一個或多個磁盤映像文件和一個基于 XML 的配置文件。該設置使得管理多臺 VM 變得極其簡單,方法是先創建一個基準系統映像,然后修改配置文件,使之符合您的需求。配置 KVM/QEMU 并與之通信的一個方法是使用 libvirt 工具包。一些供應商已經基于 libvirt 標準化其管理產品。
下面來看一個典型的域配置文件的內容。 清單 1 顯示了來自 libvirt 示例的 testdev.xml 文件。
清單 1. 設備 XML 定義
File_test_device
Libvirt
Test driver
123456
11111111-2222-3333-4444-555555555555
Libvirt
Test Driver
01/22/2007
Show moreShow more icon
從 清單 2 顯示的測試 domfv0.xml 文件中,您可以看到關于配置虛擬設備的更多詳細信息。
清單 2. domfv0.xml 設備定義文件
/usr/lib/xen/bin/qemu-dm
Show moreShow more icon
這里的重點是,您可以相對輕松地讀取這些文件并繼,然后創建自己的文件。雖然您可以手動構建任意數量的配置文件,但也可以使用像 Python 這樣的腳本語言來自動化構建過程。
安裝與設置
由于本文談論的是為 KVM 編寫腳本,所以有一個基礎假設:您擁有一個安裝了 KVM 的服務器。在使用 Ubuntu Server 11.04 的情況下,通過選擇 Software selection 屏幕上的 Virtual Machine Host 選項,您在設置過程中有一個安裝虛擬化的選項。您可能還想要選擇 OpenSSH 服務器,因為您想遠程連接至該機器。
第一項任務是安裝最新版的 libvirt 。為此,您必須執行一些命令行命令。當安裝 Ubuntu Server 11.04 之后,獲得的 libvirt 版本為 0.8.8。而 libvirt 網站上提供的最新、最強大的版本是 0.9.5。要安裝較新的版本,則需要將一個 Personal Package Archive (PPA) 儲存庫添加到包含新版 libvirt 的系統。在 launchpad.net 網站上快速搜索 libvirt 會顯示一些可能的候選對象。在嘗試執行更新之前查看儲存庫詳細信息頁面非常重要,因為一些存儲庫中可能包含損壞的軟件包。Ubuntu Virtualization Team 維護了一個包含一些軟件包(包括 libvirt )的 PPA 存儲庫。在撰寫本文時,libvirt 的最新版本為 0.9.2-4。
請執行以下步驟來安裝此版本:
安裝 python-software-properties 軟件包如下所示:
sudo apt-get install python-software-propertiesShow moreShow more icon
該命令使得 add-apt-repository 命令變得可用,您需要引用第三方來源。
輸入以下命令:
sudo add-apt-repository ppa:ubuntu-virt/ppa
sudo apt-get update
sudo apt-get install libvirt-binShow moreShow more icon
由于您要使用 Python 完成本文中的所有腳本編寫,所以請安裝 IDLE Shell,它會使腳本的編寫和測試變得更容易。
此步驟假設:您已在 Ubuntu 服務器上安裝了桌面環境。安裝桌面的最快捷方法是使用下列的命令:
sudo apt-get install ubuntu-desktopShow moreShow more icon
完成上述操作之后,您就可以訪問任意數量的圖形應用程序和 Ubuntu 軟件安裝程序。您可以使用 Ubuntu Software Center 來安裝 Python IDLE 工具。
樣例腳本
此時,在深入研究代碼之前,讓我們先來看一下使用 libvirt 的基礎知識。應用程序與 libvirt 庫之間的通信使用了一個簡單的遠程過程調用機制,該機制使得構建應用程序、從而通過 TCP/IP 連接與遠程虛擬機管理程序進行通信成為可能。統一資源標識符(URI,由 Internet Engineering Task Force [IETF] Request for Comments [RFC] 2396 定義)用于標識您想用來建立連接的特定虛擬機管理程序。
雖然有些遠程連接需要進行身份驗證,但本地連接通常不需要進行身份驗證。libvirt.conf 文件控制著安全配置。通過與某個域進行通信來進行最為廣泛的控制是通過網絡過濾來實現的。下面列出了如何使用過濾器控制網絡通訊量的一個示例:
Show moreShow more icon
這個代碼片段定義了一個名為 clean-traffic 的過濾器,可用它來計算通過指定的媒體訪問控制 (MAC) 地址的所有網絡通訊量。如果您查看一下 clean-traffic XML,就會發現它包含以下內容:
6f145c54-e3de-4c33-544a-70b69c16d9da
Show moreShow more icon
過濾器功能有大量完整的相關文檔記錄。如果您想要 libvirt 文檔和樣例文件的本地副本,只需使用一條命令即可。在這里,您只需執行以下命令即可:
sudo apt-get install libvirt-docShow moreShow more icon
操作完成后,所有的文檔都會出現在 /usr/share/doc/libvirt-doc 目錄中。稍后您會看到一些 Python 示例。如果您已經更新至較新的 libvirt 版本,那么您可能需要明確安裝 Python 綁定。完成此項操作只需執行一條命令:
sudo apt-get install python-libvirtShow moreShow more icon
可以使用 Python 的 IDLE 控制臺查看 Python 代碼,從而使用本地 QEMU 實例建立連接,然后查看已定義的域。 清單 3 顯示了您使用此方法會看到的內容。
清單 3. 在 IDLEV 控制臺中查看 Python 代碼
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53)
[GCC 4.5.2] on linux2
Type "copyright", "credits" or "license()" for more information.
==== No Subprocess ====
>>> import libvirt
>>> conn=libvirt.open("qemu:///system")
>>> names = conn.listDefinedDomains()
>>> print names
['Test1', 'SBSLite', 'UbuntuServer1104', 'Win7_64-bit']]
>>>Show moreShow more icon
此代碼顯示了如何獲取所有已定義域的列表。 listDefinedDomains() 函數的返回結果中顯示了一個包含 4 個已命名域的列表。建立到虛擬機管理程序的連接之后,就可以訪問可用函數的細目清單。以下是一個較短的腳本,顯示了如何獲取 conn 對象上所有可用函數的列表:
clist = dir(conn)
for item in clist:
print itemShow moreShow more icon
要查看已定義過濾器的列表,您可以使用相似的方法:
filts = conn.listNWFilters()
for item in filts:
print itemShow moreShow more icon
IDLE 工具是一個很不錯的方法,可用它來調查各種 API 調用,并在執行調用之后快速查看返回的結果。有些函數只能在運行域上執行。Python dir() 函數會返回指定對象的有效屬性列表。它是一個便利的命令行工具,可快速查看特定對象提供的屬性。您可以如上所示,在與虛擬機管理程序創建連接之后,使用該工具來獲得可用函數列表。
要進行演示,您可以在 IDLE 控制臺中使用幾行 Python 代碼,通過這些了解您可以在特定域上執行哪些類型的操作。 清單 4 提供了您能執行的操作的一個示例。
清單 4. 域對象的 Python 輸出
>>> import libvirt
>>> import pprint
>>> conn=libvirt.open("qemu:///system")
>>> p = conn.lookupByName('ubuntu100403')
>>> pprint.pprint(dir(p))
['ID',
'OSType',
'UUID',
'UUIDString',
'XMLDesc',
'__del__',
'__doc__',
'__init__',
'__module__',
'_conn',
'_o',
'abortJob',
'attachDevice',
'attachDeviceFlags',
'autostart',
'blkioParameters',
'blockInfo',
'blockPeek',
'blockStats',
'connect',
'coreDump',
'create',
'createWithFlags',
'destroy',
'detachDevice',
'detachDeviceFlags',
'hasCurrentSnapshot',
'hasManagedSaveImage',
'info',
'injectNMI',
'interfaceStats',
'isActive',
'isPersistent',Show moreShow more icon
您可以使用這種基本方法來構建一個簡單的腳本,以列出有關所有運行域的信息。可以使用 listDomainsID() 和 lookupByID() 函數調用來完成大多數的工作,如 清單 5 所示。
清單 5. 用 Python 編寫的列出域的腳本
import libvirt
conn=libvirt.open("qemu:///system")
for id in conn.listDomainsID():
dom = conn.lookupByID(id)
infos = dom.info()
print 'ID = %d' % id
print 'Name = %s' % dom.name()
print 'State = %d' % infos[0]
print 'Max Memory = %d' % infos[1]
print 'Number of virt CPUs = %d' % infos[3]
print 'CPU Time (in ns) = %d' % infos[2]
print ' 'Show moreShow more icon
在此腳本的輸出中,有一個域處于激活狀態,另一個為掛起狀態,如下所示:
ID = 3
Name = ubuntu100403
State = 3
Max Memory = 1048576
Number of virt CPUs = 1
CPU Time (in ns) = 1048576
ID = 4
Name = Win7_64-bit
State = 1
Max Memory = 2097152
Number of virt CPUs = 2
CPU Time (in ns) = 2097152Show moreShow more icon
libvirt 還為所有的類和方法實現了 Python 文檔字符串。您可以訪問其信息,方法是輸入 help (libvirt) 獲得頂級幫助信息,或通過 help(libvirt.class) 獲取特定的類。您必須在輸入 help() 命令前先導入 libvirt 模塊。我所測試的版本實現下列 11 個類:
libvirtError
virConnect
virDomain
virDomainShapshot
virInterface
virNWFilter
virNetwork
virSecret
virStoragePool
virStorageVol
virStream
此列表能幫助您從 Python 解碼訪問 libvirt 函數的語法。該列表還為您提供所有已命名常數的列表,比如 VIR_DOMAIN_RUNNING ,該常數等同 1。上面使用過的一些函數(如 dom.info() )會返回一個整數值,您需要對照常數表對其進行解碼。
利用實用工具腳本實現自動化
您可以使用 libvirt 和 Python 編寫一些腳本來管理 KVM 安裝。雖然對于少部分域而言這種方法是無效的,但在域的數量達到兩位數時,這樣做可以快速節省時間。一個簡單的任務就可能讓所有域映像的靜態 IP 地址做出大量修改。您可以通過迭代所有 .conf 文件并進行相應修改來完成此任務。Python 擁有許多內置功能,可幫助完成此項任務。
清單 6 顯示了一個 XML 網絡定義示例。
清單 6. 網絡配置 XML 文件
testnetwork
Show moreShow more icon
如果想要將主要的子網絡從 192.168.100 改為 192.168.200,可以在編輯器中打開配置文件并進行全局搜索和替換。當您想要做一些較復雜的操作時,比如向所有以 2 開始的 IP 地址和 MAC 地址添加 10,這個技巧非常有用。 清單 7 顯示了如何只使用 20 多行 Python 代碼就能完成此項任務。
清單 7. 更改 MAC 和 IP 地址的 Python 腳本
#!/usr/bin/env python
from xml.dom.minidom import parseString
import sys
def main():
target = sys.argv[1]
number = int(sys.argv[2])
xml = open(target, 'r').read()
doc = parseString(xml)
for host in doc.getElementsByTagName('host'):
ip = host.getAttribute('ip')
parts = ip.split('.')
parts[-1] = str(int(parts[-1]) + number)
host.setAttribute('ip', '.'.join(parts))
mac = host.getAttribute('mac')
parts = mac.split(':')
parts[-1] = str(int(parts[-1]) + number)
host.setAttribute('mac', ':'.join(parts))
f = open(target, 'w')
f.write(doc.toxml())
f.close()
if __name__ == '__main__':
main()Show moreShow more icon
此腳本演示了您使用 Python Standard Library 時所展現的 Python 的強大功能。在這里,使用了 xml.dom.minidom 的 parseString 來完成解析 XML 文件的重任。擁有特定的 XML 屬性后,只需使用 Python string.split 函數將其分成幾塊即可。接著,要進行匹配,并將字符串再連在一起。您可以擴展這個方法,將它用于任何 XML 文件的批量更改,這些文件中包括 libvirt 的 .conf 文件。
另一個有用的腳本將獲取所有正在運行的域的快照。該腳本首先需要獲取所有正在運行的域的列表,然后分別暫停每個域并獲取每個域的快照。雖然此操作對生產環境不太實用,但是您可以將其設置為在午夜作為一個 CRON 作業運行。該腳本可以輕松實現目前為止突出顯示的命令和 snapshotCreateXML() 調用。
結束語
本文只是粗淺地介紹了 libvirt 所包含的功能。請參閱 參考資料 部分,從那里獲得更深入地研究 libvirt 和虛擬化的更多文章的鏈接。當您開始嘗試通過實現代碼來監視和管理您的環境時,掌握 KVM 基礎知識只是一個開始。本系列文章的下一期文章將以此為基礎,構建一些實際的虛擬管理工具。
本文翻譯自:libvirt(2011-12-06)
總結
以上是生活随笔為你收集整理的python调用libvirt_libvirt的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第四周之圆柱面积
- 下一篇: python滑动窗口求回归——OLS和W