OS X上基于 FreeBSD/bhyve 的虛擬技術:xhyve
FreeBSD 下的虛擬技術 bhyve (The BSD Hypervisor) 是去年1月份正式發布的,包含在了 FreeBSD 10.0 發行版中。今天要玩的這個 xhyve 是基于 bhyve 的 Mac OS X 移植版本,也就是說我們想在 Mac 上運行 Linux 的話除了 VirtualBox, VMware Fusion 外,現在有了第三種選擇。
xhyve 超級小,只有 230 KB,不依賴其他軟件或庫。下面的步驟基本按照 xhyve 作者的文檔 xhyve – Lightweight Virtualization on OS X Based on bhyve 實現,不過跟著別人的文檔并不總會一帆風順,雖然文檔已經很詳細,總有碰到自己的問題的時候,有人報告說在自己的 Macbook (OS X 10.10.3) 上運行不成功。我在測試的過程中遇到的一個問題是硬盤分區問題,稍后會提到。我的編譯和測試環境是 OS X Yosemite 10.10.4 + Xcode 6.3.2.
xhyve 發布的是源代碼,需要編譯后運行,所以 Mac 上沒有安裝 Xcode 的話需要先到 App Store 安裝。
使用 git 下載源碼后編譯,運行 xhyverun.sh 后會啟動一個簡單的 Tiny Core Linux 虛擬機:
$ git clone https://github.com/mist64/xhyve.git $ cd xhyve $ make $ ./xhyverun.sh
上面的 Tiny Core Linux 只是測試和確定 xhyve 能運行,下面我們將在 xhyve 上安裝和運行完整的 Ubuntu 14.04 Server 虛擬機。
在上面的 xhyve 目錄里新建一個 ubuntu 目錄用來存放所有和 ubuntu 虛擬機相關的東東。下載 ubuntu-14.04.2-server-amd64.iso,并把 iso 里面的兩個系統啟動需要的文件 vmlinuz 和 initrd.gz 拷貝出來:
$ mkdir ubuntu $ cd ubuntu $ wget http://releases.ubuntu.com/14.04/ubuntu-14.04.2-server-amd64.iso $ dd if=/dev/zero bs=2k count=1 of=/tmp/ubuntu.iso $ dd if=ubuntu-14.04.2-server-amd64.iso bs=2k skip=1 >> /tmp/ubuntu.iso $ hdiutil attach /tmp/ubuntu.iso $ cp /Volumes/Ubuntu-Server\ 14/install/vmlinuz . $ cp /Volumes/Ubuntu-Server\ 14/install/initrd.gz .
創建一個 10GB 大小的硬盤文件當作 ubuntu 虛擬機的硬盤:
$ dd if=/dev/zero of=hdd.img bs=1g count=10
轉到上層目錄(xhyve)后新建一個腳本文件 ubuntu_install.sh,然后修改腳本文件為可執行:
$ cd .. $ vi ubuntu_install.sh #!/bin/sh KERNEL="ubuntu/vmlinuz" INITRD="ubuntu/initrd.gz" CMDLINE="earlyprintk=serial console=ttyS0 acpi=off" MEM="-m 1G" #SMP="-c 2" NET="-s 2:0,virtio-net" IMG_CD="-s 3,ahci-cd,ubuntu/ubuntu-14.04.2-server-amd64.iso" IMG_HDD="-s 4,virtio-blk,ubuntu/ubuntu.img" PCI_DEV="-s 0:0,hostbridge -s 31,lpc" LPC_DEV="-l com1,stdio" build/xhyve $MEM $SMP $PCI_DEV $LPC_DEV $NET $IMG_CD $IMG_HDD -f kexec,$KERNEL,$INITRD,"$CMDLINE" $ chmod +x ubuntu_install.sh
啟動這個文件需要 sudo 權限哦:
$ ./ubuntu_install.sh virtio_net: Could not create vmnet interface, permission denied or no entitlement? $ sudo ./ubuntu_install.sh
這時候會看到 ubuntu 的標準文本格式的安裝程序,安裝過程中唯一要注意的是硬盤分區的時候不要選擇自動分區,也不要選擇 LVM 分區,選擇手動分區,使用最簡單的一個 root 區一個 swap 區。我碰到的一個問題就是選擇自動分區后到后來安裝完畢啟動系統的時候掛在那里不動。
還有一個要注意的地方,安裝完畢后,這時候選擇 Go Back,因為我們要到 Execute a shell 命令行界面把里面的內核文件拷貝出來留作以后啟動用:
┌─────────┤ [!!] Finish the installation ├──────────┐ │ │ ┌│ Installation complete │ ││ Installation is complete, so it is time to boot into your new system. │ ││ Make sure to remove the installation media (CD-ROM, floppies), so │ ││ that you boot into the new system rather than restarting the │ ││ installation. │ ││ │ └│ <Go Back> <Continue> │ │ │ └────────────────────────────────────┘
選擇 Execute a shell 后轉到目標目錄,知道虛擬機的 IP 地址后用 nc 把虛擬機和外面的世界(Mac)連起來傳輸文件:
BusyBox v1.21.1 (Ubuntu 1:1.21.0-1ubuntu1) built-in shell (ash) Enter 'help' for a list of built-in commands. ~ # cd /target/ /target # sbin/ifconfig eth0 Link encap:Ethernet HWaddr da:ae:82:16:cf:32 inet addr:192.168.64.3 Bcast:192.168.64.255 Mask:255.255.255.0 inet6 addr: fe80::d8ae:82ff:fe16:cf32/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:24426 errors:0 dropped:0 overruns:0 frame:104 TX packets:13283 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:32881668 (32.8 MB) TX bytes:924462 (924.4 KB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) /target # tar c boot | nc -l -p 9000
在 Mac 上接受文件:
$ cd xhyve/ubuntu $ nc 192.168.64.3 9000 | tar x
有了 vmlinuz-3.16.0-30-generic 和 initrd.img-3.16.0-30-generic 內核文件,我們就可以啟動 ubuntu 虛擬機了,注意這時候 root=/dev/vda1 哦:
$ cd .. $ vi ubuntu_boot.sh #!/bin/sh KERNEL="ubuntu/boot/vmlinuz-3.16.0-30-generic" INITRD="ubuntu/boot/initrd.img-3.16.0-30-generic" CMDLINE="earlyprintk=serial console=ttyS0 acpi=off root=/dev/vda1 ro" MEM="-m 1G" #SMP="-c 2" NET="-s 2:0,virtio-net" #IMG_CD="-s 3,ahci-cd,ubuntu/ubuntu-14.04.2-server-amd64.iso" IMG_HDD="-s 4,virtio-blk,ubuntu/ubuntu.img" PCI_DEV="-s 0:0,hostbridge -s 31,lpc" LPC_DEV="-l com1,stdio" build/xhyve $MEM $SMP $PCI_DEV $LPC_DEV $NET $IMG_CD $IMG_HDD -f kexec,$KERNEL,$INITRD,"$CMDLINE" $ chmod +x ubuntu_boot.sh $ sudo ./ubuntu_boot.sh
運行成功: