WSL2にした話
0. ついに Windows 10 version 2004 が GA
先日、ようやくWindows 10 version 2004がGAになったので入れてみた。
今回の目玉の一つはWindows Subsystem for Linux(WSL) version 2(以下「WSL2」)だろう。
僕はすでに既存のWSLでUbuntuを使っていたので、公式の移行手順をもとにUbuntuを更新を開始。
#WSL2 に変換開始! pic.twitter.com/9vo6v4bLOw
— HAJIME Fukuna / 福名 一 (@f97one) May 29, 2020
で、どうなったかというと
- 手元の環境では移行に2時間40分ほどかかった(「数分かかることがあります」とはいったい....)
- 手元のPCには16GBほどメモリを積んでいるんだけど、途中、vmmemというプロセスが10GBほどメモリを握りこんで動作が非常に緩慢になる
....てな感じではあったもののどうにか終了。変換が終了したら、vmmemが握っていたメモリは無事解放された。
終わったぁぁぁぁ!! メモリも減った! #WSL2 pic.twitter.com/BSAPVetKUG
— HAJIME Fukuna / 福名 一 (@f97one) May 29, 2020
ちなみにこのvmmemというプロセス、後で調べてみたら、どうやらこれが「WSL2が使っているマネージドVM」な模様。
1. Xクライアントを動かせるようにする
変換が無事終わったので WSLのUbuntuを起動。
僕はWindows用XサーバのVcXsrvをホスト環境に入れていて、Linuxのほうがいろいろと都合がいいPHPなんかは、WSLからPhpStormなんかを立ち上げて読み書きしているんだが、日本語入力ができないと何かと不便なので、WSLのシェルスタートアップ時にインプットメソッドのfcitxを起動するようにしている。
と、起動すると、「ディスプレイに接続できない」だの、「dbus-launchが異常終了して初期化できない」だの、思ってたのと違う状況に。
いろいろググりあげた結果、次のようにすることで解決した。
- ディスプレイに接続できない件は、DISPLAY環境変数の設定をlocalhostからresolv.confのアドレスに変えるQiitaの記事を参考にして解決
- dbus-launchが異常終了する件は、StackExchangeに同様のお悩みを抱えた方からの質問を参照して解決
2. どうしてこうなった
後追いでどうしてこうなったのか調べてみることに。
「WSLはAPI変換方式からマネージドVM方式に変わる」という話は小耳にはさんだことはあったのだけど、それがどういった影響があるのかまでは気にしていなかったのでいまさらなんだけど、ASCII.jpに懇切丁寧な解説記事があるのを発見。
記事を参照すると「WSL用の仮想スイッチが追加されている」ということなのでタスクマネージャーを見てみると、確かにvEthernet(WSL)というのが追加されている。
一方、WSL内部でifconfig
してみたところ、ネットワークアドレスは172.27.128.0/20のようだ。プリフィックス20とは広くとってんな、というのが正直な感想。
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.27.136.3 netmask 255.255.240.0 broadcast 172.27.143.255
inet6 fe80::215:5dff:fe7a:7ea1 prefixlen 64 scopeid 0x20<link>
ether 00:15:5d:7a:7e:a1 txqueuelen 1000 (イーサネット)
RX packets 2699 bytes 421846 (421.8 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 102 bytes 7288 (7.2 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (ローカルループバック)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ただ、「再起動するとアドレスは変わるので一定にならない」そうなので、この値はあくまで参考値ということになる。
早い話、Windowsホスト環境とWSL内部はvEthernetのアドレスを接点にNATされている、ということのようなので、件のQiitaの記事で書かれている/etc/resolv.conf
のnameserverのアドレスを指定するやり方で問題ない、ということのようだ。
一方StackExchangeで紹介されているdbus-launchだが、DESCRIPTIONの冒頭には
dbus-launch コマンドは、シェルスクリプトから dbus デーモンのセッションバスインスタンスを開始するために使用されます。
通常は、ユーザーのログイン スクリプトから呼び出されます。デーモン自体とは異なり、dbus-launch は終了するので、
バックティックや $() コンストラクトを使用して dbus-launch から情報を読み取ることができます。
引数を指定しない場合、dbus-launch はセッションバスインスタンスを起動し、そのインスタンスのアドレスと PID を
標準出力に出力します。
....とある。WSL内で実際に実行してみると、シェル変数定義を二つ返す。
$ dbus-launch
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-Xq7M2S9YAw,guid=f6f9e17a76a4f8db225fc4bd5ed2165b
DBUS_SESSION_BUS_PID=389
manpagesの記載によれば、Xセッションの開始時にこれらの変数定義がないと新しいセッションを開始するようになっていて、事前定義するなどでdbus-launchによる自動起動を回避できるようだ。
fcitxがdbusを使っているので、dbus-launch
の起動方法を工夫することはできるんだろうけど。
3. ところで使用感は
ざっくりこんなところ。
- DockerをWSL2バックエンドに変えたら、明らかに起動が速くなったうえ、ホスト環境へのパフォーマンス影響も体感的には相当改善された、気がする
- 従来のLXSSカーネルモジュールでの動作と比べ、Ubuntu Shellの起動は明らかに遅くなった
- メモリをもりもり食うようになった
※WSL2の起動で2GBほど、Dockerを加えると+1.8GB、これにコンテナが乗るとさらに増える、といった感じ
ところで、WSL2で使うことになったアドレス範囲を内部ネットワークですでに使っている場合、どうなるんだろう?
最近のコメント