kvmtool 是一支很迷你的程式,用來開啟 kvm 虛擬機器用的程式。他是由 Pekka Enberg 在 2011 年初開始開發的。用過 kvm 開啟虛擬機器的人,應該會知道一般是由 QEMU 來做初始化虛擬機器的動作。 kvmtool 出來的目的並不是要跟 QEMU 競爭,他只是提供了一個額外的選擇,就像 chrome 相對於 firefox 一樣。
甚至你也可以將 kvmtool 視為一個極度輕量化的 QEMU。他少了 QEMU 的歷史包袱,所以他完全不含指令集模擬的部份,因此你無法在 x86 上跑 ARM、在 ARM 上跑 x86 虛擬機器,當然這也不是 kvm 原本的目的就是。此外,I/O 裝置的模擬部份他也沒有,取而代之的是 virtio 半虛擬化的裝置,包含了終端機(virtio-console)、硬碟儲存裝置(virtio-blk)、網路(virtio-net)、分享式檔案系統(virtio-9p)、virtio-balloon(喔,我不知道這個中文該怎麼翻譯 Orz)等裝置,還有比較少用的 virtio-rng 與 virtio-scsi。沒錯!就只有這些!也因為如此,才能將整個 kvmtool 的體積縮小到只有幾千行的程式碼而已。
然而,因為剛開始發展不久,因此欠缺了很多功能,像是虛擬機器的動態遷移(live migration)、libvirt 的支援等功能目前都還在規劃階段而已。幸運的是,可能也因為他小而美的關係,kvmtool 搶先於 qemu 已經正式支援 kvm-armv8 ,雖然還在實驗性的階段。當然一般 kvm 支援的平台 x86/powerpc/arm 他都是支援的。
那最後就來看看該怎麼把玩這支 kvmtool 吧。
首先,老樣子必須先裝一些必備套件,先裝上編譯 kvmtool 的套件
$ sudo apt-get install build-essential libc6-dev-i386 git-core |
再裝上編譯核心的必備套件
$ sudo apt-get build-dep linux-meta |
kvmtool 現在放在 github 裡面維護,還沒有 release 的版本,所以我們必須從 github 上抓回來:
$ git clone https://github.com/penberg/linux-kvm.git $ cd linux-kvm |
整個原始碼庫有點大,可能要花一點時間。
接著我們先編譯可以做為 kvm guest 的核心,如同之前所說的,這個虛擬機器的 IO 裝置只有 virtio 系列,所以我們必須確認我們的核心已經內建有這些驅動程式。然而,預設的核心是沒有的,所以我們必須重新編譯。幸運的是,這次我們不需要接觸傳統的 menuconfig,在那邊找選項找半天,有時候這個選項找不到,有時候可能又忘了選 Orz。 kvmtool 的核心原始碼已經帶有 kvmconfig 我們只要把它叫出來用就好。第一步必須先建立預設的核心組態,這裡以 x86_64 為例。
$ make x86_64_defconfig |
接著,補上作為 kvm guest 會需要用到的核心選項:
$ make kvmconfig |
最後就編譯它吧:
$ make -j4 |
4 是代表開多少個平行化編譯,你可以根據你的 CPU 核心數量做調整。
接著,我們要編譯 kvmtool,kvmtool 的資料夾就在整包核心原始碼的 tools/kvm 中
$ cd tools/kvm |
直接編譯就好,沒什麼選項可以選。
$ make && make install |
編譯好會產生一個叫做 lkvm 的執行檔(同時也會有一個叫 vm 的執行檔,兩者是相同的),剛剛的 make install 會將你的 kvmtool 複製一分到 ~/bin 中,通常這個路徑也在你的環境變數 PATH 中。我們先執行看看有沒有安裝成功:
$ lkvm help |
如果出現找不到的話,請先確認 lkvm 是不是存在 ~/bin 中,如果檔案存在的話可能是路徑問題,之後改下
$ ~/bin/lkvm [command] |
即可。
最後,我們來開個虛擬機器出來吧:
$ lkvm run |
預設上,這個虛擬機器的核心會採用你目前電腦的核心,所以他會嘗試去讀 /boot/vmlinuz-`uname -r` 的核心檔,然而通常一般使用者是不會有這個權限的。此外如同前面提過的,這個核心檔也缺少了適當的 virtio 驅動程式,所以是無法開機成功的。
我們必須使用剛剛編譯好的核心來開虛擬機器,這個核心放在剛剛 linux-kvm 下的 arch/x86/boot/bzImage:
$ lkvm run -k ../../arch/x86/boot/bzImage |
你可能會想問,為什麼不是 x86_64 呢?這是個好問題,x86_64 的檔案都已經搬走了,剩下的 boot/bzImage 其實也只是指向 x86_64/boot/bzImage 的 soft link 罷了。因此,我們直接用 x86/boot/bzImage 就好。
kvmtool 有實做一些 IPC 指令,所以你可以透過 kvmtool 控制正在執行中的虛擬機器。
像是列出執行中的虛擬機器:
$ lkvm list |
關閉執行中的虛擬機器:
lkvm stop -n guest-XXXX |
虛擬機器的名稱可以由 lkvm list 指令查到,如果建立虛擬機器時沒有指定的話,預設上是 guest-XXXX XXXX 是該 lkvm 的 PID。
你可能會很好奇的是,剛剛開起虛擬機器時,為什麼都不需要指定 rootfs 在哪裡?也不用像以前一樣建立一個虛擬磁碟的映象檔呢?
這是因為 kvmtool 預設上採用 virtio-9p 檔案系統作為虛擬機器的 rootfs。virtio-9p 是基於 virtio 的 9p 檔案系統格式,它的目的是讓虛擬機器共享 host 的檔案系統,所以你在虛擬機器裡面看到的所有執行檔,都是直接共享你 host 機器中的執行檔,並且那些資料夾都是唯讀的狀態,能夠寫入的就只有設定檔的資料夾以及虛擬機器中的家目錄了。
下次介紹一下這個 virito-9p 共享的路徑,以及如何建立簡單的 disk image 。