LoginSignup
4
2

More than 5 years have passed since last update.

MirageOS のインストールから Hello World までを試す

Last updated at Posted at 2019-01-11

概要

本記事ではMirageOS Unikernel 環境を仮想化支援機構(on x86_64 or aarch64 アーキ)が有効化されたLinuxマシンへインストールし、MirageOS Unikernelの第一歩であるHello Worldアプリ実行までを説明していきます。

Ubuntu18.04LTS(amd64 or aarch64) がインストールされた物理マシンが用意されていることを想定します。(Intel VT-x もしくは AMD-V の Nested が有効化された仮想マシン上のUbuntuでも動作するはずですが、実機で試しておらず...)。

MirageOS Unikernel のアプリケーション(Hello Worldアプリ)を、Linux KVM(Kernel Virtual Machine) を利用して起動させます。

(参考サイト)
MirageOS Documentation and guides - Installation
Building a MirageOS hello world

0. CPU仮想化支援機構のチェック

Intel社 もしくは AMD社製のx86系CPUを利用している場合

lscpuコマンドを用いて仮想化支援機構が有効化されているか確認します。lscpuコマンドがない場合には、インストールします。

lscpuコマンドのインストール
$ apt-get install util-linux

lscpuコマンドを実行すると、CPU仮想化支援機構が有効化されている場合には "Virtualization" という項目の行に "VT-x" もしくは "AMD-V" と表示されているはずです。
(もし表示されていない場合には、こちらなどを参考にBIOS設定を確認する必要があります。)

lscpu実行結果
$ LC_ALL=C lscpu | grep Virtualization
Virtualization:        VT-x    # Intel社製CPU
もしくは
Virtualization:        AMD-V   # AMD社製CPU

さらに、Ubuntu が提供しているx86_64用カーネルはLinux KVMがモジュール化されているため、modprobeコマンドを実行して読み込んでおきます。

kvmモジュール読み込み
# for Intel社製CPU
$ modprobe kvm
$ modprobe kvm_intel

# for AMD社製CPU
$ modprobe kvm
$ modprobe kvm_amd
ARMアーキテクチャCPUの場合

手元にあった Raspberry Pi 3 に Ubuntu18.04LTS(aarch64) をインストールしてみたところ、lscpuコマンドでは上手く "Virtualization" が表示されませんでした。代わりに、dmesgコマンドの結果からCPU仮想化支援機構が有効化されていることを確認します。
"Hyp mode initialized successfully" と表示されれば有効化されています。

dmesg実行結果
$ dmesg | grep kvm
[    4.399887] kvm [1]: 8-bit VMID
[    4.405636] kvm [1]: Invalid trigger for IRQ4, assuming level low
[    4.410233] kvm [1]: Hyp mode initialized successfully

1. 依存関係のあるパッケージのインストールと環境設定

MirageOS Unikernel は OCaml という関数型言語でアプリケーションレイヤをユーザが記述するため、コンパイラと管理ツールが必要です。コンパイラは"ocaml"、管理ツールは"opam"というパッケージ名です。

特に、Ubuntu18.04LTSのデフォルトで提供されるopamパッケージはバージョンが1.2.2と古いため、外部のリポジトリ ppa:avsm/ppa を利用してバージョン2.0.0以降がインストールされるようにします。

他にも必要なパッケージがあるため、ここでインストールしておきます。

パッケージインストール
$ sudo add-apt-repository ppa:avsm/ppa   # 外部リポジトリ利用
$ sudo apt-get update
$ sudo apt-get install opam ocaml gcc make bubblewrap m4 pkg-config

次に、opamコマンドとOcamlコンパイラに関わる設定をします。具体的には、opam initコマンドでopam環境を初期化し、.bashrc(もしくは.bash_profile)ファイルに eval `opam config env`を追加します。

opam環境の初期化
$ opam init
.bashrc(.bash_profile)の中身
$ tail ~/.bashrc
...
...
eval `opam config env`

次のステップに進むには、一度ログアウトして上記.bashrcファイルの変更を有効化させるか、またはeval `opam config env`を実行しておきます。

なお、このopamコマンドはOCaml環境を簡潔に管理するためのツールであり、異なるOCamlコンパイラのバージョンに切り替えたり、OCaml向けライブラリのインストール/アンインストール(Pythonにおけるpipコマンドと同じ仕組みです)など色々な機能を持っています。opamコマンドについての詳細な説明はこちら

インストール済みOCamlコンパイラの表示
$ opam switch list
#  switch  compiler                    description
→  4.07.0  ocaml-base-compiler.4.07.0  4.07.0
   system  ocaml-system.4.05.0
インストール済みライブラリの表示
$ opam list
# Packages matching: installed
# Name                    # Installed # Synopsis
astring                   0.8.3       Alternative String module for OCaml
base                      v0.11.1     Full standard library replacement for OCaml
...
...
tcpip                     3.5.1       OCaml TCP/IP networking stack, used in MirageOS
topkg                     1.0.0       The transitory OCaml software packager
uchar                     0.0.2       Compatibility library for OCaml's Uchar module

