次世代ハイパーバイザ/仮想環境基盤 BHyVe

FreeBSD 10からはBSDハイパーバイザと呼ばれる機能が取り込まれている。この機能は「BHyVe」と呼ばれており、機能としてはXenやKVMに近いものになっている。XenやKVMはプロセッサが仮想化支援機能を実装する前から存在してきたためソースコードが複雑になっているが、BHyVeはプロセッサの仮想化支援機能を使うことを前提にすることで、そのあたりのソースコードがすっきりしているという特徴がある。

\10.0-RELEASEではFreeBSD 10.0-RELEASE以降のFreeBSDをBHyVeで実行することができる。現在LinuxやWindowsなどほかのオペレーティングシステムを動作させるための開発が進められており、将来的にはFreeBSD以外のオペレーティングシステムも利用できるようになる見通し。この機能ももともとストレージベンダが実装を進めていた機能だ。

たとえば次のように利用する。まず、BHyVeを実行するために必要になるカーネルモジュールの読込と、トンネルインタフェースの作成を行う。

% kldload vmm
% kldload if_tap
% ifconfig tap0 create
% 
BHyVeを使うためにカーネルモジュールの読み込みとトンネルインタフェースの作成

BHyVeを直接コマンドから起動するのはオプションが多くて煩雑なので、ラッパースクリプトを利用する。次のようにNeel Natu氏が提供しているスクリプトをダウンロードしてくるとともに、FreeBSDのインストーライメージ(ISO)をダウンロードしてきて特定の名前に変換しておく。なお、2014年1月以降ならダウンロードしてくるISOファイルはRC3ではなくリリースバージョンの方がよいだろう。

% pwd
/s/b/10.0
% ls
% 
% fetch http://people.freebsd.org/~neel/bhyve/vmrun.sh
% chmod 600 ./vmrun.sh
% fetch ftp://ftp.freebsd.org/pub/FreeBSD/ISO-IMAGES-amd64/10.0/FreeBSD-10.0-RC3-amd64-disc1.iso
% mv FreeBSD-10.0-RC3-amd64-disc1.iso release.iso
% 
% ls
release.iso     vmrun.sh
%
仮想環境構築スクリプトとインストールイメージの用意

ここまで準備したら、あとはラッパースクリプトに仮想マシンの名前を指定して実行すればよい。

% ./vmrun.sh vm1
仮想環境の構築開始

次のようにBHyVe上でFreeBSDインストーラが起動してくる。

BHyVe仮想環境で起動されるFreeBSDインストーラ

実行中に先ほど作成したタップインタフェースを調べると、特定のプロセス(ここではプロセス番号1162のプロセス)によってオープンされているというメッセージが確認できる。

% ifconfig tap0
tap0: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=80000<LINKSTATE>
        ether 00:bd:52:e6:01:00
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
        media: Ethernet autoselect
        status: active
        Opened by PID 1162
% 
BHyVeによって使用されているタップインタフェース

表示されるプロセス番号を調べると、hhybe(8)というコマンドが実行されていることを確認できる。これがユーザから見えるBHyVeの本体だ。

% ps -ww -p 1162
 PID TT  STAT    TIME COMMAND
1162  0  D+   2:28.06 /usr/sbin/bhyve -c 2 -m 512 -AI -H -P -g 0 -s 0:0,hostbridge -s 1:0,virtio-net,tap0 -s 2:0,virtio-blk,./diskdev -s 3:0,virtio-blk,./release.iso -S 31,uart,stdio vm1
% 
動作中のBHyVe

インストーラ起動中

途中で端末の種類を聞かれるのでvt100を選択しておく。

ターミナルタイプとしてvt100を選択

インストール作業は通常のインストール作業と同様に進めればよい。

Installを選択

ホスト名を入力

ディスクやネットワークインタフェースはVirtIOベースのものが表示されるので、これを使用する。

Entire Diskを選択

Finishを選択

インストール中

ネットワーク設定

インストールが完了したあとはLiveCDモードに移行して、インストールした先の/etc/ttysに次の設定を追加する。

console "/usr/libexec/getty std.9600"   vt100   on secure
/etc/ttysに追加する設定

インストール後再起動

もしここで編集せずに終了してしまった場合でも、同じディレクトリに作成される「diskdev」というファイルが仮想ディスクファイルになっているので、このファイルを直接mdconfig(8)でマウントして編集することで同じことができる。たとえば次のように作業すればよい。

% mdcondig -a -t vnode -f diskdev
md0
% mount /dev/md0 /mnt
% vi /mnt/etc/ttys
% sync
% umount /mnt
% mdconfig -d -u 0
% 
インストール後にディスクイメージから直接内容を書き換える方法

再起動またはもう一度ラッパースクリプトを使ってBHyVeを実行するとディスクイメージからFreeBSDが起動してくる。

再起動画面

BHyVeゲストとして動作中のFreeBSD

ホストから見るとBHyVeで動作しているゲストは次のようにただのプロセスに見える。確保しているメモリ領域がゲストが使用するメモリのサイズとほぼ同じになっていることも確認できる。

ホストからはプロセス番号12911のプロセスとして見える

