引言

哈嘍,大家!!!該文章為KVM基礎知識的擴展包,用於深入解釋我的《KVM基礎》中涉及的相關知識點,並希望這篇文章有助於大家更加了解KVM


一、宿主機操作內核是如何調度KVM塊和QEMU(硬件模擬器)進程以及管理物理資源的

內核是一個“總調度室”。它看待一個運行的虛擬機,其實只把它當成一個普通的Linux進程,但這個進程有些特殊,因為它裏面“套娃”了,具體如何呢?接下來由我為大家介紹詳細步驟:

1、調度:把“虛擬機”當成“進程”來管

一句話:內核調度的是QEMU的“vCPU線程”,而不是KVM“模塊

1、vCPU = 內核線程: 當QEMU啓動一個有4核vCPU的虛擬機時,它實際上會在宿主機上創建4個普通的Linux線程(再加上一些輔助線程)

2、公平調度: 宿主機的Linux內核調度器(比如CFS)並不知道這是一個“vCPU”,它只把這4個線程當作系統裏普普通通的線程,和你的瀏覽器線程、代碼編輯器線程一起排隊,等待分配物理CPU時間片

2、執行:KVM模塊的“上崗”與“讓位”

當內核調度器決定“臨幸”某個vCPU線程(讓它上物理CPU)時,這個線程就開始執行。這個線程會立即通過一個叫 ioctl 的系統調用,“鑽”進內核態,去調用KVM模塊

這時,KVM模塊開始工作了:

1、VM-Entry (上崗): KVM模塊啓動CPU的虛擬化擴展(VT-x/AMD-V),把CPU切換到“Non-Root 模式”,然後把控制權交給Guest OS

2、Guest 運行: 此時,Guest OS直接在物理CPU上全速狂奔,宿主機內核完全不插手,效率極高

3、VM-Exit (暫停/讓位): Guest OS總會遇到自己處理不了的事情,比如:
–它想訪問一個模擬的硬件(比如QEMU模擬的網卡)
–它的時間片用完了(宿主機內核發出了時鐘中斷)
–…

4、CPU硬件自動觸發 VM-Exit,暫停Guest OS,CPU切回“Root 模式”,控制權交還給KVM模塊

3、I/O處理:KVM與QEMU的“踢皮球”

KVM模塊拿到控制權後,會分析“VM-Exit”的原因:

情況A(KVM能處理)

比如是時鐘中斷。KVM自己處理一下,然後馬上再次“VM-Entry”,讓Guest OS繼續跑

情況B(KVM處理不了)

比如Guest OS要從模擬的硬盤讀數據。這是QEMU的工作

1、KVM模塊會喚醒那個在用户態“沉睡”的QEMU進程

2、KVM把I/O請求(“我要讀取硬盤第x塊”)告訴QEMU

3、QEMU進程開始幹活:它像一個普通程序一樣,打開數據機上的那個.qcow2(鏡像文件)虛擬磁盤文件,找到第x塊數據,讀出來

4、QEMU把數據準備好,再通過ioctl告訴KVM:“數據我放在內存裏了,你讓Guest OS來取吧”

5、KVM這才再次“VM-Entry”,喚醒Guest OS

4、物理資源管理:內核的“本職工作”

這反而是最簡單的部分,因為虛擬機(QEMU進程)在內核眼裏就是個普通進程:

內存(RAM)

1、QEMU進程啓動時,會像一個普通程序一樣,向宿主機內核申請一個大塊內存(比如8GB)

2、宿主機內核就從物理RAM裏劃分給它8GB

3、KVM模塊再通過CPU的內存虛擬化擴展(EPT/RVI)(本文後面有對CPU的虛擬化擴展的介紹),把這8GB內存“映射”給Guest OS,讓Guest OS以為這是它獨佔的“物理內存”

磁盤(Disk)

1、QEMU進程打開一個.qcow2文件。在內核看來,這和Word打開一個.docx文件沒區別。QEMU對這個文件的讀寫。都會被內核的文件系統(如ext4)正常處理

網絡(NIC)

1、QEMU進程會在宿主機上創建一個tap虛擬網卡。在內核看來,這是一個普通的網絡設備。QEMU發出的網絡包,內核就按路由錶轉發給tap設備的數據包,內核就交給QEMU進程

總結

內核調度QEMU線程,QEMU線程調用KVM,KVM啓動Guest OS

二、CPU的虛擬化擴展

如果説KVM是“包工頭”,QEMU是“全能工具箱”,那麼CPU虛擬化擴展就是那個能讓包工頭“合法”開工的“建築許可證”和“專用高速電梯”

