Unikernelな情報 (in Japanese)

# はじめに
「Unikernelって知ってますか!?」という質問を日本で(というか海外でも)聞くとだいたい「知らない」と冷たい回答が返ってくるので、啓蒙活動の一環としてこの記事を書いてみることにしました。

サーバ仮想化用ハイパバイザの中の人のおしごとに就いて5年くらい経った頃、「次の面白いネタは何かなぁ」と探していたらフラッとUnikernelの話が一部の界隈で盛り上がり始めたのが2016年前半。

そこからずっと、「将来のコンピューティングスタイルを変えるのはUnikernelだね」と超個人的に熱い視線を注ぎ続けています。

# Unikernelとは
ちょっと"Unikernel"とググると、英文で結構記事が出て来ます。よく目にする記事は「2016年1月にDocker社がUnikernel Systems社を買収した」という内容で、有名な企業がUnikernelという技術に注目し始めたという点でインパクトがありました。しかし技術的な内容はあまり書かれていません。
- [Unikernel Systems Joins Docker @ Docker社blog](https://blog.docker.com/2016/01/unikernel/)

技術的な内容として有名でよく参照されるのは、ASPLOSというプログラミング言語系の国際会議にて2013年に発表された論文
- [Unikernels: Library Operating Systems for the Cloud](http://anil.recoil.org/papers/2013-asplos-mirage.pdf)
もしくは、2014年のACM QUEUEに掲載された記事
- [Unikernels: Rise of the Virtual Library Operating System](https://queue.acm.org/detail.cfm?id=2566628)
になります。

さて、Unikernelがどんなものかというと...
> 特定のアプリケーションプログラム、それを動かすためだけの小さなOS、必要な設定ファイルを一つにまとめたもの

と解釈することが出来ます。一般的なアプリケーション・サービスの動かし方といえば、「1つのOSをインストールしたあと、そのOS上で複数のアプリケーションまたはサービスを動作させる」というのが定石です。一方Unikernelな世界では、複数のアプリケーションまたはサービスを動かそうとする場合、あるアプリケーションプログラムとOSは1対1で紐付いているので、複数の小さなOSが同時に動くことになります。
![comparison.png](https://qiita-image-store.s3.amazonaws.com/0/291185/40bd9e21-0366-8e68-0233-93ccc3ebccb0.png)

しかしながら上記の2文献に図にて表現されているように(例えば後者の文献のFigure.1)、UnikernelのOSイメージファイルは小さいです。よほど変なことをしなければ大きくても10MB強に収まるでしょう。例えば50個のアプリケーションサービスを立ち上げないといけないとして、50個のUnikernel OSイメージが必要だとしても合計で高々500MB。ハイパバイザの領域を含め多く見積もっても1-2GBには収まるでしょう。仮想マシン用のLinux OSイメージは簡単に数GBくらいのサイズに達しますから、効率的です。

Unikernelではこの「小さなOS」というアイテムがキーとなってきます。基本的にこのOSはLinuxなどのメジャーなものをそのまま使っているわけではありません。プロプライエタリな実装なものであったり(とは言ってもいろいろなOSSを組み入れたりしている)、[Mini-OS](https://wiki.xenproject.org/wiki/Mini-OS)をベースとしたものであったり種類は様々です。OSレイヤの実装次第で、上で走るアプリケーション・サービスで利用できる機能が決まります。例えば、あるUnikernelでは仮想PCIデバイスを使えたり、別のUnikernelではPOSIXを提供していたり、など。つまり、Unikernelの特徴はOSレイヤの実装と大きくリンクしています。

１つUnikernelについて注意しておくことと言えば、
　　「巷のサーバ仮想化技術は必須ではない」
ということがあります。上記の絵ではハイパバイザ利用前提で描いていますが、実は単なるホストOS上のプロセスの１つとしてUnikernelを動作させる構成を取ることもあります。例えば、ワタシが激推ししている[MirageOS Unikernel](https://mirage.io/)では実際にそのような構成をとることが可能です。この場合、
　　「Linux or MacOS上のプロセスとしてUnikernelが動作する」
　　「つまりプロセス内部で別のOSが動いている」
　　「でもサーバ仮想化は使わない」
という「？」が沸いてくる状態となります。さらに、seccomp機能を利用した[spt tender](https://dl.acm.org/doi/10.1145/3267809.3267845)というものの上でMirageOS Unikernelを動作させ、セキュア環境を強化させることも可能となっています。

# Unikernelのいいところ
[unikernel.org](http://unikernel.org/) (本ページの一番下を参照)のトップページに書いてあるのは下記の4つです。
1. Improved security
2. Small footprint
3. Highly optimized
4. Fast boot

1.は2.と大きな関係があります。UnikernelのOSイメージはサイズが小さいのは、つまりのところソースコード量が少ないためです。こうすると、外部から攻撃される箇所(=バグが生まれる箇所)が自然と減っていきます。また、Unikernelは特定のアプリケーションだけを起動するためだけのものなので、通常OSレイヤにおいてユーザという概念が存在しません。つまりrootのようなスーパーユーザも存在しないので、権限の奪取は起こりません。execve()やsystem()などといった関数も通常無いので、CPUのNX bitと組み合わせてスタック領域でのコードセグメント実行を阻止すればShellcodeのような意図しないコード実行は相当困難になるはずです。とはいえ、Unikernel実装のバグによってバッファーオーバーフローを引き起こさせてしまうので、その点においては注意が必要です。

2.は文字通りUnikernelのOSイメージが小さいということです。これに大きく貢献している要素は、(i)利用可能デバイス種を少なくする(物理サーバ上での直接動作をやめて特定のハイパバイザ上での動作のみにする など)、(ii)アプリケーション動作に必要の無いOS機能をOSイメージに組み入れない(Linux kernel moduleのような動的なOS構成変更) といったものが挙げられます。なので小型のIoT用デバイスのOSとしてUnikernelはうってつけだと思います。

3.はアプリケーションとOSの構成決定をコンパイル時になるべく実施する事に由来します。これにより静的解析出来る箇所が増え、最適化できる範囲が広がります。

4.は文字通り起動時間が短いということです。ハイパバイザ上で動かすUnikernelであっても、BIOS初期化を必要としないOS/仮想マシンレイヤの実装であれば通常のアプリケーション起動と遜色ないくらいの時間でUnikernelベースのアプリケーションを起動させることが出来ます。仮想マシンの枠組みで隔離されたセキュアなFunctionを動作させてFaaS(Function as a Service)を実現するための一手法として、Unikernelが候補になるでしょう。

# Unikernelの苦労するところ
ナレッジが散らばっている...というか絶対量が足りない。
まだまだUnikernelはCutting edgeな段階にありマニュアルが充実していないので、興味があっても実際に使えるようになるまでに結構時間を要します。各Unikernelのメンテナたちはチュートリアル的なwebページを充実させるよう努力しているところではありますが、Dockerコンテナのようにパッと使えるようになる段階にまでは至っていません。

これはUnikernelに限った話ではありませんが、特にハイパバイザ上で動作させるUnikernelのデバッグとチューニングは複雑です。これに対して2017年にNEC Europeメンバが[Uniprof](http://sysml.neclab.eu/projects/uniprof/)を発表し、少しずつ改善される気配を見せ始めているので期待です。

# いろいろなUnikernel
世の中には用途別にいろいろなUnikernelの実装があります。アプリケーション・サービスレイヤの記述言語が異なっていたり、特定の用途向けであったり...。動くプラットフォームも違います。

言語別:
[Clive](http://lsub.org/ls/clive.html) (Go言語ベースで書かれたアプリケーション、ベアメタル環境で動作)
[HaLVM](https://galois.com/project/halvm/) (Haskell言語で書かれたアプリケーション、Xen環境で動作)
[IncludeOS](http://www.includeos.org/) (C++言語で書かれたアプリケーション、KVM環境で動作)
[LING](http://erlangonxen.org/) (Erlang/OTPで書かれたアプリケーション、Xen環境で動作)
[MirageOS](https://mirage.io/) (OCaml言語で書かれたアプリケーション、ベアメタル・Xen・KVM環境で動作)
[OSv](http://osv.io/) (C, Java, Ruby, Node.js言語で書かれたアプリケーション、Xen・KVM・Virtualbox・VMware環境で動作)
[runtime.js](http://runtimejs.org/) (Javascript言語で書かれたアプリケーション、KVM環境で動作)

特定用途:
[ClickOS](http://cnp.neclab.eu/projects/clickos/) (NFV用途向け、Xen環境で動作)
[Hermitcore](https://hermitcore.org/) (HPC用途向け、ベアメタル・KVM環境で動作)

互換性重視:
[Rumprun](http://rumpkernel.org/) (POSIX準拠アプリケーション、ベアメタル・Xen・KVM環境で動作)

Linux:
[UKL](http://www.cs.bu.edu/~jappavoo/Resources/Papers/unikernel-hotos19.pdf) (ボストン大＆RedHatによるLinuxアプリ向けUnikernel)
[UniLinux](https://www.youtube.com/watch?v=I_bGUjYGMZY) (LinuxをRing0&シングルプロセスで動作)

Windows:
[Drawbridge](http://research.microsoft.com/en-us/projects/drawbridge/) (Windowsアプリケーション、ベアメタル環境で動作)

いろいろ?:
[Unikraft](https://xenproject.org/developers/teams/unikraft/) (ライブラリ化した機能モジュールをベースにKonfigを用いてUnikernelを作成)

自作のアプリケーションをUnikernelとして動かしてみたいのであれば、言語別のUnikernelを試すのが一番近道になるかと思います。NFVもしくはHPCという特定用途を目的とするならばClickOS or Hermitcore。既存のアプリケーションをUnikernelとして動かしてみたいのであれば、(全て動くわけではありませんが)互換性重視のRumprunが選択肢になります([Apache Cassandra](https://github.com/cloudius-systems/osv/wiki/Cassandra-quickstart-on-OSv-with-KVM)の例があります)。また、UKLはRedHatが関与しているプロジェクトであり、既存プログラムの簡易なUnikernel化という大きなアドバンテージを持ちます。まだ始まったばっかりのような段階ではありますが、論文タイトルにもあるように "The Next Stage of Linux’s Dominance" となるのか今後の動きがとても楽しみです。

上記の中では活動が縮小しているようなUnikernelがあるので、長期的かつ本格的な活用を考えている場合には注意が必要です。これはホームページやgithubの更新具合である程度推測出来ます。Microsoft ResearchのDrawbridgeはそのものが公にavailableになってはいないようですが、そこでの成果が[Windows Subsystem for Linux](https://docs.microsoft.com/ja-jp/windows/wsl/about) (Windows上でLinuxのプログラムを動かす)や[SQL Server on Linux](https://blogs.msdn.microsoft.com/dataplatjp/2017/03/08/whats-sqlserver-on-linux-2/) (SQL ServerをLinux上で動かす)に活かされているようです。

個人的には、セキュリティ向上という観点でアプリケーションレイヤにOCaml(関数型言語の一つ)を採用していて、かつ開発コミュニティが活発なMirageOSを推しています。

# 統合的なUnikernel開発・運用環境
上記で紹介したUnikernelはそれぞれが独自の開発環境を有しているため、個別に対応して扱っていくのは困難です。そんな困難を取り除くべく、[Unik](https://github.com/solo-io/unik)というツールが開発されています。ストレージベンダのEMCがその開発に携わっており([SlideShare](https://www.slideshare.net/Pivotal/unik-unikernel-backend-to-cloud-foundry))、「ストレージベンダがUnikernel関係のおしごとを!?」という点で非常に興味深いです。

# Unikernelに関係している企業
(もっとあると思うので、分かり次第追加していきます)

- [Docker](https://www.docker.com/)  
上記で言及したように、英ケンブリッジ大のスタートアップであるUnikernel Systemsを買収した会社です。Unikernel SystemsはMirageOSを手がけており、MirageOSでの成果がDocker社製品にフィードバックされています。
- [Tarides] (https://tarides.com/)  
フランスのベンチャー企業であり、元々Docker社でMirageOSやDocker for Mac/Windowsに従事していた方が起こした企業です。MirageOS本体などの開発と、企業向けサポート＆開発を手がけています。
- [robur](https://robur.io/Home)  
MirageOSをベースにソフトウェアを開発している非営利組織です。組織設立前からMirageOSの開発に携わっているメンバが所属しています。
- [nanovms](https://nanovms.com/)  
元々Deferpanicという名前で設立されたスタートアップで、Unikernel IaaSのプラットフォームを提供しています。
- [Zededa](https://www.zededa.com/)  
IoT向けプラットフォームへのUnikernel適用を考えているスタートアップです([sdxcentralの記事](https://www.sdxcentral.com/articles/news/zededa-wants-to-use-the-cloud-to-power-iot-at-the-edge/2018/04/))。
- [ARM](https://www.arm.com/)  
MirageOSはARMアーキテクチャでの動作をサポートしていたり、Unikernel専用仮想マシンモニタである[hvt](https://github.com/Solo5/solo5/tree/master/tenders/hvt)のARMプロセッサ対応にARM社のエンジニアが携わっています。
- [NEC Laboratories Europe](http://sysml.neclab.eu/)  
上記のClickOSやUnikraft、Uniprofの研究をしています。
- [EMC](https://www.dellemc.com/)  
上記で述べたように、UnikというUnikernel開発・管理ツールを開発しています。
- [VMWare](https://research.vmware.com/)  
中国のR&Dチームの方がUniLinuxに取り組んでいます。
- [Boston University & RedHat](https://www.bu.edu/rhcollab/2018/11/27/ukl-a-linux-based-unikernel-with-a-community-based-approach-created-via-the-boston-university-red-hat-collaboratory/)  
Collaboratoryという形でUKLの研究開発に取り組んでいます。
- [SAP](https://www.sap.com/)  
SAPはご存じの通りERPやHANAで有名な企業です。クラウドアプリのコンテキストで[ReasonML](https://reasonml.github.io/)という言語(JavascriptとOCamlのいいとこ取り言語)に取り組んでいるらしく、OCamlを採用しているMirageOSに携わる人材採用を行っていて今後の進展に期待です。

# もっとUnikernelについて知る
Unikernelのゲートウェイ的なWebサイトが[unikernel.org](http://unikernel.org/)です。いろいろなUnikernelの情報が集まっています。
また、Unikernelについての議論は[Unikernel Devel](https://devel.unikernel.org/)にて行われます。

もし特定のUnikernel実装を気に入ったのであれば、そのUnikernelのメーリングリストに登録してみたりIRCに参加するとdeepな情報を入手することが出来ます！

# Linuxkit
「そうはいってもUnikernelはちと難しいよねぇ。まだ時代はコンテナだしさぁ」と考える方も多いかと思います。Dockerコンテナイメージのfootprintを小さくし、そのコンテナを動かすためだけの小さなLinuxOSが含まれたVMイメージを作成する[Linuxkit](https://github.com/linuxkit/linuxkit)というツールがMoby project(特定用途のコンテナを労せずに開発するためのフレームワーク)にて開発されています。

DockerCon17にて、Redisのコンテナが動作するVMイメージを作成している例があります([SlideShare](https://www.slideshare.net/Docker/dockercon-2017-general-session-day-1-solomon-hykes-75362520))。

Unikernelの思想と似ていますがLinux OSベースであることからユーザという概念がまだ存在し、Unikernelと同等のセキュア性を確保するまでには至らないことに注意する必要があります。

当然のこと(?)、LinuxkitにはMirageOS開発者が携わっていてセキュア性向上に取り組んでいます([MirageSDKの紹介@Linukit Security SIG meeting](https://www.youtube.com/watch?v=GkjswX75K08))。

# Unikernelなニュース
ここでは、Unikernelにまつわる新しめのニュースを随時追加していければいいなぁと思います。

19th Oct 2020:
5月に発表があったアメリカDoEのSCADA研究プロジェクトは、nanovms社が絡んでいるようです。[ここ](https://nanovms.com/markets/energy)に記事が出ていました。

21st May 2020:
アメリカの[DoE(Department of Energy)](https://www.energy.gov/articles/us-department-energy-announces-53-million-small-business-research-and-development-grants)に採択された研究プロジェクトにおいて、Unikernelなネタが含まれています。SCADA(Supervisory Control And Data Acquisition)という文字通り「データ収集と装置制御を司る」ソフトウェアのセキュア化にUnikernelを組み込んでいくようです。工場でもIoTなんて単語が身近になってきているので、先を見越した面白そうなネタです。
> Office of Cybersecurity, Energy Security and Emergency Response
>   Unikernel Isolation for Secure SCADA

# おわりに
UnikernelはまだまだEarly phaseな技術なので、これから進歩していくと思います。
Unikernelな世界で動きがあり次第、本ページをできる限り更新していきます!!