X86 操作系統是設計在直接執行在裸硬體裝置上的,因此它們自己認爲它們完全佔有計算機硬體。x86 架構提供四個特權級別給操作系統和應用程式來存取硬體。 Ring 是指CPU 的執行級別,Ring 0是最高級別,Ring1次之,Ring2更次之…… 就 Linux+x86 來說, 操作系統(內核)需要直接存取硬體和記憶體,因此它的程式碼需要執行在最高執行級別Ring0上,這樣它可以使用特權指令,控制中斷、修改頁表、存取裝置等等。
應用程式的程式碼執行在最低執行級別上Ring3上,不能做受控操作。如果要做,比如要存取磁碟,寫檔案,那就要通過執行系統呼叫(函數),執行系統呼叫的時候,CPU的執行級別會發生從ring3到ring0的切換,並跳轉到系統呼叫對應的內核程式碼位置執行,這樣內核就爲你完成了裝置存取,完成之後再從ring0返回ring3。這個過程也稱作使用者態和內核態的切換。
那麼,虛擬化在這裏就遇到了一個難題,因爲宿主操作系統是工作在 ring0 的,客戶操作系統就不能也在 ring0了,但是它不知道這一點,以前執行什麼指令,現在還是執行什麼指令,但是沒有執行許可權是會出錯的。所以這時候虛擬機器管理程式(VMM)需要避免這件事情發生。 虛擬機器如何通過VMM實現 Guest CPU 對硬體的存取,根據其原理不同有三種實現技術:
1、全虛擬化
2、半虛擬化
3、硬體輔助的虛擬化
客戶操作系統執行在 Ring 1,它在執行特權指令時,會觸發異常(CPU的機制 機製,沒許可權的指令會觸發異常),然後 VMM 捕獲這個異常,在異常裏面做翻譯,模擬,最後返回到客戶操作系統內,客戶操作系統認爲自己的特權指令工作正常,繼續執行。但是這個效能損耗,就非常的大,簡單的一條指令,執行完了事,現在卻要通過複雜的例外處理過程。
異常 「捕獲(trap)——翻譯(handle)——模擬(emulate)」 過程:
半虛擬化的思想就是,修改操作系統內核,替換掉不能虛擬化的指令,通過超級呼叫(hypercall)直接和底層的虛擬化層hypervisor來通訊,hypervisor 同時也提供了超級呼叫介面來滿足其他關鍵內核操作,比如記憶體管理、中斷和時間保持。
這種做法省去了全虛擬化中的捕獲和模擬,大大提高了效率。所以像XEN這種半虛擬化技術,客戶機操作系統都是有一個專門的定製內核版本,和x86、mips、arm這些內核版本等價。這樣以來,就不會有捕獲異常、翻譯、模擬的過程了,效能損耗非常低。這就是XEN這種半虛擬化架構的優勢。這也是爲什麼XEN只支援虛擬化Linux,無法虛擬化windows原因,因爲微軟不改程式碼。
2005年後,CPU廠商Intel 和 AMD 開始支援虛擬化了。Intel 引入了 Intel-VT(Virtualization Technology)技術。 這種 CPU有 VMX root operation 和 VMX nonroot operation兩種模式,兩種模式都支援Ring 0 ~ Ring 3 共 4個執行級別。這樣,VMM 可以執行在 VMX root operation模式下,客戶OS執行在VMX non-root operation模式下。
而且兩種操作模式可以互相轉換。執行在 VMX root operation 模式下的 VMM 通過顯式呼叫 VMLAUNCH 或 VMRESUME 指令切換到VMX non-root operation模式,硬體自動載入 Guest OS 的上下文,於是Guest OS獲得執行,這種轉換稱爲VM entry。Guest OS 執行過程中遇到需要 VMM 處理的事件,例如外部中斷或缺頁異常,或者主動呼叫 VMCALL 指令呼叫 VMM 的服務的時候(與系統呼叫類似),硬體自動掛起 Guest OS,切換到 VMX root operation 模式,恢復 VMM 的執行,這種轉換稱爲VM exit。VMX root operation 模式下軟體的行爲與在沒有 VT-x 技術的處理器上的行爲基本一致;而
VMX non-root operation 模式則有很大不同,最主要的區別是此時執行某些指令或遇到某些事件時,發生VM exit。也就說,硬體這層就做了些區分,這樣全虛擬化下,那些靠「捕獲異常-翻譯-模擬」的實現就不需要了。而且CPU廠商,支援虛擬化的力度越來越大,靠硬體輔助的全虛擬化技術的效能逐漸逼近半虛擬化,再加上全虛擬化不需要修改客戶操作系統這一優勢,全虛擬化技術應該是未來的發展趨勢。
KVM 全稱是基於內核的虛擬機器(Kernel-based Virtual Machine),它是一個 Linux的一個內核模組,該內核模組使得 Linux變成了一個Hypervisor:它由 Quramnet開發,該公司於 2008年被 Red Hat 收購。它支援 x86 (32 and 64 位), s390, Powerpc 等CPU。它從 Linux 2.6.20 起就作爲一模組被包含在 Linux 內核中。它需要支援虛擬化擴充套件的CPU。它是完全開源的。官方網站:http://www.linux-kvm.org/page/Main_Page
KVM 是基於虛擬化擴充套件(Intel VT 或者 AMD-V)的 X86 硬體的開源的 Linux 原生的全虛擬化解決方案。KVM 中,虛擬機器被實現爲常規的 Linux 進程,由標準 Linux 排程程式進行排程;虛機的每個虛擬 CPU 被實現爲一個常規的 Linux 進程。這使得 KVM 能夠使用Linux 內核的已有功能。但是,KVM 本身不執行任何硬體模擬,需要客戶空間程式通過 /dev/kvm 介面設定一個客戶機虛擬伺服器的地址空間,向它提供模擬的 I/O,並將它的視訊顯示對映回宿主的顯示屏。目前這個應用程式是 QEMU。
Linux 上的使用者空間、內核空間和虛機:
Guest: 客戶機系統,包括CPU(vCPU)、記憶體、驅動(Console、網絡卡、I/O 裝置驅動等),被KVM 置於一種受限制的 CPU 模式下執行。
KVM: 執行在內核空間,提供CPU 和記憶體的虛級化,以及客戶機的 I/O 攔截。Guest 的 I/O 被 KVM 攔截後,交給 QEMU 處理。
QEMU: 修改過的爲KVM虛機使用的QEMU程式碼,執行在使用者空間,提供硬體I/O虛擬化,通過IOCTL /dev/kvm 裝置和 KVM 互動。
現代CPU本身實現了對特殊指令的截獲和重定向的硬體支援,甚至新的硬體會提供額外的資源來幫助軟體實現對關鍵硬體資源的虛擬化從而提高效能。以 X86 平臺爲例,支援虛擬化技術的 CPU 帶有特別優化過的指令集來控制虛擬化過程。通過這些指令集,VMM 很容易將客戶機置於一種受限制的模式下執行,一旦客戶機檢視存取物理資源,硬體會暫停客戶機的執行,將控制權交回給 VMM 處理。VMM 還可以利用硬體的虛級化增強機制 機製,將客戶機在受限模式下對一些特定資源的存取,完全由硬體重定向到 VMM 指定的虛擬資源,整個過程不需要暫停客戶機的執行和 VMM 的參與。由於虛擬化硬體提供全新的架構,支援操作系統直接在上面執行,無需進行二進制轉換,減少了相關的效能開銷,極大簡化了VMM的設計,使得VMM效能更加強大。從 2005 年開始,Intel 在其處理器產品線中推廣 Intel Virtualization Technology 即 IntelVT 技術。
其實QEMU原本不是KVM的一部分,它自己就是一個純軟體實現的虛擬化系統,所以其效能低下。但是,QEMU程式碼中包含整套的虛擬機器實現,包括處理器虛擬化,記憶體虛擬化,以及 KVM需要使用到的虛擬裝置模擬(網絡卡、顯示卡、儲存控制器和硬碟等)。爲了簡化程式碼,KVM 在 QEMU 的基礎上做了修改。VM 執行期間,QEMU 會通過 KVM 模組提供的系統呼叫進入內核,由 KVM 負責將虛擬機器置於處理的特殊模式執行。遇到虛機進行 I/O 操作,KVM 會從上次的系統呼叫出口處返回 QEMU,由QEMU來負責解析和模擬這些裝置。從QEMU的角度看,也可以說是QEMU使用了KVM模組的虛擬化功能,爲自己的虛機提供了硬體虛擬化加速。除此以外,虛機的設定和建立、虛機執行所依賴的虛擬裝置、虛機執行時的使用者環境和互動,以及一些虛機的特定技術比如動態遷移,都是QEMU自己實現的。
KVM內核模組在執行時按需載入進入內核空間執行。KVM本身不執行任何裝置模擬,需要QEMU通過 /dev/kvm 介面設定一個GUEST OS的地址空間,向它提供模擬的 I/O裝置,並將它的視訊顯示對映回宿主機的顯示屏。它是KVM虛機的核心部分,其主要功能是初始化CPU硬體,開啓虛擬化模式,然後將虛擬客戶機執行在虛擬機器模式下,並對虛機的執行提供一定的支援。以在Intel上執行爲例,KVM模組被載入的時候,它做的事情如下:
- 首先初始化內部的數據結構;
- 做好準備後,KVM 模組檢測當前的 CPU,然後開啓CPU控制及存取CR4的虛擬化模式開關,並通過執行VMXON指令將宿主操作系統置於虛擬化模式的根模式;
- 最後,KVM模組建立特殊裝置檔案/dev/kvm並等待來自使用者空間的指令。
接下來的虛機的建立和執行將是QEMU和KVM相互配合的過程。兩者的通訊介面主要是一系列針對特殊裝置檔案/dev/kvm的IOCTL呼叫。其中最重要的是建立虛機。它可以理解成KVM 爲了某個特定的虛機建立對應的內核數據結構,同時,KVM 返回一個檔案控制代碼來代表所建立的虛機。
針對該控制代碼的呼叫可以對虛機做相應地管理,比如建立使用者空間虛擬地址和客戶機實體地址、真實實體地址之間的對映關係,再比如建立多個vCPU。KVM爲每一個vCPU生成對應的檔案控制代碼,對其相應地IOCTL 呼叫,就可以對vCPU進行管理。其中最重要的就是「執行虛擬處理器」。通過它,虛機在KVM的支援下,被置於虛擬化模式的非根模式下,開始執行二進制指令。在非根模式下,所有敏感的二進制指令都被CPU捕捉到,CPU在儲存現場之後自動切換到根模式,由KVM決定如何處理。
除了CPU的虛擬化,記憶體虛擬化也由KVM實現。實際上,記憶體虛擬化往往是一個虛機實現中最複雜的部分。CPU 中的記憶體管理單元MMU是通過頁表的形式將程式執行的虛擬地址轉換成實際實體地址。在虛擬機器模式下,MMU的頁表則必須在一次查詢的時候完成兩次地址轉換。因爲除了將客戶機程式的虛擬地址轉換了客戶機的實體地址外,還要將客戶機實體地址轉化成真實實體地址。
可見:
- qemu-kvm 通過對/dev/kvm的一系列 ICOTL 命令控制虛機。
- 一個 KVM 虛機即一個Linux qemu-kvm進程,與其他Linux進程一樣被Linux 進程排程器排程。
- KVM虛機包括虛擬記憶體、虛擬CPU和虛機 I/O裝置,其中,記憶體和 CPU 的虛擬化由 KVM 內核模組負責實現,I/O 裝置的虛擬化由QEMU負責實現。
- KVM客戶機系統的記憶體是qumu-kvm 進程的地址空間的一部分。
- KVM虛機的vCPU 作爲執行緒執行在 qemu-kvm進程的上下文中。
vCPU、QEMU 進程、LInux 進程排程和物理CPU之間的邏輯關係:
因爲CPU中虛擬化功能的支援,並不存在虛擬的CPU,KVM Guest程式碼是執行在物理CPU之上。
KVM實現客戶機記憶體的方式是,利用mmap系統呼叫,在QEMU主執行緒的虛擬地址空間中申明一段連續的大小的空間用於客戶機實體記憶體對映。在有兩個虛機的情況下,情形是這樣的:
可見,KVM爲了在一臺機器上執行多個虛擬機器,需要增加一個新的記憶體虛擬化層,也就是說,必須虛擬MMU來支援客戶操作系統,來實現 VA -> PA -> MA 的翻譯。客戶操作系統繼續控制虛擬地址到客戶記憶體實體地址的對映 (VA -> PA),但是客戶操作系統不能直接存取實際機器記憶體,因此VMM 需要負責對映客戶實體記憶體到實際機器記憶體 (PA -> MA)。
VMM 記憶體虛擬化的實現方式:
軟體方式: 通過軟體實現記憶體地址的翻譯,比如 Shadow page table (影子頁表)技術
硬體實現: 基於CPU的輔助虛擬化功能,比如AMD的NPT和Intel的EPT技術KVM 中,虛擬機器的實體記憶體即爲qemu-kvm進程所佔用的記憶體空間。KVM使用CPU輔助的記憶體虛擬化方式。在Intel和AMD平臺,其記憶體虛擬化的實現方式分別爲:
AMD 平臺上的 NPT (Nested Page Tables) 技術
Intel 平臺上的 EPT (Extended Page Tables)技術
從GUI到Linux內核,包括以下五個元件:
- virt-manager
一個用來管理VM的GUI/CUI使用者介面;它使用libvirt呼叫VM的各種功能。- libvirt
一個工具及介面,作爲較通用的伺服器虛擬化軟體,它支援Xen,VMware ESX/GSX,當然,還有QEMU/KVM。- QEMU
一個和KVM內核模組互動的模擬器,處理多種客戶機系統請求如I/O;一個QEMU進程對應一個客戶機系統。- KVM內核模組
從狹義上來說,KVM是一個Linux內核模組,處理客戶機系統的VM Exits和執行VM Entry指令。- Linux內核
既然QEMU作爲一個普通的使用者進程執行,相應客戶機系統的排程就由Linux內核自己來處理。
所有的元件都是開放原始碼軟體(OSS)。
KVM 所支援的功能包括:
Ø 支援CPU 和 memory 超分(Overcommit)
Ø 支援半虛擬化I/O (virtio)
Ø 支援熱插拔(cpu,塊裝置、網路裝置等)
Ø 支援對稱多處理(Symmetric Multi-Processing,縮寫爲 SMP )
Ø 支援實時遷移(Live Migration)
Ø 支援 PCI 裝置直接分配和單根I/O虛擬化(SR-IOV)
Ø 支援內核同頁合併(KSM )
Ø 支援NUMA (Non-Uniform Memory Access,非一致儲存存取結構 )
libvirt: 操作和管理KVM虛機的虛擬化API,使用C語言編寫,可以由Python,Ruby,Perl,PHP,Java 等語言呼叫。可以操作包括 KVM,vmware,XEN,Hyper-v,LXC 等 Hypervisor。
Virsh: 基於libvirt 的命令列工具(CLI)
Virt-Manager: 基於libvirt的GUI工具
virt-v2v: 虛機格式遷移工具
virt-* 工具: 包括Virt-install (建立KVM虛機的命令列工具),Virt-viewer (連線到虛機螢幕的工具),Virt-clone(虛機克隆工具),virt-top 等
sVirt: 安全工具和selinux相關
什麼是雲端計算?
雲端計算:設定各種資源的方式
雲端計算的分類:基礎即服務Iaas,平臺即服務Paas,軟體即服務Saas
如果按照不同的部署方式:公有雲、私有雲、混合雲
虛擬化的不同的方式:
基於二進制的全虛擬化: | |
---|---|
半虛擬化: | Xen |
全虛擬化: | KVM、VMware |
基於內核的虛擬機器(Kernel-Based virtual mathine)
yum groupinstall "GNOME 桌面" -y #安裝GNOME桌面環境
yum install qemu-kvm -y #KVM核心模組
yum install qemu-kvm-tools -y #KVM偵錯工具,可以選擇性安裝
yum install qemu-img -y #允許你建立、轉換和修改映象,能處理被qemu支援的所有映象格式
yum install libvirt -y #管理虛擬機器的工具包
yum install virt-install -y #virt-install是一個使用libvirt庫構建新虛擬機器的命令列工具
yum install virt-manager -y #圖形介面管理虛擬機器
yum install bridge-utils -y #設定linux乙太網橋
安裝系統後,可以檢查CPU是否支援虛擬化功能。如果值爲0,說明不支援,如果非0,說明支援
[root@localhost ~]# egrep -c "(vmx|svm)" /proc/cpuinfo
2
檢查KVM模組是否安裝
[root@localhost ~]# lsmod | grep kvm
kvm_intel 188688 0
kvm 636969 1 kvm_intel
irqbypass 13503 1 kvm
[root@localhost ~]# systemctl status libvirtd
如果libvirtd服務停止執行,那麼你將不能管理虛擬機器,也就是不能使用virt-manager等工具來管理虛擬機器。
1)操作系統安裝媒介:ISO檔案,並上傳到系統的/iso目錄下
[root@localhost ~]# ls /iso/
CentOS-7-x86_64-DVD-1611.iso
2)磁碟空間準備;(建立虛擬機器時直接給大一點的磁碟空間即可)
2.1)新增新磁碟
2.2)建立LVM
2.3)建立檔案系統及掛載點,並設定開機自動掛載
pvcreate /dev/sdb
vgcreate vmvg /dev/sdb
lvcreate -n kvm-lv -l 20479 vmvg
mkdir /kvm-vm
mount /dev/vmvg/kvm-lv /kvm-vm/
virt-manager是基於libvirt的圖形化虛擬機器管理軟體。在命令列中以root身份輸入virt-manager命令,出現virt-manager管理介面
或:
建立儲存池
雙擊「QEMU/KVM」,然後選擇「儲存」索引標签,然後單擊「+」按鈕新建儲存池,命名爲「kvm-vm」,單擊「前進」,然後輸入上面建立的lvm掛載目錄,單擊完成。
以同樣的方法建立一個映象儲存池,命名爲 iso,目錄爲 /iso 即可,用於放置以後KVM虛擬機器使用的iso光碟映象檔案。
建立儲存卷,其實就是KVM虛擬機器的硬碟檔案,選擇剛建的「vm」儲存卷,點選新建卷,設定名字和大小。
在虛擬系統管理器中選擇「新建虛擬機器」,選擇「本地安裝媒介」,「前進」
選擇「瀏覽」,選擇映象檔案
選擇記憶體和CPU設定
網路使用預設的NAT網路即可
單擊完成後,虛擬機器就開始建立,然後按照操作系統即可
[root@localhost ~]# virt-install --os-type=linux --os-variant centos7.0 --name test01 --ram 1024 --vcpus 1 --disk=/kvm-vm/test01.raw,format=raw,size=10 --location /iso/CentOS-7-x86_64-DVD-1611.iso --network network=default --graphics vnc,listen=0.0.0.0 --noautoconsole
然後到桌面系統,開啓virt-manager,完成後續的安裝操作系統的工作即可。
如果不希望手動安裝操作系統,也可以指定應答檔案來自動完成安裝過程,增加–extraargs參數 --extra-args=’ks=http://192.168.1.100/mini.txt’ (mini.txt爲應答檔案)如果希望通過PXE安裝虛擬機器,可以使用以下命令參數:–pxe 指定使用PXE協定從網路引導
通用選項:
-n NAME, --name=NAME 虛擬機器名稱
-r MEMORY, --ram=MEMORY 以MB爲單位爲用戶端事件分配的記憶體
–vcpus=VCPUS 設定虛擬機器的虛擬CPU(vcpu)數量,如:
–vcpus 5
–vcpus 5, maxcpus=10
–vcpus socket=2,cores=4,threads=2
–cpuset=CPUSET Set which physical CPUs domain can use.
–cpu=CPU CPU型號及功能,如:–cpu coreduo,+x2apic
–description=DESCRIPTION 在生成的XML中儲存的可讀VM描述。
–security=SECURITY 設定域安全驅動器設定。
–numatune=NUMATUNE 爲域進程調整NUMA策略。
安裝方法選項:
-c CDROM, --cdrom=CDROM 光碟機安裝媒介
-l LOCATION, --location=LOCATION
安裝源(例如:nfs:host:/path、http://host/path、ftp://host/path)
–pxe 使用 PXE 協定從網路引導
–import 在磁碟映像中構建客戶機
–livecd 將光碟機媒介視爲 Live CD
-x EXTRA, --extra-args=EXTRA 附加到使用–location引導的內核的參數
–os-type=DISTRO_TYPE 要安裝的操作系統型別,例如:‘linux’、‘unix’、‘windows’
–os-variant=DISTRO_VARIANT The OS variant being installed guests, e.g. ‘fedora6’,‘rhel5’, ‘solaris10’, ‘win2k’ 可以通過osinfo-query os命令查詢
–boot=BOOTOPTS 自選設定後安裝引導順序、選單、永久kernel引導,等等。
儲存設定:
–disk=DISKOPTS 用各種選項指定儲存。 Ex.
–disk path=/my/existing/disk
–disk path=/my/new/disk,size=5 (in gigabytes)
–disk vol=poolname:volname,device=cdrom,bus=scsi,…
–nodisks 不要爲該用戶端設定任何磁碟。
–filesystem=FILESYSTEMS
將主機目錄傳遞給虛擬機器。例如:
–filesystem /my/source/dir,/dir/in/guest
–filesystem template_name,/,type=template
聯網設定:
-w NETWORK, --network=NETWORK
設定客戶網路介面。 Ex:
–network bridge=mybr0
–network network=my_libvirt_virtual_net
–network network=mynet,model=virtio,mac=00:11…
–nonetworks 不要爲該客體建立網路介面。
圖形設定:
–graphics=GRAPHICS設定虛擬機器顯示設定。例如:
–graphics vnc
–graphics spice,port=5901,tlsport=5902
–graphics none
–graphics vnc,password=foobar,port=5910,keymap=ja
–noautoconsole 不要自動嘗試連線到用戶端控制檯
裝置選項:
–serial=SERIALS 設定虛擬機器串列埠裝置
–parallel=PARALLELS 設定虛擬機器並口裝置
–channel=CHANNELS 設定虛擬機器溝通頻道
–console=CONSOLES 設定虛擬機器與主機之間的文字控制檯連線
–host-device=HOSTDEVS 設定與客戶相連的物理主機裝置
–soundhw=SOUNDHW 設定客戶聲音裝置模擬
–watchdog=WATCHDOG 設定虛擬機器 watchdog 裝置
–video=VIDEO 設定虛擬機器視訊硬體。
–smartcard=SMARTCARD 設定虛擬機器智慧卡裝置。例如:
–smartcard mode=passthrough
–redirdev=REDIRDEV
Configure a guest redirection device. Ex:
–redirdev usb,type=tcp,server=192.168.1.1:4000
–panic=PANIC Configure a guest panic device. Ex:
–panic default
虛擬化平臺選項:
-v, --hvm 用戶端應該是一個全虛擬用戶端
-p, --paravirt 這個用戶端是一個半虛擬用戶端
–container This guest should be a container guest
–virt-type=HV_TYPE 要使用的管理程式名稱(kvm、qemu、xen 等等)
–arch=ARCH 模擬的 CPU 構架
–machine=MACHINE The machine type to emulate
–noapic 爲全虛擬用戶端禁用 APIC(在 os-type/osvariant db 中覆蓋數值)
–noacpi 爲全虛擬用戶端禁用 ACPI(在 os-type/osvariant db 中覆蓋數值)
-u UUID, --uuid=UUID 用戶端 UUID。
其它選項:
–autostart 引導主機時自動啓動域。
–print-xml 輸出所生成域的XML,而不是定義虛擬機器。
–print-step=XMLSTEP 輸出具體安裝步驟(1,2,3,all)的 XML。
–noreboot 完成安裝後不要引導虛擬機器。
–wait=WAIT 要等待的時間(以分鐘爲單位)
–dry-run 完成安裝步驟,但不要建立裝置或者定義虛擬機器。
–force 對任意應用程式提示強制回答‘yes’,終止其它提示
-q, --quiet 禁止無錯誤輸出
–prompt 要求使用者爲模糊情況或者需要的選項輸入
-d, --debug 輸入故障排除資訊