簡單來説,它就是CPU 硬件層面內置的、專門用來加速虛擬機運行的特殊功能(指令集)

為了讓您徹底明白,我們來個“有擴展”和“沒有擴展”的對比:

1、沒有虛擬化擴展的時代(純軟件模擬)

在”遠古時代“,CPU並不知道”虛擬機“是啥玩意

問題所在

操作系統(Guest OS)需要運行在最高權限(Ring 0)才能管理硬件。但虛擬管理器(Hypervisor)本身已經佔用了Ring 0

笨方法(Trap-and-Emulate 陷阱-模擬):

1、Hypervisor 只能“騙”Guest OS,讓它以為自己跑在 Ring 0,其實是跑在一個較低的權限(比如 Ring 1)

2、當 Guest OS 嘗試執行一個“特權指令”(比如訪問硬件),CPU 會因為權限不夠而“報錯”(產生一個Trap,即陷阱)

3、Hypervisor 捕獲這個“陷阱”

4、Hypervisor在軟件層面慢吞吞地"模擬"這個指令的效果,然後在把結果返回給Guest OS

來一個生動的比喻:您(Guest OS)想開燈(特權指令),但您沒有開關權限。您只能大喊一聲:“我要開燈!”。 管家(Hypervisor)聽到後,跑過來,用手搖發電機(軟件模擬)把燈點亮,然後告訴您:“燈開好了。”

這樣開銷巨大,效率極低

2、擁有虛擬化擴展的時代(硬件輔助虛擬化)

CPU廠商看不下去之前使用的笨辦法了,決定從硬件層面提供支持,於是就有了“CPU虛擬化擴展”
Intel的技術:稱為Intel VT-x(Virtualization Technology)
AMD的技術:稱為AMD-V(AMD Virtualization)

聰明的辦法(硬件輔助虛擬化)

1、這些擴展技術在CPU層面創造來兩種新模式:“Root模式”(給Hypervospr用)和”Non-Root“模式(給Guest OS用)

2、Gugest OS現在可以直接在”Non-Root模式“下運行。它在這個模式下就擁有Ring 0權限(一個 ”虛擬的Ring0“)

3、當Guest OS執行絕大多是指令時,它直接在物理CPU上全速運行,就像運行一個普通程序一樣

4、只有當它執行極少數,必須由Hypervisor處理的敏感指令時(比如訪問真實的物理設備I/O),CPU硬件才會自動“暫停”Guest OS(這個過程叫VM-Exit),切換到“Root模式“去通知Hypervisor

來一個生動的比喻:您(Guest OS)現在有了一個專用的房間(Non-Root 模式)。 房間裏所有的電器(CPU指令)您都可以直接使用(硬件直通),只有當您需要叫“客房服務”(訪問模擬的I/O設備)時,您按一下服務鈴(VM-Exit),管家(Hypervisor,比如KVM0才會進來處理您的請求

三、存儲池詳解

一、存儲池定義

存儲池就是Libvirt提供的一種管理虛擬磁盤存放位置的機制。它就像專門為虛擬機硬盤建立的一個 “倉庫”。您告訴Libvirt:“嘿,我把/data/kvm-storage這個目錄劃分出來當倉庫了。Libvirt就會把這個目錄管理起來,您以後創建虛擬機硬盤時,就可以直接從這個“倉庫”裏劃分空間,非常規整

二、存儲池分類

1、目錄類型(dir)

這是最簡單直接的一種(也是本系列教程中使用的一種)。直接使用宿主機上的一個目錄作為存儲池。對新手極其友好

2、LVM類型(logical)

使用LVM(邏輯卷管理器)的卷組作為存儲池,性能和管理上更靈活,適合進階用户

3、NFS/iSCSI類型

使用網絡存儲作為存儲池

三、為什麼要用存儲池

1、集中管理,井井有條

所有的虛擬硬盤都存放在一個或幾個預先定義的池中,查找、備份、遷移都非常方便,告別混亂

2、簡化創建流程

創建虛擬機時,不再需要手動指定一個常常的硬盤文件路徑,直接説在某某存儲池裏創建一個20G的盤就行了,Libvirt會幫您搞定剩下的事

3、資源監控

Libvirt可以輕鬆地告訴您每個存儲池的總容量、已用空間和剩餘空間,方便您進行容量規劃

4、標準化操作

無論是使用virsh命令還是圖形界面,操作都變得統一和標準化,大大降低裏管理成本