這篇文章將深入分析Linux中虛擬化技術的實現----KVM技術,從KVM技術的簡介、技術架構、以及虛擬機和宿主機交互的重要處理邏輯出發,深入探究KVM技術的實現。
一、KVM簡介:
首先,我們先查看一下KVM架構,看看它的整體工作流程:
上圖展示了KVM(Kernel-based Virtual Machine)的架構及其與QEMU的交互。以下是對該架構的說明:
-
?KVM Guest(虛擬機客戶機)?:
- ?Applications(應用程序)?:這是運行在虛擬機內的上層應用程序。
- ?File system and block devices(文件系統和塊設備)? 和 ?Drivers(驅動程序)?:這些組件為應用程序提供對存儲設備的訪問。
- ?VCPU(虛擬CPU)?:虛擬機內的虛擬處理器,圖中展示了
vcpu0
到vcpuN
,代表多個虛擬CPU。
-
?Hardware Emulation (QEMU)?:
- ?QEMU(硬件模擬)?:QEMU負責模擬硬件,使得虛擬機可以運行在不同于宿主機硬件的環境中。
- ?ioTHREAD?:這是QEMU中的一個線程,負責生成I/O請求并處理這些請求,ioTHREAD代表虛擬機處理輸入/輸出操作,如讀寫磁盤數據。
-
?KVM (kvm.ko)?:
- ?KVM模塊(kvm.ko)?:這是Linux內核中的一個模塊,用于直接在內核中實現虛擬化功能。KVM本身不實現硬件模擬,而是與QEMU結合使用,通過QEMU進行硬件模擬。
- ?File system and block devices(文件系統和塊設備)? 和 ?Physical drivers(物理驅動程序)?:這些組件用于連接KVM模塊與實際的硬件,如磁盤。
-
?Hardware(硬件)?:
- ?CPU(中央處理器)?:物理CPU,被虛擬化為多個虛擬CPU(如
cpu0
,?cpuN
)供虛擬機使用。 - ?Disk(磁盤)?:物理存儲設備,被虛擬機通過文件系統和塊設備訪問。
- ?CPU(中央處理器)?:物理CPU,被虛擬化為多個虛擬CPU(如
?KVM與QEMU的交互?:
- QEMU通過IOTHREAD生成I/O請求并處理這些請求,這些請求代表虛擬機與硬件的交互。
- KVM模塊(kvm.ko)在Linux內核中運行,管理虛擬機的VCPU,并與QEMU協作,確保虛擬機能夠運行并訪問硬件資源。
- 整個系統通過
qemu_mutex
機制確保在任何時刻只有一個線程可以運行QEMU代碼,從而避免競態條件和數據不一致。 - 在創建虛擬機時,QEMU會調用KVM提供的接口來創建虛擬機、分配vCPU等。同時,QEMU還負責模擬虛擬機的其他硬件設備,如網卡、串口等?。
- 在虛擬機運行過程中,QEMU會發起對vCPU的運行請求,KVM則負責實際運行vCPU,并在需要時與QEMU進行交互,如處理I/O請求等?。
總結來說,KVM和QEMU的結合提供了一種高效的虛擬化解決方案,KVM負責虛擬CPU的管理和調度,而QEMU則負責硬件模擬和I/O處理,兩者緊密協作,使得虛擬機能夠在宿主機上高效運行。
綜上所述,QEMU和KVM通過特定的接口和機制進行交互,共同實現了虛擬機的創建、運行和I/O虛擬化處理等功能。
二、深入KVM工作流程:
通過下圖來解析KVM的工作流程:
通過上圖所示QEMU與KVM整體架構圖,可以詳細了解KVM(Kernel-based Virtual Machine)的工作流程。下面通過舉例來說明KVM的工作流程:
-
?硬件平臺與系統總線?:
- 圖左側顯示了一個模擬平臺,包含系統總線、VGA、PCI總線、內存及vCPU等硬件資源。這些資源通過QEMU進行模擬,并在宿主機上實現虛擬化。
-
?KVM API與主循環?:
- 宿主機內核中包含了KVM API(/dev/kvm),通過該接口用戶空間的QEMU進程可以與內核中的虛擬化模塊進行交互。
- QEMU通過KVM API將虛擬機的指令和操作傳遞給KVM模塊。
-
?虛擬機入口(VM Entry)?:
- 當虛擬機需要執行時,通過VM Entry進入虛擬機環境。此時,虛擬機的vCPU與宿主機上的物理CPU進行交互。
- 網卡驅動、磁盤驅動和顯卡驅動等虛擬機設備驅動通過gCR3表(影子頁表)與宿主機資源進行映射和交互。
-
?虛擬機狀態與掛起/恢復?:
- VMCS(Virtual Machine Control Structure)保存了虛擬機的狀態,包括物理機狀態和虛擬機狀態。
- 當虛擬機需要掛起時(例如,保存當前運行狀態),其狀態信息會被保存到VMCS中。
- 恢復時,通過檢查掛起的信號,如果滿足進入Guest模式的條件,則通過handle exit處理退出事件,并重新進入虛擬機執行。
-
?應用程序與虛擬機?:
- 虛擬機中的應用程序1和應用程序2通過vCPU執行,vCPU通過影子頁表(gCR3)訪問宿主機資源。
- 虛擬機中的操作通過VCPU與QEMU進行交互,QEMU再通過KVM API將操作傳遞給KVM模塊處理。
?示例說明?:
假設有一個宿主機運行Linux操作系統,并在其上通過KVM和QEMU創建了一個Ubuntu虛擬機。
-
?啟動虛擬機?:
- 用戶啟動QEMU進程,通過KVM API創建和初始化虛擬機的vCPU、內存和I/O設備等資源。
- QEMU將虛擬機的指令和操作通過KVM API傳遞給KVM模塊,KVM模塊將這些操作映射到宿主機的物理CPU和內存上。
-
?虛擬機運行?:
- 虛擬機啟動后,其vCPU通過VM Entry進入虛擬機環境,開始執行Ubuntu操作系統。
- 虛擬機中的應用程序在vCPU上運行,并通過影子頁表(也可使用EPT方式)訪問宿主機的硬件資源,例如通過網絡驅動訪問網絡,通過磁盤驅動訪問存儲設備等。
-
?掛起與恢復?:
- 假設虛擬機正在進行一個長時間的計算任務,用戶決定暫時掛起虛擬機去處理其他事情。
- QEMU通過KVM API將虛擬機的當前狀態(包括CPU寄存器、內存狀態等)保存到VMCS中。
- 用戶事情處理完后,決定恢復虛擬機,QEMU通過KVM API從VMCS中恢復虛擬機狀態,并通過handle exit處理恢復邏輯,使虛擬機繼續執行之前的任務。
本篇博客主要分析了KVM模塊和QEMU的整體架構、以及它們是如何協同工作的,后面會深入內核源碼去探究KVM模塊的具體實現。
本博客的內容參考了書籍:《QEMU_KVM源碼解析與應用》
歡迎大家一起來探討虛擬化技術,后期我會針對KVM技術進行更深入的分析,并且會結合eBPF技術,分享如何去觀測KVM模塊,大家可以持續關注專欄《虛擬化技術》。