Chapter 01

WSL2の時代

WSL2がやってきた

MicrosoftのWindowsを開発環境として魅力的にしようとする諸々の取り組みにおいて、もっとも大規模(OSへの影響含めて)なものがおそらくWSL2です。

WSL1はシステムコールを変換するというアプローチでした。LinuxアプリからはLinuxカーネルに見えるんだけど、実際に動いているのはWindowsカーネルという構造です。

GoogleのgVisor的な。gVisorはホストもゲストもLinuxでセキュリティのために一部のシステムコールを蓋閉じをするという目的だったので、互換性問題が大きくクローズアップされたりしたのは記憶にないです。一方、WSL1はホストとゲストが別なので、実装もいろいろ大変だったと思います。

WSL2はLinuxカーネルをまるごと乗っけてしまい、既存の仮想化のHyper-Vを使うというアプローチになりました。initプロセスはMS製だし、カーネルもMSの手の入ったものではありますが、本物のLinuxカーネルが動作することで互換性は大幅に上がりました。Dockerも含めてLinuxが動くのであれば、今までmacで開発していた環境をこちらにうつそうという人も結構でてきました。

Ryzenという黒船

WSL2自体の注目度もあったのですが、僕の周りに関していえば、Ryzenが後押しをしてWindowsを使い始めた人が多いです。僕自身、ここ2年ぐらい、比較的軽くて、GPUが強くて、ディスプレイが高解像度という条件でノートPCを探していました。1月のCESのニュースの中でASUSのZephyrus G14という機種の情報があり、あまりにも自分の理想にミートしていたので、毎日ニュースサイトを確認し、販売開始と同時に速攻で直販専用モデルを脊髄反射で購入しました。

これ以外にも、Lenovoの3万円のデスクトップ機なんかも話題です。最近はLenovoもHPも、AMDを全面に押し出してきています。僕の買ったのはGPUが良いのもあってそこそこですが、そうでなければ10万円でお釣りが返ってくるのもあるレベルです。僕の周りも、多くの人がデスクトップなりノートなりでRyzen機を次々と購入しています。

WSL2の構造

WSL2は仮想PC(Hyper-V)で本物のLinuxカーネル(WSL2カスタム)が動いています。ただ単に仮想PCというと、CPUやメモリを予めVMのハイパーバイザーアプリに与えておいて、アプリケーションはその小さい枠の中でリソースをやりくりして動くものが多いのですが、WSL2はWindowsとリソースを共有していて、Linuxアプリが「メモリが欲しい」とリクエストすると、Linuxカーネル経由でWindowsカーネルがメモリを渡します。Linuxアプリがメモリを返すと、LinuxはメモリをWindowsに返します。Windows上でWindowsのアプリケーションを実行する時は、予め「今プロセスにこれだけメモリを付与する」みたいなことを設定する必要はありません。これと同じような使い勝手が実現されています。

なお、Windowsから見えるメモリの50%(以前は80%)がVMから見える最大メモリとなっていますし、この割合や容量を変えることもできます。

ストレージはext4の仮想ディスクイメージですが、WSLのプロセスからもWindowsのファイルシステムが見えますし、Windowsのプロセス(エクスプローラ)からもWSLのファイルシステムが相互に見えるようになっており、別のファイルシステム+ネットワーク同期という仕組みにもかかわらず、お互いに同一ファイルシステムで動いているかのようにシームレスです。ChromeOSでLinuxを使うのよりも便利なぐらい。

ネイティブなLinuxカーネルになったことで、DockerもLinuxに近い動作になりました。今までの仮想PCベースから、WSL2上のライトウェイトなcgroup方式でコンテナを起動できます。DockerもWSL2を有効にしていると、WSL2の機能を利用したバックエンドが選択されます。これまでは最新のDocker DesktopはHyper-Vが必須で、それによりPro版のWindowsが必須でしたが、WSL2がHomeでも利用可能になったため、HomeでもDocker Desktopが利用可能になりました。古いDocker Toolkitをわざわざ探してきてインストールする必要もなくなりました。

WSL2の落とし穴

そんな感じでWSL2環境を手にする人が増えて、「Windows便利になったじゃん」と思う人は多く出てきました。僕もインストール直後にちょっと触ってみて、Windowsそのものの進歩もあって、HiDPIでもディスプレイもだいぶきれいになったし、とても良い感触を得ましたが。しかし、本格的な開発をしようとすると、思ったほどパフォーマンス出ないぞと感じ、いろいろ調べたり聞いたりしたところ、この使い方では高性能なはずのスペックをまったくいかせない、ということがわかりました。

また、WSL環境は単なるLinux環境とはまた別で、より複雑です。Linuxの中からWindowsのプログラムを使ったり、WindowsからLinuxのプログラムが利用できるようになります。何かしらの開発支援ツールを作る場合、自分が動作する環境を検知してLinuxプログラムがWindows環境にアクセスしたり、その逆が必要になると思われます。

本ドキュメントでは、そのような落とし穴を避ける方法と、今後LinuxやWindows向けのプログラムを作る人が知っておくと良い、OS環境のもろもろについて紹介します。

WSL上で動くアプリケーションの作法

OS環境がカオスということで、場合によっては環境差異の吸収がアプリケーション側の責務になるのではないかと考えています。今までは行儀の良いマルチプラットフォームアプリというと、だいたい次のような項目を守るだけである程度実現できました。

しかし、ふつうに今まで通りの行儀のよいマルチプラットフォームアプリではWSL2から実行されるWindowsアプリとか、Windows上で実行されるLinuxアプリでは、コンパイル時のターゲットのOSの挙動に引きずられてしまうため、十分とは言えません。ちょっと追加のロジックが必要になります。それらについても紹介します。

参考文献

これを執筆する上で参考にさせていただいたウェブサイトなどは以下の通りです。

また、次の方々にはWSL2の開発の知見などをいろいろ教えていただきました。たくさん売り上げが上がったら、それぞれの方にストロングゼロのケースなどが送付される予定です。

  • @mopemope
  • @moriyoshi
  • @yochang4s
  • @aodag