為什么要折騰 KVM 虛擬機
最近因為公司的事情,沒有太多時間進行寫作,就用一篇技術(shù)類的文章來湊數(shù)吧。
事情是這樣的,我們公司有一個小東西是基于嵌入式的系統(tǒng)開發(fā)的,不屬于 Android 也不屬于 iOS 平臺。嗯,這意味著什么呢?這意味著開發(fā)這個小東西的語言是 C 語言,而不是 Java, Objective-C 抑或是 Swift。所以我們需要一個 Cross Compiler,也就是俗稱的交叉編譯環(huán)境來編譯這個代碼。
其實 Xcode 編譯出來的 iOS App 也屬于交叉編譯的范疇。
然而,這個交叉編譯環(huán)境竟然只有 Windows 平臺的!其實,好像除了 GCC 之外,好用的交叉編譯環(huán)境都是 Windows 下面的。估計很多玩嵌入式的同學應該都知道,現(xiàn)在業(yè)內(nèi)用得比較多的也就是 Keil 和 IAR 系列了。而及其不幸的是,兩者都是 Windows 特供的,沒有 macOS 或 Linux 版本。
為什么 Windows 會讓我這么得不爽呢?因為平常為了更好的提高工作效率,除了不得不使用的行業(yè)應用軟件必須要跑在 Windows 下的時候,我們只用 Mac 不用 Windows。所以,我們基本上沒有閑置和富裕的 Windows 主機,不!是壓根就沒有,沒有什么「基本沒有」一說。
而在服務器端,更不要跟我說什么 Windows Server 云云的。作為一個 macOS 和 Ubuntu 的腦殘用戶,我是不可能在 Bare metal 上跑一個 Windows Server 的。服務器我們只跑 Linux,別的沒興趣。
那么問題來了,我們有一套自動化編譯系統(tǒng),也就是大家所熟知的 CI 體系 (Continuous integration),用的是 Atlassian 的全家桶:Bitbucket、Bamboo、JIRA 還有 Confluence 什么的,全部跑在 Linux 平臺的 Docker 虛擬化容器中。
現(xiàn)在我們想把這個小東西也自動化編譯器來,以便更好地把人力釋放出來,也方便未來跟蹤和管理每一次 Release 的內(nèi)容。而第一個要解決的問題就是:我們沒有 Windows 的服務器。
既然現(xiàn)在虛擬化這么流行,那么我們就利用現(xiàn)有的 Ubuntu 服務器虛擬化一個 Windows 好啦,走起!
啥是 KVM
KVM 的全稱是:Kernel-based Virtual Machine,簡單一句話概括,就是一個基于 Linux 內(nèi)核的虛擬化管理系統(tǒng)。
從 Linux 內(nèi)核 2.6.20 版本開始就已經(jīng)集成了該功能。簡單理解 Docker 是在應用層的虛擬化,而 KVM 是在系統(tǒng)層的虛擬化。
區(qū)別就是,Docker 虛擬化的內(nèi)容,必須跟 Host 主機共享內(nèi)核,也就意味著只能跑 Linux 類系統(tǒng)。
而 KVM 是整個主機虛擬,所以可以安裝不同的操作系統(tǒng),而不局限于 Linux 本身。等我過段時間抽風的時候,看看能不能在 Ubuntu 上虛擬化個 macOS 出來。這樣就不用單獨再弄個 Mac 主機來自動化編譯 iOS App 了。
安裝 KVM
我這里使用的是 Ubuntu 16.04 LTS 版本,考慮長期使用和穩(wěn)定性,基本上只選 LTS 版本,其他版本差別也不太大,參考著做就好了。
首先是安裝 KVM 相關的包文件,因為我的服務器都是命令行,沒有安裝 X 桌面,所以我加了 --no-install-recommends 參數(shù)。不然的話它會安裝 virt-viewer 之類的包,而它們的依賴關系中又有 X11 和很多圖形圖像庫,而這些都用不上。但是如果你開啟了桌面系統(tǒng),那么也可以不加該參數(shù)。
$ sudo apt-get install --no-install-recommends qemu-kvm qemu-utils libvirt-bin virtinst cpu-checker
讓我們來驗證一下是不是一切 OK
$ kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used
很好,一切順利,我們再來弄個橋接網(wǎng)絡。其實這個也不是必須的,看你的使用場景。
KVM 會自己創(chuàng)建一個 virbr0 的橋接網(wǎng)絡,但是這個是一個 NAT 的網(wǎng)絡,沒有辦法跟局域網(wǎng)內(nèi)的其他主機進行通信,所以還是別偷懶,自己建一個橋接網(wǎng)絡吧。
參考配置如下:
$ cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
source /etc/network/interfaces.d/*
# The loopback network interface
auto lo
iface lo inet loopback
# The bridged network interface
auto br0
iface br0 inet static
address 1.2.3.4
netmask 255.255.255.0
gateway 1.2.3.1
dns-nameservers 1.2.3.1
bridge_ports enp9s0
bridge_stop off
bridge_fd 0
bridge_maxwait 0
重啟網(wǎng)絡,并驗證一下橋接狀態(tài):
$ sudo systemctl restart networking
$ sudo brctl show
bridge name bridge id STP enabled interfaces
br0 8000.f079593874d9 no enp9s0
virbr0 8000.525400087ef2 yes virbr0-nic
OK,一切正常,可以開始創(chuàng)建虛擬主機了。
創(chuàng)建虛擬主機
KVM 只是完成了第一步,我們還需要創(chuàng)建虛擬主機才可以繼續(xù)往下走。
在開始之前,我們要準備好幾個東西:
1.Windows 安裝鏡像
2.Virtio ISO 和軟盤鏡像
3.VNC 客戶端(macOS 自帶)
我這里使用的是 Virtio 0.1.126-2 版本。操作系統(tǒng)版本是:Ubuntu 16.04.1 LTS。
一切準備就緒,使用 virt-install 命令來幫助創(chuàng)建虛擬機:
virt-install \
--name win10 \
--memory 2048 \
--vcpus sockets=1,cores=1,threads=2 \
--cdrom=/path/to/windows_10.iso \
--os-variant=win8.1 \
--disk /path/to/win10/win10.qcow2,bus=virtio,size=40 \
--disk /path/to/virtio/virtio-win-0.1.126_amd64.vfd,device=floppy \
--network bridge=br0,model=virtio \
--graphics vnc,password=Passw0rd,port=5910 \
--hvm \
--virt-type kvm
基本上配置信息都在上面了,虛擬信息機配置如下:
2G 內(nèi)存
1 個 CPU,1 個核,2 個線程
1 個 CDROM(Windows 安裝光盤)
40G 硬盤(系統(tǒng)盤)
1 個軟驅(qū)(Virtio 驅(qū)動)
在 5910 端口開放一個 VNC 遠程桌面
如果你的命令輸入的正確,應該會得到類似的反饋信息:
Starting install...
Creating domain...
Domain installation still in progress. Waiting for installation to complete.
簡單來說,就是虛擬機已經(jīng)創(chuàng)建好了,但是因為沒有圖像界面,所以沒有辦法下一步了。當我們連接了 VNC 以后,就可以繼續(xù)往下走了。這個提示只會出現(xiàn)一次,安裝好系統(tǒng)以后,不會出現(xiàn)這個啟動等待的情況。
安裝 Windows 10
雖然我們在創(chuàng)建虛擬機的時候,指明了使用 5910 端口來提供 VNC 遠程桌面。但是這個端口是不能直接訪問的,因為它默認綁定在 127.0.0.1 上,也就是只有本地才能訪問。我們需要先把遠程的本地端口,映射成本地的端口。
ssh -L 5910:127.0.0.1:5910 server
然后在 macOS 下,⌘ + Space 呼叫出 Spotlight,然后輸入:
vnc://127.0.0.1:5910
在彈出的窗口中輸入密碼:Passw0rd
然后就可以愉快的安裝 Windows 系統(tǒng)了,如果不能識別硬盤,需要手動加載一下驅(qū)動,選擇 A 盤和對應的 Windows 目錄就可以了。同樣的,如果網(wǎng)卡沒有驅(qū)動,也是如法炮制。
附安裝完成的屏幕截圖一張: