xhyve使用

xhyve_logo

FreeBSD 下的虚拟技术 bhyve (The BSD Hypervisor) 是去年1月份正式发布的,包含在了 FreeBSD 10.0 发行版中。今天要玩的这个 xhyve 是基于 bhyve 的 Mac OS X 移植版本,也就是说我们想在 Mac 上运行 Linux 的话除了 VirtualBox, VMware Fusion 外,现在有了第三种选择。

xhyve is a lightweight virtualization solution for OS X that is capable of running Linux. It is a port of FreeBSD’s bhyve, a KVM+QEMU alternative written by Peter Grehan and Neel Natu.

特点:

  • super lightweight, only 230 KB in size
  • completely standalone, no dependencies
  • the only BSD-licensed virtualizer on OS X
  • does not require a kernel extension (bhyve’s kernel code was ported to user mode code calling into Hypervisor.framework)
  • multi-CPU support
  • networking support
  • can run off-the-shelf Linux distributions (and could be extended to run other operating systems)

xhyve may make a good solution for running Docker on your Mac, for instance.

install

search xhyver:

1
2
3
4
5
6
7
8
9
$ brew info xhyve
xhyve: stable 0.2.0 (bottled), HEAD
xhyve, lightweight macOS virtualization solution based on FreeBSD's bhyve
https://github.com/mist64/xhyve
/usr/local/Cellar/xhyve/HEAD-1f1dbe3 (11 files, 11.2MB) *
Built from source on 2017-08-24 at 12:12:21
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/xhyve.rb
==> Requirements
Required: macOS >= 10.10 ✔

install:

1
$ brew install xhyve

Ubuntu 16.04 VM

下载ubuntu-16.04.1-server-amd64.iso,装载该iso,然后将其中的vmlinuzinitrd.gz复制出来,以供xhyve使用。

在mac系统下直接装载ubuntu的iso会出错

1
2
$ hdiutil attach ./ubuntu-16.04.1-server-amd64.iso
hdiutil: attach failed - 无可装载的文件系统

所以需要制作一个新的iso,新的iso文件前预留2KB的空间

1
2
3
4
5
6
$ dd if=/dev/zero bs=2k count=1 of=./tmp.iso
$ dd if=./ubuntu-16.04.1-server-amd64.iso bs=2k skip=1 >> ./tmp.iso
$ hdiutil attach ./tmp.iso

$ cp /Volumes/Ubuntu-Server\ 16/install/vmlinuz .
$ cp /Volumes/Ubuntu-Server\ 16/install/initrd.gz .

创建一个磁盘映像文件hdd.img,当作虚拟机的虚拟硬盘

1
$ dd if=/dev/zero of=hdd.img bs=1g count=8

编写VM创建脚本mk_xhyve.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

KERNEL="vmlinuz"
INITRD="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-16.04.1-server-amd64.iso"
IMG_HDD="-s 4,virtio-blk,./hdd.img"
PCI_DEV="-s 0:0,hostbridge -s 31,lpc"
LPC_DEV="-l com1,stdio"

xhyve $MEM $SMP $PCI_DEV $LPC_DEV $NET $IMG_CD $IMG_HDD -f kexec,$KERNEL,$INITRD,"$CMDLINE"

运行VM创建脚本sudo sh ./mk_xhyve.sh创建ubuntu虚拟机

xhyve_vm_run

按正常系统安装方法安装。。。
待成功安装完成后选择<Go Back> => Execute a shell,进入iso的shell界面,然后需要将已经安装好的hdd.img也就是系统中的/dev/vda中的boot目录copy出来,因为要用里面的vmlinuz-4.4.0-31-genericinitrd.img-4.4.0-31-generic

进入shell后先查看一下ip地址

1
2
3
4
5
6
7
8
9
BusyBox v1.22.1 (Ubuntu 1:1.22.0-15ubuntu1) built-in shell (ash)
Enter 'help' for a list of built-in commands.

~ # ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
link/ether 82:62:9e:40:cf:32 brd ff:ff:ff:ff:ff:ff
~ #

发现没有获取到ip地址,此时shell用的是busybox,是没有dhclient的,不过busybox提供udhcpc -i <interface>
获取到ip地址后,vm可以通过tar c ./boot | nc -l -p 1234将boot目录发送给宿主机,宿主机用nc <vm ip> 1234 | tar x接受boot目录。

获得到boot目录后取出其中的vmlinuz-4.4.0-31-genericinitrd.img-4.4.0-31-generic,然后修改VM创建脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

KERNEL="vmlinuz-4.4.0-31-generic"
INITRD="initrd.img-4.4.0-31-generic"
CMDLINE="earlyprintk=serial console=ttyS0 acpi=off root=/dev/vda1"

MEM="-m 1G"
#SMP="-c 2"
NET="-s 2:0,virtio-net"
IMG_CD="-s 3,ahci-cd,./ubuntu-16.04.1-server-amd64.iso"
IMG_HDD="-s 4,virtio-blk,./hdd.img"
PCI_DEV="-s 0:0,hostbridge -s 31,lpc"
LPC_DEV="-l com1,stdio"

xhyve $MEM $SMP $PCI_DEV $LPC_DEV $NET $IMG_CD $IMG_HDD -f kexec,$KERNEL,$INITRD,"$CMDLINE"

并执行sudo sh ./mk_xhyve.sh

xhyve_vm_run2

ubuntu 16.04 正常启动了,over!

参考&鸣谢