WSLには3つの「バージョン」がある

Windows で Linux の機能を手軽に扱うことのできるWSL (Windows Subsystem for Linux)．
「WSL」と「WSL2」の2つがあるのはご存じの方も多いと思いますが，実は他にも「バージョン」があることをご存知でしょうか．

順に解説していきます．

# Ⅰ:「WSL1」と「WSL2」
WSLには，大きな仕組みの違いから2つのタイプがあります．
WSL1（WSL）が先に開発されており，後発で WSL2 ができました．
この種類のバージョンは，この2つのみです．（WSL1.1とか，WSL2.1とかはありません。）

現在のWSLのバージョンを確認するには，Powershell上で以下コマンドを実行します．
（コマンドに失敗する場合は，Windowsのバージョンが古く，WSL2が利用できない可能性があります）
```powershell:PowerShell
> wsl -l -v
  NAME        STATE           VERSION
* Ubuntu      Running         2
```

データを保持したまま相互に切り替えることが可能です．（ただし，切り替えには時間がかかります．）
主な違いは[公式サイト](https://learn.microsoft.com/ja-jp/windows/wsl/compare-versions)でも紹介されていますが，まとめると以下の通りです．

|  | WSL1 | WSL2 |
|:-:|:-:|:-:|
| Linuxの機能 | 不完全 | **ほぼ完全** |
| ファイルシステム | Windows上に直接ファイルを作成し保存 | **仮想ディスク上に保存** |
| WSL内でのファイル読み書き速度 | 遅い | **速い** |
| Windows上のファイル読み書き | **可能** | 可能だが，WSL1と比べると遅い |
| ネットワーク | **Windowsと同じIPアドレス・ポートを共有** | Windows下で仮想ネットワーク（NAT）を利用 |
| Dockerの利用 | 困難 | **可能** |

基本的にはWSL2を利用するのがベストですが，WSL2のネットワークについては留意しておく必要があります．
### WSL2のネットワーク
WSL1と異なりWindows下で別のネットワークが構成されています．
WSL上でのIPアドレスは，下記コマンドで確認できます．
```bash:WSL
$ ip a show eth0
6: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:XX:XX:XX brd ff:ff:ff:ff:ff:ff
    inet 172.31.xxx.xxx/20 brd 172.31.xxx.255 scope global eth0
    …
```
そのため，外部のマシンからWindowsを介してWSL内にアクセスするには，Windows側でポート転送（ポートフォワーディング）の設定が必要です．
WSL2のIPアドレスは，WSLの**起動のたびに変化する**ので，自動化するには工夫が必要です．
また，場合によってはファイヤーウォールの設定も追加で必要です．

ただし，WSLを実行しているWindows（ホスト）から，localhostでWSL内にアクセスするぶんには，自動でポート転送を行ってくれるので特に設定は不要です（Localhost Port Forwarding）．
例えば，WSLでApacheを実行するとき…
* ホストマシンで http://localhost にアクセス → ✅OK
* ホストマシンで http://127.0.0.1 にアクセス → ✅OK
* ホストマシンで http://172.31.xxx.xxx （WSL2のIPアドレス）にアクセス → ✅OK
* ホストマシンで http://192.168.xxx.xxx （WindowsのIPアドレス）にアクセス → ⚠️ポート転送が必要
* 外部マシンで http://192.168.xxx.xxx （WindowsのIPアドレス）にアクセス → ⚠️ポート転送（&場合によってファイアウォール設定）が必要
となります．



# Ⅱ:「WSL」のバージョン
しかし，これだけでは話は終わりません．
実は，「WSL1」「WSL2」とはまた区別して，**WSLそのものにもバージョンがあります**．
WSLはMicrosoftストアからインストールするのが一般的かと思うのですが，
ストアから，[Ubuntu 22.04などのディストリビューション](https://apps.microsoft.com/store/detail/ubuntu-22041-lts/9PN20MSR04DW?hl=ja-jp&gl=jp)をインストールするだけでは，実は「WSL」は最新バージョンにはなっていません．（2022年11月現在）
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193471/48d8e269-d5ba-a2d0-b7ca-3b20b41eabc9.png"></img>


初期状態では，Windowsに組み込まれているWSL（「Windowsの機能の有効化と無効化」でオンにした「Linux用Windowsサブシステム」ですね）が利用されています．

このWindows組み込みWSLとは別に，プレビュー版として「WSL」の開発が行われていて，つい最近（2022年11月），正式版としてリリースされました．
その最新版「WSL」を利用するには，同じくMicrosoftストアにある「[Windows Subsystem for Linux](https://apps.microsoft.com/store/detail/windows-subsystem-for-linux/9P9TQF7MRM4R?hl=ja-jp&gl=jp)」をインストールする必要があります．
公式GitHub（ https://github.com/microsoft/WSL/releases ）からダウンロードすることもできます．
（インストールに失敗する場合は，Windowsアップデートを行いましょう：[参考](https://github.com/microsoft/WSL/issues/9157)）
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193471/5635faf6-3967-0a10-9a8d-b5059810704e.png"></img>

上記「Windows Subsystem for Linux」アプリがインストールされている場合，Powershellで下記コマンドでそのバージョンを確認可能です．
```powershell:PowerShell
wsl --version
```
```
WSL バージョン: 1.0.0.0
カーネル バージョン: 5.15.74.2
WSLg バージョン: 1.0.47
MSRDC バージョン: 1.2.3575
Direct3D バージョン: 1.606.4
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windowsバージョン: 10.0.22621.819
```
この「WSL バージョン」がそうです．

:::note warn
出力結果が上記結果のようにならない（コマンドの使い方が表示される）場合は，Windows組み込みWSLが使われている（古いWSLである）状態ですので，上記「Windows Subsystem for Linux」アプリをインストールする必要があります．
:::

このWSLバージョンの違いによって，**利用できる機能に多少の差異があります**（例えば，GUI機能，systemdのサポートなど）．
基本的に新しいバージョンほど機能が追加されていきますので，最新のWSLの機能が使えない場合は，この「Windows Subsystem for Linux」アプリがインストールされているかどうかを確認しましょう．

こちらの「WSL」は下記コマンドでアップデート可能です．
```powershell:PowerShell
wsl --update
```

なお，「Windows Subsystem for Linux」アプリをアンインストールすれば，元の状態（Windows組み込みWSL）に戻ります．

# Ⅲ: WSL カーネルのバージョン
先ほどの`wsl --version`コマンドの出力であった「カーネル バージョン」がそれです．
```
カーネル バージョン: 5.15.74.2
```

こちらは，WSLに用いるLinuxカーネルのバージョンを示しています．
一般に用いられる Linux kernel のリリースに追従して，WSL対応版のカーネルがリリースされているようです．
基本的に，Ⅱで説明したWSLのバージョンに沿って，カーネルのバージョンが決まります．

基本的には必要ありませんが，以下公式GitHubレポジトリからダウンロードして，ビルドすることも可能です．
https://github.com/microsoft/WSL2-Linux-Kernel

ビルド時にネットワーク関連，USBデバイスのサポート等，様々なオプションの選択を行うことができるので，これらの機能が必要な場合に必要に応じて利用することになります．

関連: [WSL2環境からUSBシリアルデバイスを使う](https://qiita.com/baggio/items/28c13ed8ac09fc7ebdf1)

ビルドしたカーネルは，設定ファイルで既定のカーネルと差し替えることが可能です．
（[公式サイトの解説](https://learn.microsoft.com/ja-jp/windows/wsl/wsl-config) にある`kernel`キーを指定します．）


# まとめ
WSLには，大きく分けて次の3種類の「バージョン」があります．
1. **「WSL1」と「WSL2」**: 大きな仕組みの違い，WSL2では(ほぼ)完全なLinuxを利用可能
2. **「WSL」のバージョン**: 「Windows Subsystem for Linux」アプリをインストールしている場合．利用可能な機能に違いがある
3. **Linuxカーネルのバージョン**: WSLで利用されているLinuxカーネルのバージョン

このほかにも，例えばWSLg（Windows上でWSLのGUIアプリが使える機能，Windows 11から利用可能）のバージョンであるとか，
WSLでインストールしているディストリビューションのバージョン（例えば`Ubuntu`なら`18.04`, `20.04`, `22.04` … etc.）など，他にも「バージョン」の種類が考えられます．

一言に「WSLのバージョン」といっても状況によって指し示すものが変わってきますので，混同しないようにしましょう．
それでは，よきWSLライフを！