KVM他說的基於內核的虛擬機是什麼意思呢?
vmware workstation和virtual box就不是基於內核的虛擬機嗎?
它這樣做有哪些好處呢?對於物理機和虛擬機而言分別有那些好事呢?
這個問題下面好幾個答案是完全錯的,也有些是對的,但寫得很簡單,看相關的討論,估計讀者都沒有讀懂。這裡的關鍵問題是概念比較亂,我來幫忙整理一下。
下面的概念定義很多來自我自己的定義,但和現有的概念基本上不會衝突,也應該更容易幫助讀者理解虛擬化技術,所以我猜應該沒有什麼問題。
虛擬化技術,一般理解上,是在一個操作系統之上,模擬另一個操作系統的執行環境。我們看到的各種遊戲機模擬器,還有為開發CPU做模擬而做的模擬程序,就是早期比較常見的虛擬化解決方案,它的工作原理很簡單:把CPU的所有寄存器都寫在一組變數中(這組變數我們稱為CPUFile),然後用一片內存當作被模擬CPU的內存(這片內存這裡稱為vMEM),然後在用一些數據結構表示IO設備的狀態(這裡稱為vIO),三者的數據結構綜合在一起,就是代表一個虛擬化的環境了(這裡稱之為VM),之後按順序讀出一條條的指令,根據這個指令的語義,更改VM的數據結構的狀態(如果模擬了硬體,還要模擬硬體的行為,比如發現顯存被寫了一個值,可以在虛擬屏幕上顯示一個點等),這樣,實施虛擬的那個程序就相當於給被虛擬的程序模擬了一台計算機,這種技術,我稱它為「解釋型虛擬化技術」。指令是被一條一條解釋執行的。
在這個方案中,我們有三個對象:
Host:執行虛擬程序的系統
Emulator:實施虛擬的,運行在Host上的那個程序
Guest:被虛擬出來的系統,也就是運行了軟體(例如操作系統)的VM
這些概念在技術演進的過程中會一定程度變化,讀者要注意這一點,記住它的原始含義,否則很容易亂掉。
解釋型虛擬化技術很簡單,直接,概念也容易理解,但很明顯,這個效率是很低的。優化得比較成功的是qemu,它使用一種所謂「編譯型」的技術,把每條被虛擬的設備的指令都寫成一段C代碼,用這段C代碼去修改CPUFile等VM數據,然後再用編譯器去編譯這些C代碼,借用了編譯器的優化能力,最後在解釋Guest的指令的時候,用一個「翻譯區「,把這些C代碼的編譯結果拼起來,然後直接執行。這種方法有效提高了」解釋」的效率(所以qemu才稱為Quick-emulator),但效率很明顯還是非常低的。Android的SDK模擬基於ARM的手機,用的就是這種技術。
隨著技術的發展,有人就開始取巧了:很多時候,我們僅僅是在x86上模擬x86,這些指令何必要一條條解釋執行?我們可以用CPU直接執行這些指令啊,執行到特權指令的時候,我們直接異常,然後在異常中把當前CPU的狀態保存到CPUFile中,然後再解釋執行這個特權指令,這樣不是省去了很多」解釋「的時間了?用這種技術實現的虛擬機,就稱為」調度型虛擬化技術「,這種情況下,Emulator的主要工作就不是解釋了,它的主要工作是調度,調度Host和所有的Guest來分時(或者分核)使用CPU。
qemu也可以工作在這種模式。要工作在這種模式,它需要在內核中插入一個kqemu.ko,以便處理那些特殊的,由它的模擬程序產生的異常。
這種情況下,我們會發現,Emulator已經不是原來那個意思了,雖然我們仍需要使用這個程序,但僅僅靠這個程序,它作為Host上的一個程序,沒有辦法調度Host的資源。所以我們引入另一個實體,所謂Hypervisor,Hypervisor負責調度,Emulator只是給它提請求而已。
(這裡,Emulator的語義也發生變更了,讀者有必要注意這一點)
Hypervisor需要掌控整個系統的資源,這樣它就需要有所有設備的驅動,這樣會讓Hypervisor變得非常複雜的。所以Host的概念仍然存在,一種簡化的理解可以是,BIOS啟動Hypervisor,Hypervisor首先啟動第一個OS,那個就是Host,之後Host上的Emulator啟動Guest,Emulator向Hypervisor請求資源,Hypervisor模擬一個環境給新的Guest,但如果Guest向Hypervisor請求IO或者其他特殊能力,這些請求就會被Hypervisor調度到Host上,讓Host執行。
在Xen上,這個Host稱為DOM0,說明Xen是認為Host和Guest在調度上沒有本質區別的,都是一個調度的對象,但DOM0帶有所有的驅動,管理程序也可以放在這裡直接和Hypervisor通訊。
好了,現在你可以明白為什麼KVM稱為」內核(K)的VM"技術了,Xen的Hypervisor是一個獨立的部件,由BIOS(其實是grub了)直接載入,然後和DOMx的各個操作系統通訊。而KVM的Hypervisor直接就是內核的一部分,這個Hypervisor的代碼直接就在Linux的內核中,當Host啟動的時候,它們一起載入,一同初始化,只是Hypervisor的代碼工作在虛擬機調度器的狀態,而其他代碼工作在普通內核狀態而已。
這個用ARM64平台特別好理解,ARM64平台(不考慮安全態)3個特權級,EL0用戶態,EL1內核態,EL2 Hypervisor態。這樣,內核啟動先進入EL2,初始化Hypervisor部分的狀態,然後切換入EL1,初始化內核的狀態,然後才fork init,進入EL0。這之後,你啟動qemu-kvm,這個程序就可以通過系統調用(對/dev/kvm文件做ioctl)進入內核,調用KVM的請求,執行調度,從內核中直接做Hypervisor請求,進入Hypervisor要求調度Guest。
這樣,很明顯,KVM確實是」Linux內核提供的虛擬化技術「,這就是它和其他虛擬化技術不同的地方了。
vmware和virtualbox的技術和Xen類似,無論它們如何載入,是否獨立,或者作為一個內核模塊載入,畢竟它們不是內核原始設計的一部分。
至於是全虛擬化(Guest不知道你自己是被模擬的系統),還是Para虛擬化(Guest知道自己是模擬的系統,用直接和Hypervisor通訊的方法實現IO),這個問題和是否KVM沒有關係(kvm兩種模式都可以支持),和性能也沒有關係。這僅僅是構架的不同。
討論區有讀者問,為什麼沒有看到VirtualBox從BIOS載入Hypervisor呢?這個涉及到兩個要素:
第一,kqemu.ko也可以不從BIOS載入,這種模式我仍把kqemu稱為Hypervisor,但這個Hypervisor並非工作在Hypervisor狀態,它是和內核互相妥協從而工作在Hypervisor的角色上的,它的工作級別並不比Host高,但仍可以為Guest模擬出一個運行環境來。VirtualBox使用一樣的技術。
第二,VirtualxBox還可以支持VT-x這樣的硬體加速的虛擬工作狀態。這個事情和VT-x的設計有關,VT-x的特權級繼承自傳統的x86特權級,就是0-3,0是最高優先順序,3是最低優先順序。像Linux就只用了0和3級表示內核和用戶態。剛開始支持虛擬化的時候,Intel考慮0是Hypervisor級(VMM級),1是內核,3是用戶。但這種設計造成不兼容和複雜度。所以到了64位後,新的模式是:系統剛啟動的時候,是Host態0級,在這個級別你可以用VMXON進入VMM級,然後你可以在這個級別創建虛擬機,再用VMXON進入虛擬機,VMXOFF退出虛擬機。虛擬機中仍可以有0-3級。這樣一來,在Host中,你只要能進入0級,就可以把自己提升到VMM級。VirtualBox只要能在內核中插入一個模塊,就可以為自己獲得VMM的許可權。但這個方法在ARM64上是行不通的。
(讀者應該已經注意到了,這裡面的定義在整個發展過程中不斷發生語義的變化,這造成很多人對技術誤解,所以,我們理解計算的概念,更多看我們如何用和如何建模,如果你認為某個概念是持久不變的,基本上你很快就被計算機技術拋棄了。因為基於概念保持部分使用模式不變,然後進行技術演進,是計算機發展的常態)高票說的對啊,
hypervisor分type 1和type 2兩種,type 1是原生hypervisor,在任何內核啟動之前就開了vmx指令的,從開機自己就是ring 0,最著名的的type 1應該是vmware esx吧。
type 2是在host啟動之後啟動的,屬於後入式,需要使用運行特權指令開vmx,需要host配合。
那麼問題來了,kvm到底是不是type 1 hypervisor啊?
顯然,kvm是在linux內核之後運行的,是type 2。
不過呢如果我們把linux整體當做一個hypervisor的話,這個hypervisor就可以認為是type 1了,所以這樣才叫kvm的吧。
…………………………………………………………………
所以hv server是type 1還是type 2呢……
實際使用上,沒多大差別。全虛擬化效率低,但是不需要修改guest系統;半虛擬化效率高,但是要定製guest系統。
kvm原來也一直專註於全虛擬化,但是為了提高i/o效率,也引進了virtio模塊。
所以,不用糾結,基於內核的虛擬化,還是其他的虛擬化。全虛擬化和辦虛擬化只要管理好了,都能起到提高生產效率的作用。如果安裝運行起來,就不管了,就。。。
主要是在於vmm這一層,例如kvm的vCPU調度直接是kernel來解決,性能不論實現起來是相對就比較容易。而其它方案如xen不得不自己去實現vcpu調度工作,如此種種某種程度就是實現了操作系統的部分功能,代碼也會變得比較龐大。
意思就是: 我是virtualization,不是emulation!
所謂virtualization vs emulation,是針對『如何虛擬化 CPU和memory而言』的。
emulation:VM中一條CPU指令,被翻譯成host上一段代碼執行。
運行效率可想而知。
代表有 不開啟kvm的qemu ,不開啟VT-x的VMWare。
當然好處也有,那就跨硬體模擬 -- 我在x86上,可以模擬出ARM的機器。
virtualization:
VM中一條CPU指令,不經過翻譯,直接在host上CPU上執行,也就是『全速執行』。
要求host CPU支持VT-x (有興趣的同學還可以了解一下,EPT, VT-d)。
真正實用的IaaS,必然是virtualization。
而kvm,就是一個模塊,讓上層hypervisor(一般來說就是qemu)比較方便地使用VT-x功能。
除了『如何虛擬化 CPU和memory』,VM還要面對另一大類問題『如何虛擬化硬碟,網卡等外設』。
這就是full-virtualization 和 para-virtualization之爭了。
經常有人把兩類問題搞混,kvm與否,其實和para與否沒有必然關係:)
虛擬化分為3大類
1. 全虛擬化 CPU指令 設備IO 全部由軟體模擬. 可以跨arch, 比如跑arm在x86,跑mips在arm etc.
1.1 Function Model. 這種只是保證模擬的功能效果(輸入輸出)一樣,但是對於時鐘的模擬不能保證. 比如真實的一條指令是3個cycles, 軟體並不能保證其實現的時間也是3個cycles(虛擬). 例如simics, skyeye, qemu(非kvm) vmware(非vt-x)這類工具.
1.2 Cycle級精確. 這種一般是完全模擬硬體行為,即模擬功能也模擬時延, 各家有各家的工具一般不對外.
2. para 虛擬化, 硬體對於虛擬化沒有特別的支持, 需要修改OS代碼, 一旦涉及到特權操作, 需要hypervisor接管(通過hypercall) 例如早期的xen/玩具lguest. 這種host/guest arch必須一致. 性能很差,比如shadow pagetable 足以讓人卻步.
3. 硬體輔助虛擬化, 硬體對於虛擬化有特定的優化(vt-x, vt-d) cpu指令直接跑在cpu上, 涉及到特權操作的時候, 可以通過配置vmcs來達到是否退出non root模式的目的. 設備模擬也有sriov vt-d配合 總體性能優化. vmware/xen/kvm/hyperv 目前都支持.從簡單架構而言,沒有哪個效率可用的虛擬機沒有在內核里插代碼(.ko)。
但具體到各部分,就存在如何實現的問題。KVM之所以自稱「基於內核的」就是因為它的很多實現是使用了內核現成的功能。做個類比,就好比其它虛擬機是申請1G內存塊,然後自己管理變數內存分配;而KVM直接使用內核提供的內存管理功能。更多的比如虛擬網卡的實現、CPU調度的實現等。
首先,任何 VM 都要運行在 Hypervisor 上,而 Hypervisor 怎麼實現?在哪一層上實現?大家是八仙過海,各顯神通,也就產生了各種「概念」。
Vmware Workstation 和 VirtualBox 屬於桌面級 Hypervisor ,這類 Hypervisor 是一種運行在操作系統之上的軟體,Vmware 有自己獨特的二進位翻譯技術,VirtualBox 即支持軟體虛擬化,靈活性高,但是畢竟是軟體級的 Hypervisor ,架構上講:硬體 ---&> Host OS ---&> Hypervisor ---&> VM,效率有限。
KVM 、XEN、Hyper-V 這類 Hypervisor 是為商用而生的,他們本身就是一種 OS,直接運行在硬體之上,例如KVM,架構是:硬體 ---&> {Linux Kernel + KVM} ---&> VM,即載入了 KVM module 的 Linux Kernel 本身就是一種完備的 Hypervisor,運行在內核態。這樣做的好處在於可以使用 Kernel 本身的 CPU 調度 和 內存管理,不用像XEN一樣自己實現,所以說,KVM 是基於 Linux Kernel 的。
其實啊,現在虛擬化這麼牛逼,不是上面說的那些東西牛逼,而是 Intel CPU 對虛擬化的支持越來越牛逼了。因為脫襪子童鞋特別偏執。他可以接受別人的code在他上面(KVM),接受不了別人的code在他下面(Xen)。
商用上Xen挺成熟的,性能這事兒,不好說,沒有明顯的差距搞點兒沒意義大數據都可以吹。
不要回復,不要私信,我是肌肉男,不懂高科技。
沒有VT-x之前,x86上的虛擬化只能走二進位翻譯的方式,比如vmware,掃描目標碼,找到特權指令,實時替換成對自己的系統調用。Xen是預先把部分特權指令替換成了自己的系統調用,需要改內核,重新編譯。
有了VT-X之後,就可以直接跑目標代碼,遇到特權指令直接內陷進入虛擬機管理程序。KVM就是這樣的虛擬機管理程序,只是它的事先是在現成的linux內核里幹活,做成一個核心模塊,各個虛擬機就成為linux下的一個普通進程,由linux核心裡現成的進程管理、內存管理、I/O驅動等等來提供服務。
Xen是自己搞了一個內核做這些事。kvm是linux內核里的一個模塊,它實現了cpu的虛擬化(這個是在處理器輔助下添加了一層level0實現的),內存的虛擬化(不過內存管理的一套還是直接使用的linux系統本身的內存管理),然後文件系統,驅動啥的也都是使用的linux的那一套。不過I/O使用的qemu代為處理的。這是我的理解。
kvm失去了linux就沒有虛擬出一個虛擬機的能力了。
我覺得描述有問題,就如:小米說miui是基於安卓開發的,難道yunos,鎚子就不是么。
推薦閱讀:
TAG:操作系統 | Linux | 虛擬機 | VMware威睿 | VirtualBox |