2025年もWSL1を使っていく

created at
updated at
technology WSL Docker Windows Linux

2025年にもなってWSL1使ってる奴、居る❓
居るよなァ❗

この記事は はてなエンジニア Advent Calendar 2024l の43日目の記事ですが完全に存在を忘れていました。

WSL1とは
Windows上でLinuxを動かすサブシステムとその環境です。1とついている通り、これは最初のバージョンであり、現在は2が最新になっています。
最初期にはBash on Windowsと呼ばれていましたが、Windows Subsystem for Linuxに改名されました。

WSL2との違い
WSL1はWindowsのサブシステムとしてLinuxカーネル互換のシステムコールを実装したものです。対してWSL2はHyper-Vハイパーバイザ上で動くLightweight Utility VMで本物のLinuxを動かしています。
詳しくは WSL バージョンの比較 | Microsoft Learn を参照ください。

WSL1で困るポイント
使っていくと言っているのに先に困るポイントからご紹介します。
  • NTカーネルを巻き込んでクラッシュすることがある
  • たまーにNTカーネルを巻き込んでクラッシュし、今時珍しいブルースクリーンを拝むことができます
  • Linuxのファイルシステムへのアクセスが遅い
  • VSCodeでGitリポジトリにコミットを積もうとすると5秒ぐらいかかったりします
  • systemdが動かない
  • initにはWSLが提供する独自のものが使われるのでsystemdが動きません
  • というかSystem V IPCが実装されていないので逆立ちしても動きません
  • GPU支援が動かない
  • WSL2専用です

WSL1を使う理由
ではなぜそれでもWSL1を使うのでしょうか。
  • WindowsのファイルシステムへのアクセスがWSL2よりも速い
  • WSL2ではvirtio-9p経由でアクセスしますが、TCP/IP経由でWindowsと通信するためあまり速くありません
  • WSL1ではDrvFs経由でアクセスしますが、これはWSLサブシステム内でNTのシステムコールに変換されるだけなので9PFsよりも速いです
  • 逆に言うとLinuxのファイルシステムにもWSLサブシステム内でNTのシステムコールに変換が必要なのでそこがオーバーヘッドになって遅いという事なんですね
  • ネットワーク回りの使い勝手が良い
  • WSL2の場合はVM上で動いているのでハイパーバイザ側でNATが挟まってしまいますが、WSL1はWindows側のNICをシステムコールを変換しつつ使うのでNATがありません
  • WSL2ではmirroredモードもありますが、IPv6がうまく動かなくて困ったりします
  • 浪漫がある
  • Wine と対になる存在そして浪漫を感じませんか?
  • 頑張ればDockerも動く
  • 実は動きます

WSL1でDockerを使う方法
WSL1では頑張ればDockerを使えます。
WindowsのDocker Desktopを導入しつつWSL1のDockerでDocker Desktopを参照することで、WSL1からもDockerをシームレスに使うことができます。
ただし、以下のような問題があります
  • DockerでマウントできるのはWindowsのファイルシステムのみ
  • 仮想化支援技術が使える環境でしか動かない
  • 商用の場合はライセンス購入が必要

インストール方法
  • まずはDocker Desktopをインストールします
  • Docker Desktopを起動して設定を変更します
  • Expose daemon on tcp://localhost:2375 without TLS を有効にしてください
  • WSL1にDocker CLIをインストールします
  • WSL1の設定を変更します
  • Windows側のファイルシステムを / 直下にマウントします。これがミソです
  • Docker Desktop内ではWindows側のファイルシステムが / 直下にマウントされ、/c/Users/owner/something のようにアクセスできるようになっています
  • これによって、Windowsで docker コマンドを実行する時にWindowsのパスをそのまま指定できるようになっています
  • WSL1側もマウントポイントを合わせておくことで、Windowsで docker コマンドを実行した時と同じようにWindowsのパスをそのまま指定できるようになります
  • WSL1のDocker CLIからDocker Desktopに接続します
  • デフォルトのコンテキストは編集できないので、新しいコンテキストを追加します
  • _
    docker context create docker-desktop --docker "host=tcp://localhost:2375"
  • あとは今作ったコンテキストを参照すれば完了です
  • _
    docker context use docker-desktop
  • 毎回コンテキストを変更するのがダルい場合は DOCKER_CONTEXT 環境変数にコンテキスト名を指定しておけば、自動的に切り替えてくれます
  • クレデンシャル関係のエラーが出る時は ~/.docker/config.json を編集してください
  • 完成!!!

おわりに
ここまでしてWSL1を使う必要はないのでWSL2を使いましょう
僕は気合で使い続けます