隨著計算機硬件的發展,人們對最大化利用硬件資源的需求日益迫切。從上世紀六、七十年代虛擬機概念的提出,到現在虛擬化技術的日益成熟,為人們這些需求的實現提供了有利的解決方案。基于IntelVT技術的KVM虛擬機,是一種采用硬件輔助虛擬化的全虛擬化方案,并在Linux 內核版本2.6.20 之后,以模塊的形式集成到內核的各個主要發行版本。KVM虛擬機吸收了QEMU、Bochs、UML、Virtual PC 等傳統虛擬機的長處和優勢,利用硬件輔助的虛擬化技術,使虛擬機的大多數指令可以直接在物理處理器上運行,具有更加優越的效率和性能。為了充分利用處理器的資源,往往需要虛擬機在某一指定個核上運行,而其它的核上運行特定的任務。本文基于CPU 的親和性(Affinity),采用進程綁定,實現了一種解決上述問題的有效方法。
1 Intel VT技術下的KVM虛擬機架構
KVM 虛擬機由兩部分構成:一部分是以模塊形式集成到Linux 內核的KVM Driver,負責管理虛擬硬件資源,并創建一個字符設備(/dev/kvm),通過ioctl接口與用戶空間的設備通信,以及完成虛擬機內存的分配、虛擬機寄存器的讀寫以及虛擬機CPU 的運行等。因此,每個虛擬機被Linux 核心當作是一個標準的進程。另一個部分是KQEMU,即針對有虛擬化支持的X86 處理器而修改過的QEMU。KQEMU 主要是完成對硬件的模擬,通過/dev/kvm 與KVM Driver 交互。KVM 虛擬機架構如圖1 所示:
在Intel VT-x 技術下有兩種工作模式:VMX rootoperation 模式和VMX non-root operation 模式。在這兩種模式下,KVM 虛擬機充分利用硬件的支持,實現了系統的虛擬化。KVM 的KVM Driver 和KQEMU分別運行于Kernel 模式的和User 模式。這里的Kernel模式和User 模式實際上指的是VMX root operation 模式下的特權級0 和特權級3。在圖1 中,Linux Kernel、KVM Driver 和/dev/kvm 都屬于VMX root operation 模式。另外,KVM 將客戶機所在的運行模式稱為Guest模式,即VMX 的VMX non-root operation 模式。
圖1 KVM 虛擬機架構
2 KQEMU和KVM工作原理
Intel VT-x 是與處理器管理相關的硬件虛擬化技術[6]。在VT-x 的支持下,KVM 中的每個虛擬機可具有多個虛擬處理器VCPU,每個VCPU 對應一個KQEMU 的線程,這個KQEMU 線程代表了KVM 虛擬機的運行。沒有硬件支持的純QEMU 虛擬機和利用硬件支持實現虛擬化的KVM 虛擬機的差異也就在這里。為了更加形象地說明KVM 和KQEMU 間的關系,本文稱它為KVM 線程,而將創建客戶機的應用程序KQEMU 稱為KQEMU 進程。KQEMU 應用程序在創建或者說在加載一個Guest OS 后,就轉換為KVM 線程運行。VCPU 的創建、初始化、運行以及退出處理都在KVM 線程上下文中進行,需要Kernel、User 和Guest 三種模式相互配合,其工作模型如圖2 所示:
圖2 KVM 工作模型
從圖2 可看出,KVM 線程以ioctl 的方式與KVM內核模塊間進行交互,指示KVM 內核模塊進行VCPU的創建和初始化等操作,而KVM 內核模塊與客戶機之間通過VM Exit 和VM entry 操作進行切換。初始化工作完成之后,KVM 線程以ioctl 的方式向KVM 內核模塊發出運行VCPU 的指示,后者執行虛擬機進入操作(VM entry),將處理器由Kernel 模式切換到Guest 模式,轉而運行客戶機。但此時仍處于KVM 線程上下文中,且正在執行ioctl 系統調用的kernel 模式處理程序。
客戶機在運行過程中,如發生異常或外部中斷等事件,或執行I/O 操作,可能導致虛擬機退出操作(VMexit),將處理器狀態由Guest 模式切換回Kernel 模式。KVM內核模塊檢查發生VM exit 的原因,如果VM exit由I/O 操作導致,則執行系統調用返回操作,將I/O操作交給處于User 模式的KQEMU 進程來處理,這時KQEMU會創建一個新的KQEMU線程來完成這些I/O處理,之后再次執行ioctl,指示KVM 將處理器切換到Guest 模式,恢復客戶機的運行;如果VM exit 由其它原因導致,則由KVM 內核模塊負責處理,并在處理后切換處理器到Guest 模式,恢復客戶機的運行。
由以上分析可知,KVM 虛擬化技術中物理CPU核的隔離實現,與KQEMU 應用程序、KVM 線程、異步IO 事件處理這三方面有著密切的聯系。
3 虛擬機進程隔離實現
3.1 隔離方案設計
在KVM 虛擬機運行的過程中,與虛擬機處理器緊密相關的重要數據結構VMCS保存在內存中,包含了虛擬CPU 的相關寄存器的內容和虛擬CPU 相關的控制信息,每個VMCS對應一個虛擬CPU。但VMCS具有“遷移性”,使用時需要與物理CPU 綁定。例如,某個VMCS 先和物理CPU0 綁定,并在某個時刻解除綁定關系,下一個時刻可能會重新綁定到物理CPU1上。在任意給定時刻,VMCS 與物理CPU 是一對一的綁定關系,即一個VMCS 只能與一個物理CPU 綁定。
因此,多核條件下要實現Guest OS 在一個虛擬的單核平臺上運行,就需要考慮KQEMU 應用程序、KVM 線程、異步IO 事件處理與CPU 的綁定關系。利用CPU 的親和性(Affinity),通過設置這三方面的Affinity 屬性,可以將Guest OS 進程綁定到指定的核上運行,從而實現虛擬的單核平臺。例如,在創建虛擬機時將兩個Guest OS 進程綁定到指定的CPU 核上,使其在整個運行期間不發生遷移,如圖3 所示:
圖3 客戶操作系統與CPU 核的綁定
根據KVM 原理和機制的分析,可以通過兩個方案實現綁定操作:
方案一:直接通過內核函數設置Guest OS 進程的屬性,實現Guest OS 保持運行在指定的核上。通過編寫腳本文件,使創建虛擬機和綁定兩項操作自動完成。
方案二:修改、優化KQEMU 源代碼,生成特定的KVM 虛擬機。在創建客戶機的時候實現綁定,使客戶機只能在指定核上的運行,不發生遷移。
從兩個方案的設計可知,方案一的主要是從KQEMU應用程序的應用出發的,它的實現必然要用到文件的讀寫和腳本的綁定,以及虛擬機管理器啟動腳本的修改。方案二是基于Qemu 源代碼的修改,綁定時機明顯早于方案一,實現過程也更簡單明了。除此之外,方案一從理論上來說,對有異步IO 時才產生的aio 線程的綁定可能出現問題,所以本文最終選擇方案二。
3.2 處理器隔離的實現方法
Linux 的線程在核內是以輕量級進程的形式存在的,而實現是在核外。它擁有獨立的進程表項,其創建、刪除等操作都是在核外POSIX thread 庫中進行。與fork() 調用創建一個進程的方法不同,pthread_create()創建的線程并不具備與主線程同樣的執行序列,而是使其運行start_routine()函數。因此,用fork 創建的父子進程之間的Affinity 具有繼承性,而調用pthread_create()創建的父子進程之間則沒有這種繼承性,KQEMU 和KVM 之間則是后者的情況。
因此,僅通過設置KQEMU 的Affinity 屬性不能實現KVM 虛擬機處理器的隔離。需分為兩部分處理:
①從啟動QEMU 的命令獲取cpuid 參數。這需要對KQEMU 源代碼進行修改,增加-cpuid 的命令選項,完成對參數的解析以及相關的綁定操作。主要涉及KQEMUOption、KQEMU_options 等幾個選項變量。
②根據解析獲得的cpuid 參數,對KQEMU 應用進程、KVM 線程、異步IO 事件處理線程運用Linux 內核的Affinity 機制進行綁定,實現對處理器的隔離。圖4 是以雙核處理器為例實現KVM虛擬機綁定的主要過程。
圖4 KVM 虛擬機進程綁定實現過程
4 實驗結果與分析
由設計思路的分析可知,對方案二實現方法需要驗證的是客戶機的創建、客戶機的運行,以及客戶機的異步IO 事件處理。本實驗中使用的測試平臺是:處理器是Pentium(R) Dual-Core CPU E5300 2.60GHz,內存為DDR2-800 2G , 操作系統內核版本是Linux-2.6.33.2 。GuestOS 運行測試程序是計算Fibonacci 前35 項和,每計算一次休眠15 毫秒。
執行命令qemu-system-x86_64 Guestos.img –m512–cpuid 1,在啟動Guest OS 時指定創建Guest OS進程的處理器參數cpuid,使創建客戶機的進程在指定的核1 運行。用top 命令的p 和H 參數,觀察KVM虛擬機運行時的進程號和線程號。
t1 時刻(19:33:34),KQEMU 進程號為3905,KVM線程號為3906,異步IO 事件處理線程號為3910,如圖5 所示:
圖5 t1 時刻KVM 虛擬機進程運行狀態
t2 時刻(20:43:20),KQEMU 進程號為3905,KVM線程號為3906,異步IO 事件處理線程號為4212,如圖6 所示。此時圖4 中線程號為3910 的aio 線程消失,動態產生aio 線程4212。
圖6 t2 時刻KVM 虛擬機進程運行狀態
根據Linux 內核的PID 命名規則可知,PID 逐漸遞增,aio 線程的產生是一個動態過程,根據Guest OS的需要而產生。從而進一步證實,如果用采用方案一,則難以實現aio線程的綁定。
經過長時間的實驗觀察,雖然運行Guest OS 時CPU 核1 的利用率達到94.7%左右,KVM 虛擬機始終保持在指定的核1 運行,即使核0 十分空閑,仍不會發生遷移。可以通過taskset 命令查看這三個進程的Affinity 值,得到進一步的驗證,如圖7 所示。圖中3905 , 3906 , 4212 進程的Affinity 值為2 ( 即0x00000010),表示相應進程或線程運行在核1 上。
圖7 用taskset 命令查看虛擬機進程的Affinity 值
5 結論
本文通過對KVM 虛擬機的綁定,實現了KVM 虛擬機處理器核之間的隔離,使KVM 虛擬機在指定的物理CPU 核上運行,不發生核間的遷移,從而達到物理CPU 資源的指定使用。當運行多個Guest OS 時,只需在運行時指定CPU 參數,即可讓各個Guest OS始終運行在指定的核上,進而能夠充分有效地利用計算機硬件資源。
核心關注:拓步ERP系統平臺是覆蓋了眾多的業務領域、行業應用,蘊涵了豐富的ERP管理思想,集成了ERP軟件業務管理理念,功能涉及供應鏈、成本、制造、CRM、HR等眾多業務領域的管理,全面涵蓋了企業關注ERP管理系統的核心領域,是眾多中小企業信息化建設首選的ERP管理軟件信賴品牌。
轉載請注明出處:拓步ERP資訊網http://m.hanmeixuan.com/
本文標題:KVM虛擬化技術中處理器隔離的實現