機能も増えてきた WSL2 を使おう!
シーエー・アドバンス Advent Calendar 2023 5日目
普段自宅のPCでは WSL を使って、Linux環境を利用しています。WindowsではWSLがLinux環境として使えます。
そんな WSL もリリースされてから結構時間が経ちますが、最近いろいろと機能の更新があったので、機能の調査してみました!
インストール
たった1行です。
wsl --install
詳細は下記で!
新機能を試す
2.0.0 が今年(2023) にリリースされ、以下の設定項目が追加され、新しい機能が使えるようになっています。
リリース内容
[experimental] autoMemoryReclaim=gradual | dropcache | disabled networkingMode=mirrored dnsTunneling=true firewall=true autoProxy=true
この中で気になるもの。
autoMemoryReclaim
は WSL(Linux) が確保しているメモリのキャッシュを開放する設定で、これにより、メモリの節約ができそうです。
networkingMode
はネットワークインターフェースを wsl と windows で同じものを使うようにする(ミラー)設定で、windows の firewall の設定などを適切に行えば、他の端末から WSL にダイレクトでアクセスできるようになりそうです(他の端末から wsl に ssh で接続したり、ウェブサーバーにアクセスしたり)
新機能は experimental としてリリースされましたが、2.0.5 のバージョンから、新機能のうちのいくつかは通常の機能に昇格したようです。
(当初は、.wslconfig の [experimental]
セクションで設定を書く必要がありましたが、通常機能に昇格したものは [wsl2]
セクションに記載します。後方互換性のため、[experimental]
セクションに記載してもいいようですが)
autoMemoryReclaim
を試す
この機能のお陰で、キャッシュ用途のメモリを徐々に開放してくれて、メモリの節約ができる嬉しい機能です。一気にメモリが開放されるわけじゃないので、キャッシュの良さも活かしつつ、パフォーマンスのバランスも取れるはず(という触れ込み)
.wslconfig の [experimental]
セクションに autoMemoryReclaim=gradual
を記載し、wsl を再起動したら、機能が有効になります。
機能が有効になったかどうかは、以下のファイルの有無を確認すればいいみたいです。あれば有効。
❯ ls /sys/fs/cgroup/memory.reclaim
/sys/fs/cgroup/memory.reclaim
上記ファイルがあることを確認し、npm install
などの、ファイルキャッシュをたくさん使いそうな操作を行って、メモリの変化を見てみました。
npm install 実行前
Linux 上で観測したメモリ
Every 2.0s: free -h windows: Mon Dec 4 21:55:13 2023
total used free shared buff/cache available
Mem: 3.8Gi 996Mi 2.4Gi 13Mi 513Mi 2.6Gi
Swap: 1.0Gi 695Mi 328Mi
buff/cache が 513MB 程度でスタート
VmmemWSL
のメモリ使用量
Windows 上のタスクマネジャーで観測した タスクマネジャーでは1GB弱でスタート
npm install 直後
Linux 上で観測したメモリ
Every 2.0s: free -h windows: Mon Dec 4 21:57:23 2023
total used free shared buff/cache available
Mem: 3.8Gi 763Mi 1.9Gi 13Mi 1.2Gi 2.8Gi
Swap: 1.0Gi 695Mi 328Mi
buff/cache が増えて、npm install で作成されたファイルのキャッシュが作られていそうな雰囲気。
VmmemWSL
のメモリ使用量
Windows 上のタスクマネジャーで観測した VmmemWSL
のメモリ使用量めっちゃ上がる~
npm install してからしばらく経過
Linux 上で観測したメモリ
Every 2.0s: free -h windows: Mon Dec 4 22:02:32 2023
total used free shared buff/cache available
Mem: 3.8Gi 730Mi 2.5Gi 12Mi 590Mi 2.9Gi
Swap: 1.0Gi 717Mi 306Mi
7分くらいで、実行前のメモリ使用量まで落ち着いた
VmmemWSL
のメモリ使用量
Windows 上のタスクマネジャーで観測した WSL が保持しているメモリの減少も確認できた。でも開始当初と比べると、メモリの使用量多い・・・。
Windows からみたメモリの使用量はすごく緩やかに開放されるのかもしれない。
networkingMode
を試す
こちらは、WSL のネットワークの挙動を変更する機能です。
networkingMode=mirrored
に設定した場合、仮想マシン的な存在である WSL と、 Windows で同じネットワークインターフェースを使うようになります。
従来(NAT)
従来は、WSLのネットワークは NAT になっていて、他の端末から WSL にネットワークを介してアクセスするには、起動の都度変わる WSL のIPアドレスに対して、ポートフォワーディング(netsh の portproxy)の設定を行う必要がありました。
ざっくり言うとこんな感じで通信できるようにポートフォワーディングを行う必要があった↓
(他の端末 → Windows のネットワークインタフェースのポート → WSLのIPアドレスのポート)
※Windows 上で firewall の設定をして、ポートフォワードするポートの Inbound も許可しておく必要があります
mirrored
mirrored にすると、Windows と WSL でネットワークインターフェースが同じになるので、上記の3段構成が以下の2段構成に変わります!
(他の端末 → Windows & WSL のインターフェース)
インターフェースがミラーされるので、他の端末からは Windows に通信する感じで、WSLに直接アクセスができるようになリます。
設定が有効になっているかどうかは、以下のコマンドを wsl 上で実行することで確認できます。
❯ /usr/bin/wslinfo --networking-mode
mirrored
何が嬉しいかというと、WSLをサーバーの用途として使いたいときに、ネットワークに繋げやすくなったというところですね。
そもそも、そんな用途あんまり無さそうですが・・・w
ただ、なにかしらウェブアプリをWSLで開発して、それのスマホレイアウトを確認しようというときに、PCのブラウザではなくて、実機で直接 WSL のサーバーにリクエストその表示を確認するといったことなら1ミリくらい需要ありそうです。
まあ・・・頑張ってWSLでサーバー動かすぐらいなら、Linuxインストールしたほうが簡単なんですけどね~😭
あれ?なんか動かない?
試したんですが、なんか動かない・・・
調べてみると、色々と問題がありそうでした。
Docker との互換性問題!
残念!networkingMode=mirrored
が有効になっていると、WSL 上で起動した docker コンテナにポートフォワーディングができないようです!
つまり、docker コンテナで nginx を起動したときにブラウザから http://localhost でアクセスできません!
なお、従来の nat モードなら普通に docker 使えますので、nat に戻せば問題なしです。
80 番ポートのウェブサーバーが動きません!
コンテナがだめなら、WSL上に直接ウェブサーバー動かせばいいじゃん!と思い、
python -m http.server
や nginx のデーモン起動などを試しましたが、
なにやら 80 番ポートが使用済で WSL 上でウェブサーバーが起動できません!
sudo lsof -i tcp:80
とかで、80 番ポートを使っているプロセスを WSL上で 探しましたが、見つからず。
NETSTAT.EXE -aon | grep ":80"
のコマンドを Powershell で実行すると、以下のプロセスが80番ポートを使っていたことがわかりました。
❯ NETSTAT.EXE -aon | grep ":80"
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4924
更に、プロセス4924をタスクマネジャーで検索すると、Service Host: IP Helper
のプログラムが実行されていることがわかりました。(タスクマネジャーって検索できるんですね!便利!)
タスクマネジャーの上部に検索ボックスがあることに初めて気がついて・・・感動
このタスク(プロセス) を止めてしまえば、80 番ポートが開放されて、WSL上で起動しているウェブサーバーが使えるようになりそうですが、
なんか Windows 標準のプログラムのようなので、止めると OS のネットワーク機能に支障がありそうで、断念。
ウェブサーバーだけじゃなくて、SSH の 22 番ポートも同じタスクに使われてしまっているので、ある端末から、WSL に SSH するというのも難しそうです。
なお、80 番以外の適当な空いているポート番号を使えば、一応 WSL 上でウェブサーバー起動して、localhost:4567 とかでアクセスできることは確認できました。
ネットワークインターフェースでは WSL と Windows で同じIPアドレスになっていた
機能を有効にすると、たしかにネットワークインターフェースは、WSLとWindowsで同じIPアドレスが振られていました。
ipconfig.exe
~~~ 省略 ~~~
Wireless LAN adapter Wi-Fi:
Connection-specific DNS Suffix . : flets-west.jp
IPv6 Address. . . . . . . . . . . : 240b:252:9083:bd00:d528:6d3f:8a21:45a2
Temporary IPv6 Address. . . . . . : 240b:252:9083:bd00:8537:40e:937c:2a46
Temporary IPv6 Address. . . . . . : 240b:252:9083:bd00:9167:4e64:d975:944a
Link-local IPv6 Address . . . . . : fe80::2ae9:7ed3:7476:6ee2%14
IPv4 Address. . . . . . . . . . . : 192.168.11.5
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : fe80::212:e2ff:fe70:7148%14
192.168.11.1
~~~ 省略 ~~~
❯ ip a
'1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: loopback0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:6d:b1:28 brd ff:ff:ff:ff:ff:ff
3: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN group default qlen 1000
link/ether 9c:2d:cd:93:55:84 brd ff:ff:ff:ff:ff:ff
4: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN group default qlen 1000
link/ether 00:15:5d:e7:30:f6 brd ff:ff:ff:ff:ff:ff
5: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 10:b1:df:70:0c:eb brd ff:ff:ff:ff:ff:ff
inet 192.168.11.5/24 brd 192.168.11.255 scope global noprefixroute eth2
valid_lft forever preferred_lft forever
inet6 240b:252:9083:bd00:8537:40e:937c:2a46/128 scope global nodad noprefixroute
valid_lft forever preferred_lft forever
inet6 240b:252:9083:bd00:d528:6d3f:8a21:45a2/64 scope global nodad deprecated noprefixroute
valid_lft forever preferred_lft 0sec
inet6 fe80::2ae9:7ed3:7476:6ee2/64 scope link nodad noprefixroute
valid_lft forever preferred_lft forever
ただ、前述の通り、IPアドレスが共通化されても、Docker が以前のように使えなくなったり、
80 番ポートが競合してしまったりと、
mirrored のネットワークモードはなかなか制約多くてまだ使いづらい印象です。
まとめ
- autoMemoryReclaim はいい感じにメモリ節約してくれる
- networkingMode=mirrored はなんだかまだ不安定。制約も多し。でもいつかもっと改善されてほしい!
今後も WSL の研究続けていきます!
参考
Discussion