ついにDockerに対応したWSL2を私見で解説してみた

多くの記事も出ていますがMicrosoft Build 2019にて、Windows Subsystem for Linuxの次期版でフル互換のLinuxが動作するとの発表がありました。 これの何が嬉しいってDokcerがWSLで普通に動かせるようになる事です! www.publickey1.jp

セッションを聞いて来たのですが中々面白かったので、自分の理解できた範囲でWSL1から何が変わったのか、どう実現しているのか? を解説していきたいと思います。 私の理解が間違ってるかもしれないので、違っただ誰か指摘ください。

そもそもWindows Subsystem for Linuxって何?

WSLに関して知らない人もいると思いますが、Windows上でLinuxを動かすための仕組みです。 主な用途としては開発ツールチェインを始めとしたLinuxの資産を活かすためなのですが、類似のツールは結構たくさんあります。

などなど。かつてはcoLinuxとかもありました。 Cygwin/MinGW/Git-Bashはツールチェインの移植です。手軽な反面Linuxそのものでは無いので細かく挙動が違いますし、aptなんかも当然使えません。 一方で、Docker for Windows/Docker Toolbox on WindowsWindowsVMを入れて本物のLinuxを起動した上でLinuxを動かすという方法になります。 Linuxに閉じてサーバ開発とかをする分には十分ですが、Windowsから完全に隔離されるのでWindowsの操作を拡張する という用途では使えません。 その辺を両方とも解決してくれるのがWindows Subsystem for Linux すなわちWSLです。

ターミナルとしてLinux環境であるUbuntuSUSEが動くのはもちろんのことWindows環境とファイルは連携されているし、Windows側のPGをWSL上から起動することすらできます。 Windows 10から搭載された機能なので開発者以外には興味ももたれなかったと思いますが、ここ最近で一番アツい機能の一つです。

WSL1はどう動いてる?

WSL1は発表資料を引用すると下記のような構成になっています。 f:id:pascal256:20190509160244p:plain

私の理解だとWSL1はある種のUser Mode Linuxです。 LinuxカーネルへのシステムコールWindows NTカーネル上に作成しバイパスする事で動作しています。

いわゆるx86を全てエミュレートする仮想マシンモデルよりは、こう言ったシミュレータの方が原理的には高速ですし、Windows側との親和性も高く出来ます。 それでいて本物のLinuxディストリビューションが動くのでaptとかyumとか使えて便利ですね。

ただ、以下のような問題もありました。

なので、どうしても微妙に使いづらい感があったのは正直なところです。 特に今はDocker全盛時代でそれが動かないのは個人的には困りました。そこだけDocker Toolboxに接続するとかまあ色んな裏技を試していましたけど、そうすると細かい問題がチラチラと。

この問題はおそらくWindows上でLinuxのシステムコールを実装してることに起因しています。 セッション中でも「メモリモデルとかも違うし単純に1:1に移植できるわけじゃ無いからシステムコールのフル実装は辛い」という感じのことを言っていました。たぶん。 やはり、同じユーザ空間でのシステムコールの実装と言ってもLinux同士で単純にバイパスできるケースがほとんどのUMLやgVisorとは、何もかもが違うNTカーネルLinuxシステムコールを移植するのは相当大変なのでしょう。そもそもマイクロカーネルモノリシックカーネルというレベルで違うし。。。 この辺りが起因してWSL1のいまいち感は出ていました。

WSL2はどう動いている?

というわけで本題のWSL2です。野心的な試みのWSL1に対してWSL2は一見時代に逆行するシンプルなVMアプローチです。 f:id:pascal256:20190510115022p:plain

ただ、VMと言ってもAWSのFireclakcerのように1秒未満の超高速で起動するマイクロVMアプローチになります。 LinuxカーネルもNTカーネルHyper-V上で起動してユーザプロセス同士で通信はするって感じですね。

本物のLinuxカーネルVM上で動いているのでDocker含めて当然全ての機能が動きます。Hyper-Vベースなので技術的にこなれてるのもポイント。

さらにWSL2の環境毎にVMを立ち上げるのではなくLinuxカーネルは一つだけ立ち上げて、それぞれのWSL環境はコンテナで仕切っている様です。 f:id:pascal256:20190510115225p:plain

この辺りはHyper-Vを使ったDockerの実行方法であLinux Containers on Windows (LCOW)の技術を応用してる感じですかね。これによってVMによるオーバヘッドを極小化しているため、demoを見ている限りでは起動など劣化はほぼ見られませんでした。

f:id:pascal256:20190510114820p:plain

なお、Linuxカーネル自体もマイクロソフト謹製なので用途最適化されてる様です。たぶんVM前提でデバイスドライバ減らすとかそういうの。 ちなみにWindows UpdateLinuxカーネルがバージョンアップされる様になったとのコメントには会場も爆笑でしたw

パフォーマンス

ファイル周りの遅さが改善されてパフォーマンスは大きく向上している様です。 f:id:pascal256:20190510114336p:plain f:id:pascal256:20190510114450p:plain

理論的にはUML方式のが速い気がするのですが、実装の最適化度合いやファイルシステム周りの違いかな。 NTカーネル経由せずに直接ハイパーバイザを叩くならAPI的にもシンプルな可能性がありますし。 また、VMだと使用メモリ等が気になるところですがデモ中リソースモニタで監視しててもほとんど増えず、カーネルを仮想で動かしてる部分に関してはかなり小さい様です。

CPUヘビーな処理だとどうなるのかはちょっと気になるところですが、最近のVMでCPUが極端に劣化するイメージも無いので通常用途は大丈夫な気がします。

Windows側との連携

これだけだと「LCOWでDokcer起動すれば良くねって?」って話になるのですが、Windowsとの連携こそがWSLの真骨頂。ちゃんとWSL2も以下の特徴は引き継いでる様です。

  • Windows上のファイルがWSLから見れる
  • WSL上のファイルがWindowsから見れる
  • Windowsの実行ファイルをWSLのターミナルから実行できる

WSLからのアクセス f:id:pascal256:20190510120351p:plain

WSLへのアクセス f:id:pascal256:20190510120535p:plain

どうやって実現してるのかというと、まさかの9P(Plan 9 Filesystem Protocol)です。令和の時代にまさからPlan9の単語を聞くとは思わなかったですが分散OSなので、こういうのには向いてるのかもしれないです。 一応「SMBとかNFSとかなんで使わないの?」って質問に対して「こっちのが単純だから」と答えて気がします。ちょっと自信なし。

あと、あまり実装の詳細は分からなかったですが従来通りWindows側の実行ファイルをキックしたりも出来ていたので、この辺りの開発者フレンドリーなUXを作って来るのはさすがMSって感じがしました。

このおかげでWindows環境のツールチェインの一部としてLinuxの機能をフルに利用する事が出来ます。

まとめ

WSL2によりFuseやDockerがWindows10で簡単に動かせる様になりそうです。 これによってCI環境でWindowsコンテナとLinuxコンテナを混在させたかった課題とかが解決しそうで個人的にはドンピシャなソリューション。

それをおいてもWIndowsLinuxの開発はかなりしやすくなりますし、Windowsの補助ツールとしても使える。 もしかしたら将来的にはWIndowsを直接サポートせずにWSL前提なOSSとかも出てくるんじゃないかと思います。リリースが待ち遠しい!

そうなって来ると最近はMacもいまいちだし、Surface欲しくなるなぁ、とそんな気持ちになりますね。Linuxは敵だと言っていたMicrosoftも今は昔。

それではHappy Hacking!

参考