こんにちは、サイオステクノロジー武井(Twitter:@noriyukitakei)です。今回は、第4回シリーズで、WSL2、Visual Studio Code、Docker、Windows Terminalなどの最新技術を用いて、Windows開発環境をグッとよくしましょうっていうお話をします。第2回目の今回は、WSL1とWSL2ってナニモノなのか、そしてその仕組みをお話したいと思います。
- その1:まずは概要
- 今回はこちら → その2:WSL1&2のしくみ
- その3:WSL2、Windows Terminalで改善!!
- その4:Visual Studio Code、Dockerで改善!!
※ 本記事は技術評論社出版の「WEB+DB PRESS」Vol.117(詳細はこちら)に私が寄稿した「WSL 2、Docker、Visual Studio Code[最新]Windows開発環境」の記事をベースとしております。是非、WEB+DB PRESSの方も合わせてご覧ください!!
なぜWindows Subsystem for Linuxが必要になったのか
Windows Subsystem for Linux(以降、WSL)は、Windows内でLinuxを実行できる仕組みです。1章でも説明したとおり、理想的な開発環境とは、親しみやすいインターフェースを持ったWindowsと、実行基盤の安定性で定評のあるLinuxという、2つの特徴を合わせもったものです。そして、WSLは、その理想的な環境を実現するために重要なサービスの一つなのです。
では、どのようにしてWSLがWindowsの開発環境を改善させるのか、WSL の特徴の説明を交えながら紐解いていきます。
導入の容易さ
まず、導入の容易さについて、ご説明致します。Virtual Boxを始めとした仮想環境は、ネットワークやストレージ、メモリを始めとした各種リソースの設定、それからOSやミドルウェアのインストール、設定と、かなりの手間と時間を要します。
それと比べて、WSLを導入するまでは数ステップ、時間にすれば10分程度で、OSインストール済みの環境が出来上がります。本当に簡単で、あっという間です。
高速起動
WSLの起動は、ほぼ一瞬です。それは、Windowsのコマンドプロンプトを起動するのと同じような感覚といっても過言ではありません。
Virtual Boxなどの仮想環境は、昨今のOSの起動が早くなったとはいえ、WSLには遠く及びません。開発においてLinuxの環境が必要になったとき、たとえ5秒待たされるのさえストレスに感じます。
使いたい時にさっと使えるのは、大きなアドバンテージになるのではないでしょうか?
Windows – Linux間の親和性
WSLは非常にWindowsとの親和性が高いことが、大きなメリットです。その一例として、Windows⇔Linux間の相互ファイルアクセスです。
Virtual Boxでも、SambaなどのCIFSプロトコルに対応したサーバーを立てれば、もちろん可能です。しかし、Sambaのインストールや設定といった煩雑な作業が待っていますし、アクセス権の設定やファイル名の文字コードなど、頭を悩ませることがありますよね。
WSLであれば、とても簡単です。WindowsからLinux上にあるファイルにアクセスするには、「\\wsl$\[ディストリビューションの名前]」というパスにアクセスすればOKです。ディストリビューションがUbuntuの場合は「\\wsl$\Ubuntu-18.04」となります。この機能を使えば、WSL上で動作させているPHPスクリプトに、Windows上のエディタからダイレクトに編集することが可能となります。
LinuxからWindowsの場合は、「/mnt/[ドライブ名]」というパスにアクセスすると、Windowsの指定したドライブ直下にアクセスが出来ます。Cドライブにアクセスする場合は、「/mnt/c」となります。
図2 WSLからWindowsのフォルダへアクセス
WSL1とWSL2との違い
2019年5月にシアトルで開催されたマイクロソフトの開発者向けイベント「Build 2019」で、従来のWSLを強化した「WSL2」が発表されました。
アーキテクチャが大きく刷新されたWSL2の特徴は、「仮想マシン上で動作するホンモノのLinux」ということです。ここからは、今までご説明したWSLとWSL2を明確に区別するために、WSL1と呼称します。
ここで、「え?WSL1のLinuxはニセモノなの?」という疑問が湧くと思いますが、半分アタリです。
アーキテクチャ
WSL1とWSL2のアーキテクチャのイメージ図に基づき、その違いについて、ご説明します。
WSL1は、Linuxカーネルのファンクションコールが、LXCoreというシステムによって、Windowsへのファンクションコールに変換されて、動作しています。よって、WSL1にはLinuxカーネルは存在しません。ご存知のとおり、ファンクションコールは多数あり、それら全てをLXCoreでは変換しきれないため、Linuxの動作を忠実に再現することができません。そのため、Linuxのファンクションコールに強く依存するDockerなどは動作しません。
一方で、WSL2は、Hyper-Vベースの仮想マシンサービス上にLinuxカーネルを搭載したOSが動作します。これにより、Windows上でフル互換のLinuxが動作します。このアーキテクチャは、一見、時代の流れに反しているようにも見えますが、このHyper-Vは、WSL2専用にカスタマイズされた軽量なものであり、さらにLinuxカーネルもマイクロソフト独自パッチを当てることで軽量化を実現しているので、約2秒程度の超高速起動を実現しています。ささっと開発環境にてLinuxが使いたいときに、その起動がもったりするのは、かなりストレスになるのは想像に難くありません。WSL1同様、WSL2もストレスフリーの開発環境を実現できます。
ただ、残念ながら本記事執筆現在(2020年4月17日)、WSL2はWindows Insider Preview版の機能となっており、まだ正式リリースはされていません。Windows Insider Previewは開発中のバージョンにより、まだバグが残っている可能性もあるため、ご利用には十分ご注意下さい。
本章でWSL2を強くおすすめする理由は、「Docker」が動作することです。
先程もご説明しましたが、WSL2は、WSL1と違い、フル互換のLinuxです。つまり、WSL2では強くカーネルに依存するソフトウェアであるDockerが動作します。開発環境においては、Dockerが動作するというのが、その最大のメリットになります。第4章で後述しますが、Windowsでの開発環境は、Dockerを組み合わせることにより、さらにその便利さが加速します。
WSL2はWSL1より高性能であり、基本的にはWSL2を優先して使うほうがいいのですが、先程も説明したようにWSL2は本記事執筆現在(2020年4月17日)、Windows Insider Preview版の機能となっております。よって、WSL2の機能を最大限に活かすことのできる第4章でのみWSL2を使い、第3章ではWSL1を使って説明いたします。
パフォーマンス
WSL1のファイルシステムはNTFSでしたが、WSL2ではEXT4でフォーマットされたVHDになります。WSL1とは違い、Linuxカーネル標準のファイルシステムであるEXT4を利用することにより、ディスクパフォーマンスが大幅に改善しています。ベンチマークとして、Linuxのddコマンドによって、300MBのファイル生成が完了するまでの時間をWSL1とWSL2でそれぞれ計測してみました。
WSL1
$ time dd if=/dev/zero of=test bs=1k count=300000 300000+0 records in 300000+0 records out 307200000 bytes (307 MB, 293 MiB) copied, 1.79515 s, 171 MB/s real 0m1.839s user 0m0.125s sys 0m1.641s
WSL2
$ time dd if=/dev/zero of=test bs=1k count=300000 300000+0 records in 300000+0 records out 307200000 bytes (307 MB, 293 MiB) copied, 0.548946 s, 560 MB/s real 0m0.551s user 0m0.000s sys 0m0.551s
WSL1では300MB書き出すのに0.18秒かかっていますが、WSL2では0.05秒と3倍近いパフォーマンスが出ています。
しかしながら、逆にWSL1のほうがパフォーマンスが出る場合もあります。それはWSL上のLinuxからWindowsのファイルにアクセスする場合です。こちらも先程と同様に300MBのファイル生成が完了するまでの時間を計測しました。
WSL1
# time dd if=/dev/zero of=/mnt/c/data/test bs=1k count=300000 300000+0 records in 300000+0 records out 307200000 bytes (307 MB, 293 MiB) copied, 1.96355 s, 156 MB/s real 0m1.979s user 0m0.063s sys 0m1.813s
WSL2
# time dd if=/dev/zero of=/mnt/c/data/test bs=1k count=300000 300000+0 records in 300000+0 records out 307200000 bytes (307 MB, 293 MiB) copied, 105.718 s, 2.9 MB/s real 1m45.729s user 0m3.770s sys 0m26.386s
WSL1では0.19秒程度で完了しているにも関わらず、WSL2では1分45秒と驚くほどの差が出ています。
WSL1ではWindows側のファイルアクセスにDrvFsというプロコトルを使っており、WSL2ではPlan 9 Filesystem Protocol(9P)というプロトコルを利用しています。このプロトコルの性能差が原因と思われます。
この事象については、以下のマイクロソフトの公式ドキュメントにも記載してあり、Windows側へのファイルアクセスが多い場合には、WSL2よりもWSL1を推奨するとのことです。
使い分けの方針
WSL2は、WSL1とは違いLinuxカネール上で動作するので、機能面では、WSL2を使うほうが多くのメリットはあります。ただし、WSL2にも欠点がないわけではありません。
WSL2は、WSL1をインストールし、Microsoft StoreからUbuntuなどのディストリビューションをインストール後、そのディストリビューションをWSL2にコマンドラインで変換する形で使うことができ、その変換には約10分ほど要することになります。つまり、WSL2はWSL1に比べて、セットアップに一手間必要になります。もしDockerなどのLinuxネイティブな機能が不要であればWSL1でも十分です。
また、WSL2はHyper-Vのサブセット機能を利用するため、その実行には、仮想マシン支援機能が必要となります。これは、PCで仮想化機能を使う際に,仮想化ソフトウエアが処理する作業をCPUで分担して処理してくれるものです。昨今のPCではこの機能はほぼ備わっていますが、例えば、ParallelsというMac上で動作する仮想化ソフトウェアを使って、Windowsを動作させる場合は注意が必要です。Parallelsの場合は、Proという上位バージョンでないと、この仮想マシン支援機能を利用することができません。WSL2を使う場合には、お使いのPC環境を確認して、仮想マシン支援機能が利用できるかをチェックする必要があります。
先程も言及しましたが、LinuxからWindowsへのファイルアクセスは、WSL2よりもWSL1のほうが大幅にパフォーマンスが出ます。よって、Windows側へのファイルアクセスが多い場合は、WSL1の利用をおすすめします。
上記の結果を以下の表にまとめましたので、WSL1およびWSL2使いわけの方針を立案するための参考として下さい。
項目 | WSL1 | WSL2 |
---|---|---|
実現方式 | LXCoreによるコマンドの変換 | Linuxカーネル |
Windows10 Home | 利用可能 | 利用可能 |
仮想マシン支援機能 | 不要 | 必要 |
セットアップ | WSLインストール後すぐ利用可能 | WSLインストール後、WSL2への変換が必要 |
ファイルアクセス(Linux→Linux) | 低速 | 高速 |
ファイルアクセス(Linux→Windows) | 高速 | 低速 |
まとめ
今回はWSL1&WSL2のしくみとその違いについて、お話させていただきました。さて、次回からはいよいよ実践編「WSL2、Windows Terminalで改善!!」になります。