% ps -uww -p 12911
USER   PID %CPU %MEM    VSZ   RSS TT  STAT STARTED    TIME COMMAND
root 12911  0.0  0.2 551768 25480  0  D+   11:23AM 0:16.96 /usr/sbin/bhyve -c 2 -m 512 -AI -H -P -g 0 -s 0:0,hostbridge -s 1:0,virtio-net,tap0 -s 2:0,virtio-blk,./diskdev -S 31,uart,stdio vm1
% 
ホストからは単一のプロセスのように見えるBHyVeゲスト

ゲストとして動作するFreeBSDはvirtio_pci、vtnet、vtblkのようにVirtIOを経由してデバイスにアクセスしていることがわかる。

root@bhyve:~ # dmesg
Copyright (c) 1992-2013 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
        The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
FreeBSD 10.0-RC2 #0 r259404: Sun Dec 15 08:18:20 UTC 2013
    root@snap.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64
FreeBSD clang version 3.3 (tags/RELEASE_33/final 183502) 20130610
CPU: Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz (3391.96-MHz K8-class CPU)
  Origin = "GenuineIntel"  Id = 0x306a9  Family = 0x6  Model = 0x3a  Stepping = 9
  Features=0x8f83ab7f<FPU,VME,DE,PSE,TSC,MSR,PAE,CX8,APIC,SEP,PGE,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2,SS,PBE>
  Features2=0xe2ba6257<SSE3,PCLMULQDQ,DTES64,DS_CPL,SMX,SSSE3,CX16,xTPR,PCID,SSE4.1,SSE4.2,x2APIC,POPCNT,AESNI,F16C,RDRAND,HV>
  AMD Features=0x20100800<SYSCALL,NX,LM>
  AMD Features2=0x1<LAHF>
  TSC: P-state invariant
real memory  = 536870912 (512 MB)
avail memory = 492273664 (469 MB)
Event timer "LAPIC" quality 400
ACPI APIC Table: <BHYVE  BVMADT  >
FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs
FreeBSD/SMP: 2 package(s) x 1 core(s)
 cpu0 (BSP): APIC ID:  0
 cpu1 (AP): APIC ID:  1
ioapic0: Changing APIC ID to 2
ioapic0 <Version 1.1> irqs 0-16 on motherboard
kbd0 at kbdmux0
random: <Software, Yarrow> initialized
module_register_init: MOD_LOAD (vesa, 0xffffffff80cfa560, 0) error 19
acpi0: <BHYVE BVXSDT> on motherboard
atrtc0: <AT realtime clock> port 0x70-0x71,0x72-0x77 irq 8 on acpi0
Event timer "RTC" frequency 32768 Hz quality 0
Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
acpi_timer0: <32-bit timer at 3.579545MHz> port 0x408-0x40b on acpi0
pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0
pci0: <ACPI PCI bus> on pcib0
pcib0: no PRT entry for 0.31.INTA
virtio_pci0: <VirtIO PCI Network adapter> port 0x2000-0x201f mem 0xc0000000-0xc0001fff at device 1.0 on pci0
vtnet0: <VirtIO Networking Adapter> on virtio_pci0
virtio_pci0: host features: 0x1018020 <NotifyOnEmpty,Status,MrgRxBuf,MacAddress>
virtio_pci0: negotiated features: 0x18020 <Status,MrgRxBuf,MacAddress>
vtnet0: Ethernet address: 00:a0:98:e2:d9:c8
virtio_pci1: <VirtIO PCI Block adapter> port 0x2040-0x207f mem 0xc0002000-0xc0003fff at device 2.0 on pci0
vtblk0: <VirtIO Block Adapter> on virtio_pci1
virtio_pci1: host features: 0x10000044 <RingIndirect,BlockSize,MaxNumSegs>
virtio_pci1: negotiated features: 0x10000044 <RingIndirect,BlockSize,MaxNumSegs>
vtblk0: 8192MB (16777216 512 byte sectors)
uart2: <Siig CyberSerial (1-port) 16550> port 0x3f8-0x3ff irq 4 at device 31.0 on pci0
uart2: console (9600,n,8,1)
Timecounters tick every 10.000 msec
random: unblocking device.
Netvsc initializing... SMP: AP CPU #1 Launched!
Trying to mount root from ufs:/dev/vtbd0p2 [rw]...
root@bhyve:~ #
ゲストではVirtIO経由でデバイスを認識していることがわかる

FreeBSD 10にはVirtIO関連のデバイスドライバがデフォルトで採用されている点もポイントとなっている。このためBHyVeに限らずVirtIOがあれば動作する数々の仮想環境で実行できるようになっている。

BHyVeのひとつの活用シーンとして、ホストのFreeBSDカーネルには変更を加えずにFreeBSD Updateおよびpkg(8)による自動アップデートを実施し、カーネルの書き換えやオプションを指定してのアプリケーションが必要になるケースではBHyVe上にカスタマイズしたカーネルやソフトウェアを用意して利用するといった使い方が考えられる。ベースシステムの安定性とカスタマイズの利便性の双方を実現する方法として興味深い。