KVM 虛擬化原理探究— overview
標簽(空格分隔): KVM
寫在前面的話
本文不介紹kvm和qemu的基本安裝操作,希望讀者具有一定的KVM實踐經驗。同時希望借此系列博客,能夠對KVM底層有一些清晰直觀的認識,當然我沒有通讀KVM的源碼,文中的內容一部分來自於書籍和資料,一部分來自於實踐,還有一些來自於自己的理解,肯定會有一些理解的偏差,歡迎討論並指正。本系列文章敬代表我個人觀點和實踐,不代表公司層面。
KVM虛擬化簡介
KVM 全稱 kernel-based virtual machine,由Qumranet公司發起,2008年被RedHat收購。
KVM實現主要基於Intel-V或者AMD-V提供的虛擬化平台,利用普通的Linux進程運行於虛擬態的指令集,模擬虛擬機監視器和CPU。KVM不提供硬件虛擬化操作,其IO操作等都借助QEMU來完成。
KVM有如下特點:
- guest作為一個普通進程運行於宿主機
- guest的CPU(vCPU)作為進程的線程存在,並受到宿主機內核的調度
- guest繼承了宿主機內核的一些屬性,比如huge pages(大頁表)
- guest的磁盤IO和網絡IO會受到宿主機的設置的影響
- guest通過宿主機上的虛擬網橋與外部相連
KVM整體架構
每一個虛擬機(guest)在Host上都被模擬為一個QEMU進程,即emulation進程。
我們創建一個虛擬機后,用普通的ps 命令就可以查看到。
➜ ~ virsh list --all
Id Name State
----------------------------------------------------
1 kvm-01 running
➜ ~ ps aux | grep qemu
libvirt+ 20308 15.1 7.5 5023928 595884 ? Sl 17:29 0:10 /usr/bin/qemu-system-x86_64 -name kvm-01 -S -machine pc-i440fx-wily,accel=kvm,usb=off -m 2048 -realtime mlock=off -smp 2 qemu ....
可以看到,此虛擬機就是一個普通的Linux進程,他有自己的pid。並且有四個線程,線程數量不是固定的,但是至少會有三個(vCPU,IO,Signal)。其中有兩個是vCPU線程,有一個IO線程還有一個信號處理線程。
➜ ~ pstree -p 20308
qemu-system-x86(20308)-+-{qemu-system-x86}(20353)
|-{qemu-system-x86}(20408)
|-{qemu-system-x86}(20409)
|-{qemu-system-x86}(20412)
虛擬CPU
guest的所有用戶級別(user)的指令集,都會直接由宿主機線程執行,此線程會調用KVM的ioctl方式提供的接口加載guest的指令並在特殊的CPU模式下運行,不需要經過CPU指令集的軟件模擬轉換,大大的減少了虛擬化成本,這也是KVM優於其他虛擬化方式的點之一。
KVM向外提供了一個虛擬設備/dev/kvm,通過ioctl(IO設備帶外管理接口)來對KVM進行操作,包括虛擬機的初始化,分配內存,指令加載等等。
虛擬IO設備
guest作為一個進程存在,當然他的內核的所有驅動等都存在,只是硬件被QEMU所模擬(后面介紹virtio的時候特殊)。guest的所有硬件操作都會有QEMU來接管,QEMU負責與真實的宿主機硬件打交道。
虛擬內存
guest的內存在host上由emulator提供,對emulator來說,guest訪問的內存就是他的虛擬地址空間,guest上需要經過一次虛擬地址到物理地址的轉換,轉換到guest的物理地址其實也就是emulator的虛擬地址,emulator再次經過一次轉換,轉換為host的物理地址。后面會有介紹各種虛擬化的優化手段,這里只是做一個overview。