KVM 虛拟化學習筆記
什麼是KVM?
Kernel-based Virtual Machine的簡稱,是一個 Linux Kernel 的子產品。它是一種全虛拟化的解決方案,目前在x86,AMD和ARM都已經支援。使用KVM虛拟機,你可以在其上運作沒有修改過代碼的Linux 和 Windows 作業系統。
KVM 開發環境
本學習筆記主要是針對 kernel + kvmtool 的環境來學習KVM虛拟化。
kernel 下載下傳位址
git://git.kernel.org/pub/scm/linux/kernel/git/bonzini/linux.git
https://git.kernel.org/pub/scm/linux/kernel/git/bonzini/linux.git
https://kernel.googlesource.com/pub/scm/linux/kernel/git/bonzini/linux.git
kvmtool 的下載下傳位址
git://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
https://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
https://kernel.googlesource.com/pub/scm/linux/kernel/git/will/kvmtool.git
開發環境:ubuntu (linux-like system)+ kvmtool + guest kernel,共享本地的rootfs
kvmtool
可能有的小夥伴要問了,什麼是kvmtool,不是都用qemu嗎?
kvmtool 是一個輕量級的虛拟化工具,用來虛拟化與本地相同架構的虛拟機。
同時因為qemu太過于龐大,其中包含很多kvm不需要的内容,針對我們這種虛拟化的新人,還是越簡單越好。
當然如果你有足夠的信心,你也可以直接去看qemu的代碼。
好了,進入正題讓我們先用kvmtool 來運作一個 Linux 的虛拟機。
- 編譯 kvmtool - 直接make就能搞定,會生成一個binary,lkvm
- 編譯 kernel - make x86_64_defconfig, make kvmconfig,make -j4。會生成 bzImage
- 運作虛拟機,
./lkvm run --kernel your kernel img path bzImage
運作結果
是不是很簡單,我們的虛拟機已經跑起來了。Ctrl+D 就可以退出。
KVM 虛拟化架構
虛拟機我們已經run起來了,再進行下一步的分析之前,我們來先了解一下KVM的基本架構,這樣可以幫助我們了解。
其基本的原理是KVM Module 提供 KVM的interface 給 kvmtool, kvmtool 通過ioctl去調用這些API來進行建立,設定,監控虛拟機的操作。當設定好了以後通知KVM Module,通過VM Entries 事件來運作虛拟機,或者resume 虛拟機。 當虛拟遇到一些它無法獨立完成的事件,比如IO 操作 / memory的操作 會觸發VM exits 事件,傳回到vmx root 模式進行處理,如果在kvm module 就可以完成,就直接傳回,這也被成為 lightweight exit。如果還需要kvmtool 來進行處理,則再傳回到kvmtool中執行完畢以後,再傳回kernel 去resume vm。這個也被稱為heavy exit。
通過上圖你一點有個疑問,什麼是VM Entries 和 VM Exits ?
Intel 虛拟化的擴充提供了2個額外的模式,一個是VMX root,另外一個是VMX non-root。其分别對應于 host端 和 guest 端。 當我們從VMX root 切換到 non-root的行為稱為 VM Entries,當從non-root 傳回 root,則稱為VM exits。
okay,你說通過VM Entries 和 VM Exits 能進行 non-root 和 root 的切換,那他們切換之前的環境儲存在哪呢?
Intel 也考慮到這個問題,是以提供了一個叫VMCS的結構用來儲存之前的環境。
當Guest os 執行一些敏感操作且自己無法處理的時候,就會導緻VM exits,那麼就會把目前的環境到VMCS中。同理當 kvmtool 或者 kernel kvm module 處理完這些Guest os的這些敏感操作以後就會從VMCS中讀取之前的儲存狀态,再調用VM Entries 傳回到Guest OS 繼續運作。