MirageOS Unikernel の概要

# MirageOS Unikernel の簡単な歴史
[MirageOS Unikernel](https://mirage.io/) (以下 MirageOS と記述)は、クラウド/ベアメタルサーバなど様々なプラットフォーム上で動作するセキュアかつ高性能なアプリケーションを実現するためのLiburary OSで、Unikernel実装の一つです。

MirageOSのプロジェクトは2009年に始まり、コアチームとして英ケンブリッジ大 [OCaml Labs](http://ocamllabs.io/)、[Docker](https://www.docker.com/)社、[Robur](http://robur.io/)、[Tarides](https://tarides.com/)社に所属するメンバ、および重要なコントリビュータとして[ARM](https://www.arm.com/)社、[IBM Research](http://www.research.ibm.com/)、[Google](https://www.google.com/)社、[Citrix](https://www.citrix.co.jp/)社などに所属するメンバが継続的に開発に携わってきています。

MirageOSが脚光を浴びたのは、2016年1月の「Docker社によるUnikernel Systems社買収」ではないかと思います([Unikernel SystemsのWebサイト](http://unikernel.com/))。Unikernel Systemsはケンブリッジ大のスタートアップ企業であり、そこで開発されていたのがMirageOSです。MirageOSでの成果(ライブラリ等)がDocker for Mac/Windowsに活かされていたりします。

MirageOSに関連する事柄の流れを見ているとなかなか興味深いです。Unikernel Systems社のメンバにはサーバ仮想化ハイパバイザのXenに従事していた方が何人かいます。Xenもケンブリッジ大のスタートアップから始まっているので、「この流れは自然だなぁ」という感じです。MirageOSのクラウド向け(仮想化環境向け)プラットフォームとして最初にXenから始まったのも、そういったバックグラウンドと知識があったからと推測します(個人的見解)。

# とりあえず MirageOSを試してみたい！
まずは[Install](https://mirage.io/wiki/install)のページを参考に環境をセットアップしましょう。サーバ仮想化とかこだわらなくていいのであれば、ベアメタルのLinuxやMac OS上でも動作します。
環境が完成したら、[Hello World!](https://mirage.io/wiki/hello-world)を試してみましょう。途中で`mirage configure -t unix`を実行する箇所が出てきますが、これはMirageOSを動かすバックエンドとしてベアメタルLinuxを利用するときに使います。
(とはいうものの、まだ英語の説明が体系化されていないので今後このQiitaかどこかでスッキリとまとめたいです...)
MirageOSを試そうとすると、[OCaml](https://ocaml.org/)という関数型言語の知識が必要となってきます。Hello Worldのチュートリアルでは補足がされているので比較的わかりやすいですが、そもそも関数型プログラミングに慣れていない方や、さらに何か深掘りしようとすると苦労します。幸いにして[Real World OCaml](https://realworldocaml.org/)というOCamlのエッセンスを解説してくれている本のWeb版を無料で利用できるので、まずはこれを参考にすると良いかと思います。

# MirageOS の特徴
### 1. OCaml for secured software stack  
ユーザがコードを書いてコンパイルしたあとにそのバイナリがMirageOSのアプリケーションレイヤとして組み込まれますが、そのアプリケーションコードは上記で少し言及したOCamlで書かれています。OCamlの詳細な記述をここでは避けますが、OCamlは厳密な型検査を持つセキュアな関数型言語の一つです(関数型言語というと、手続き型言語だけを使ってきた人にとっては敷居が高いですが、一度クリアしてしまうとなかなか面白い世界です)。  
MirageOSでは図のようにOSのコア部分(例えば、TCP/IPなどのネットワーキング)も極力OCamlで実装されていて、バグを生み出す可能性の高いC言語のコードを極力排除するようにしています。  
ちなみにOCamlは投資運用機関である[JaneStreet](https://www.janestreet.com/technology/)が昔から採用し、自社のプラットフォームのために多大なる投資をしてきています。もちろんOCamlコンパイラの開発にも携わっており、その過程でIntel CPUの[バグ](http://ocamllabs.io/general/2017/06/26/IntelHyperThreadBug.html)を発見したりしています。また、[Tezos](https://ocaml.org/meetings/ocaml/2017/extended-abstract__2017__benjamin-canou_gregoire-henry_pierre-chambart_fabrice-le-fessant_arthur-breitman__tezos-the-ocaml-crypto-ledger.pdf)という仮想通貨の実装にも使われているようです。

### 2. Minimum module set
Unikernelの特長である"Small surface"を実現するために、MirageOSではアプリケーションコードにとって必要最低限のモジュールだけを組み込みます。例えば、ネットワークに関するアプリケーションコードを書いた場合にはストレージのモジュール(例えばファイルシステムやブロックデバイス)は必要ありません。
このような機能を実現するために、MirageOSではアプリケーションをコンパイルする際に必要となる構成ファイル(config.ml)の中で、「どのモジュールを利用するか」を把握します。例えば、ネットワークアプリのサンプルの[config.ml](https://github.com/mirage/mirage-skeleton/tree/master/device-usage/network/config.ml)は下記のように

    let stack = generic_stackv4 default_network

と記述してあり、この記述を元に実際に必要となるEthernet、IP、TCPなどのモジュールのパッケージをリンクできるようにMakefileを生成します。このような自動的なモジュールパッケージの把握は[Mirageモジュール](mirage.github.io/mirage/mirage/Mirage/index.html)に記載されたものに関してだけのため、それ以外のモジュールパッケージは明示的に指定してあげる必要があります。例えばhttpクライアントのサンプルの[config.ml](https://github.com/mirage/mirage-skeleton/blob/master/device-usage/http-fetch/config.ml)では、httpクライアントのライブラリパッケージを利用するために明示的に`package "cohttp-mirage";`を記述し、foreign文によって取り込んでいます。

    let client =
      let packages = [ package "cohttp-mirage"; package "duration" ] in
      foreign
        ~packages
        "Unikernel.Client" @@ time @-> console @-> resolver @-> conduit @-> job

### 3. Multiple platforms
MirageOSのアプリケーションは、コードを変更することなく(とはいえ再コンパイルが必要となるのですが)様々なプラットフォーム上で動作させることが可能です。2018年12月現在で動作が確認できているプラットフォームは下記となります。
**ベアメタル上**
- Linux(x86、x86_64)
- MacOS(Intel 64)

**サーバ仮想化上**
- Linux/KVM with hvt(x86_64、aarch64)
- FreeBSD/vmm with hvt(x86_64)
- OpenBSD/vmm with hvt(x86_64)
- Muen with hvt(Intel 64)
- QEMU with virtio(x86_64をエミュレーションしていればハードアーキ問わず)
- Xen(x86、x86_64、arm32)

"with hvt"というのは、IBM Watson Research Laboratoryのメンバが中心になって開発したUnikernelを動作させることに特化したハイパバイザ([HotCloud16のpaper](https://www.usenix.org/system/files/conference/hotcloud16/hotcloud16_williams.pdf))です。最初はLinux KVMのみを考慮していたため"ukvm"と呼ばれていましたが、最近になりターゲットが増えたため"hvt(=hardware-virtualized tender)"に名前が変わりました。hvtはハイパバイザレイヤでも"Small surface"を実現することにフォーカスしており、2. Minimum module setのところで記述したようにMirageOSアプリケーションに必要なハイパバイザの機能モジュールだけをリンクさせてハイパバイザバイナリを動的に生成することが可能です。また、ARM社のエンジニアが協力してくれているため、experimentalではありますが64bit ARM(例えばRaspberry Pi3)上でもMirageOSを動作させることができます([チュートリアル](https://mirage.io/wiki/arm64))。
*→ MirageOSはサーバ仮想化上での動作について、堅牢性向上のためにQEMUやXenよりもhvtにフォーカスしてきています。*

[Muen](https://muen.codelabs.ch/)はスイスのthe University of Applied Sciences Rapperswilにて開発されているMicrokernelであり、Intel社製プロセッサに搭載されているVT-x機能を利用して堅牢なアイソレーションを実現することができます。

# MirageOSをもっと知る
コツコツとトピックを増やしていく予定です。
(Done)
- [とりあえず Hello World を試す](https://qiita.com/t-imada/items/6ee299653ac063532b4f)
- [Networkアプリを題材にちょっと仕組みを理解する](https://qiita.com/t-imada/items/5d0149587d36c6051ed3)
(To do)
- [httpクライアントアプリ](https://github.com/mirage/mirage-skeleton/tree/master/device-usage/http-fetch)を試してみる
- プラットフォームの変更方法 (hvt や Xen や ベアメタルLinux を行ったり来たり)
- [hvt](https://github.com/Solo5/solo5/tree/master/tenders/hvt)の中身をみる (仮想化の中の人としてはとてもおもしろい題材)
- etc ...