2. MirageOS Unikernel のインストール

実のところ、本ステップはMirageOS Unikernel自体のインストールではありません。MirageOS Unikernelはユーザが記述するアプリケーションコードがあって初めてコンパイルできるものなので、ここでのインストールは「ユーザ記述のアプリケーションコードをコンパイルするためのプログラムやモジュール、ライブラリのインストール」のことを指します。

インストール作業はとても簡単です。下記のコマンドを実行して、mirageパッケージをインストールするだけです。1. にて紹介したopamコマンドを早速利用します。

mirageパッケージインストール
$ opam install mirage

mirageコマンドを使えるようになりました。

mirageコマンド実行
$ mirage
NAME
       mirage - The mirage application builder

SYNOPSIS
       mirage COMMAND ...
...
...

3. Hello World な Mirage Unikernel アプリケーションのコンパイルと実行

Hello World な Mirage Unikernel アプリケーションのコードは、サンプルがあるので github から clone します。

mirage-skeletonのclone
$ git clone https://github.com/mirage/mirage-skeleton.git

この "mirage-skeleton" というリポジトリには、Hello World 以外にもDHCPサーバアプリなど幾つかのアプリケーションコードが登録されています。

次に、Hello World アプリケーションコードのあるディレクトリへ移動します。config.mlunikernel.mlという2つのファイルがあります。前者は構成ファイル、後者はアプリケーションコードファイルです。

helloディレクトリ
$ cd ./mirage-skeleton/tutorial/hello
$ ls
config.ml  unikernel.ml

アプリケーションソースコード(unikernel.ml)を見てみると、 "hello"文字列を出力するための Logs.info()関数がloop()再帰関数によって4回実行されるように記述されています。

unikernel.ml
open Lwt.Infix

module Hello (Time : Mirage_time_lwt.S) = struct

  let start _time =

    let rec loop = function
      | 0 -> Lwt.return_unit
      | n ->
        Logs.info (fun f -> f "hello");
        Time.sleep_ns (Duration.of_sec 1) >>= fun () ->
        loop (n-1)
    in
    loop 4

end

コンパイルしてみます。コンパイルまでには3コマンド実行します。

コンパイルまでの3コマンド(その1)
# ターゲットプラットフォームの設定(ここでは hvt) と コンパイルに必要なファイルの生成
$ mirage configure -t hvt
$ ls
_build  config.ml  key_gen.ml  main.ml  Makefile  mirage-unikernel-hello-hvt.opam  myocamlbuild.ml  unikernel.ml
コンパイルまでの3コマンド(その2)
# 依存関係のあるパッケージのインストール
$ make depend
コンパイルまでの3コマンド(その3)
# MirageOS Unikernel アプリケーションバイナリの生成 と 仮想マシン(hvt)バイナリの生成
$ make
$ ls
_build            config.ml  key_gen.ml  Makefile            mirage-unikernel-hello-hvt.opam  solo5-hvt
_build-solo5-hvt  hello.hvt  main.ml     Makefile.solo5-hvt  myocamlbuild.ml                  unikernel.ml

ここで、hello.hvt は MirageOS Unikernel アプリケーションバイナリファイルであり、solo5-hvt は仮想マシンバイナリファイルです。この2つを用いて、Linux KVMを利用して仮想CPU上でアプリケーションバイナリを実行させます。

このとき、Linux KVM利用のために /dev/kvmファイルをオープンする必要があるため、 sudo コマンド経由での実行となります。sudo コマンドでの実行が不便な場合は /dev/kvm ファイルにreadとwriteのユーザ権限を付与してください(もちろん自己責任の範囲で...)。

アプリケーション実行
$ sudo ./solo5-hvt ./hello.hvt
            |      ___|
  __|  _ \  |  _ \ __ \
\__ \ (   | | (   |  ) |
____/\___/ _|\___/____/
Solo5: Memory map: 512 MB addressable:
Solo5:     unused @ (0x0 - 0xfffff)
Solo5:       text @ (0x100000 - 0x20efff)
Solo5:     rodata @ (0x20f000 - 0x236fff)
Solo5:       data @ (0x237000 - 0x303fff)
Solo5:       heap >= 0x304000 < stack < 0x20000000
2019-01-11 16:42:35 -00:00: INF [application] hello
2019-01-11 16:42:36 -00:00: INF [application] hello
2019-01-11 16:42:37 -00:00: INF [application] hello
2019-01-11 16:42:38 -00:00: INF [application] hello
Solo5: solo5_exit(0) called

無事に "hello" という文字列が4回出力されました!!
なお、アスキーアートと"Solo5:"で始まる文字列は仮想マシン(hvt)側のログ出力です。

4. コードの構成を理解したいときは...

こちらにネットワークアプリケーションを題材とした記事がありますので、参考にしてみてください。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2