263
201

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

WSL2で困ったときに使う魔法の呪文

Posted at

絶対だいじょうぶだよ

image.png

引用:Windows 7、Linuxのリーナス・トーバルズも太鼓判

みなさん。WSL2使ってますでしょうか。
WSL2とは2019年5月に「Build 2019」で発表された、Windows Subsystem for Linuxのアップデート版です。
ざっくりというとMS公式が作ったWindows上で動くLinuxです。
正直、こういうものは昔からあり、眉唾ものだったのですが、WSL2あたりから、dockerが正常に動作するようになり、開発環境として常用するようになりました。
そこで、私が半年使ってきた中で、WSL2関連でどういう問題が発生したのか、どういう解決をしたのか。そのあたりを紹介したいと思います。

それらの問題は、大体1つの魔法の呪文でなんとかなります。

> wsl --shutdown

apt-getが失敗する

ピーリカピリララ ポポリナペーペルト!

なんかapt-getが失敗する

というすごいざっくりとした現象が起こることがあります。
パッケージがないのでは?と思いますが、apt-cache searchをやってもパッケージが存在する。そして、apt-getを行ったら、たまに起こるパッケージの破損でもない。そんな時は、

> wsl --shutdown

をすれば直ることがあります。
原因は何か?というと、WSL2の時刻のずれです。時刻がずれていると、apt-getが失敗するそうです。

Ubuntu 18.04LTSで # apt update 失敗 → 設定変更により、修正完了

これは、私のユースケースかもしれませんが、ノートパソコンでWSL2を動かしていました。そのため、ちょこちょことスリープ状態にすることがあり、そこから復帰したときに、失敗することが多かったです(おそらく、電池が切れそうになりPCの動作が極限まで落ちて、WSL2上の時計が止まる?)。そのため、WSL2自体を再起動することで、時刻のリセットをかけ、直していました。

localhostが見えない 

ノボブヨ、オシ、ハシタワ、ドケダ、グンミーチャ、デー、リブラ!

さて、最近ではdockerで開発することも多いと思います。

sudo docker run --rm -it -p 8000:80 ubuntu:latest

などポートフォワーディングをすることも多いと思います。しかし、localhost:8000をブラウザで見てみると表示されない。
実は、過去にWindows側からWSL上のサーバーへリクエストをする場合、設定が必要でした。

「WSL 2」最大の課題であった“localhost”問題が解決 ~「Windows 10」Build 18945
https://forest.watch.impress.co.jp/docs/news/1198651.html

しかし、そんなことは関係なく、localhostが見えない。という挙動です。
それ以外の理由だと、これだけだと、dockerのimageが壊れているのか?と思われるかもしれませんが、そうでない場合もあります。
WSL2上で、

$ curl localhost:8000

とすると、正常なレスポンスが返ってきます。意味が分からない。
ざっくりといいますと、WSL2とWindowsのネットワークのブリッジが悪い。
ということがあります。これは、WSL2上のポートの8000番はlistenしている状態なのですが、それをWindows側から見ると、8000番が閉じられており、疎通が取れない。ということがあります。
この話のやっかいなポイントとして、開発上3つぐらいポートをバインドしていたときに、1つだけポートがWindowsから見れない。といった中途半端にWSL2-Windows間のポートの疎通が死ぬ場合があり、プログラムのバグと判別がつきにくいことです。そのため、一度でもポートの疎通が取れない場合は、とりあえずWSL2上で、telnetやcurlをお勧めします。そして、WSL2上でレスポンスが返ってくるのに、Windows上から見えないときは、

> wsl --shutdown

です。

だんだん動作が遅くなる

オンキリキリバサラウンバッタ

これは非常にわかりにくいバグなのですが、**特定のコマンドを打った時にメモリリークする。**という挙動です。私の場合は、(おそらく)

sudo docker build

でした。2GB程度のDockerイメージを毎日ガシガシビルドして、動作を調整していた時期があるのですが、そういう作業をしていると、だんだんとWSL2のレスポンスが遅くなり、Chromeの検索窓の入力にもたついたりし始めました。タスクマネージャーを見るとDockerのイメージをビルドするたびにvmmemというプロセスの使用メモリが増えていき、ビルドを終了してもメモリが解放されない。という事象がありました。
入ってたウイルス対策のソフトがMcAfeeだと発生するというIssueがありましたが、別のウイルス対策を入れても、あまりメモリリークには関係ないように見えました。

こうなると、メモリ食いつぶすだけで、メモリの使用量の上昇を止める方法がないので、いつものやつです。

> wsl --shutdown

突然ディレクトリが見えなくなる

エロイムエッサイムエロイムエッサイム

WSL2上で、以下のコマンドを打ってみてください。

$ cd ~
$ explorer.exe .

そうすると、普通にエクスプローラーが起動します。

image.png

WSL2のキモイポイントですが、WSL2上のUbuntuのBashからWindowsのexeが普通に呼べます。
したがって、explorer.exeによって、Ubuntu上のフォルダの中身を閲覧することができます。
しかし、このフォルダは突然見えなくなることがあります。この場合だと、

「\wsl$\Ubuntu\home\kotauchisunsunのパスは存在しません。」

のようなエラーが発生することがあります。このエラーが出るタイミングがよくわからず、PCをスリープから復帰したタイミングというわけでもなく、割とランダムに1日1回ぐらいのペースででたりします。はい。直し方はわかりません。なので、

> wsl --shutdown

ファイルが突然なくなる

いあ!いあ!くとぅるふ ふたぐん!

これはWSL1の時代にあった話なのですが、WSL2でも応用できる面がありそうなので書いておきます。
題名は怖い内容ですが、いきなりファイルをぶっ壊すわけではありません。しかし、非常に困った挙動をする場合があります。
VueやReactなどの開発をしている場合、ファイルの変更を検知し、ホットリロードをかける場合があると思います。例えば、Vueの場合、

$ npx vue-cli-service serve

などです。
普通に開発をしてると、xxxx.js not Found.的なエラーが発生し、あれ?なんか間違って消したっけ?と思って、ls xxxx.jsとか打ってみると、普通に存在するわけです。lsでは見えるけども、ホットリロードからは見えなくなる的な割とやらしいバグが発生したりします。

この原因なのですが、おそらくWindows側のファイルシステムの方式により発生するバグだと思います。

image.png

画像元 Build 2019で見えた「Windows Subsystem for Linux 2」の詳細

WSL1からCドライブ配下のファイルを見るときにはDrvFsという方式で見ています。先ほどのファイルがなくなる現象が発生したときは、C:\配下にファイルを置いていたので、このDrvFsという形式でアクセスしており、おそらく、それが見えなくなる原因だったんだろうと思います。
それが、WSL2になり、C:\配下領域は9P、WSL2領域はext4で見るようになっています。

Windows10 Insider 18917 で WSL2 が来たので雑にボリュームマウントのベンチマークとってみた(追記あり)

参考記事を見てもらうとわかるのですが、**git cloneの場合、C:\配下やる場合と、~/でやる場合、前者の方が3倍程度遅いです。**これは、マウントしている方式の違いです。
先述したようにこの"ファイルが見えなくなるバグ"はWSL1の時に起きたバグで、WSL2では起きていません。理由としては、自分が、必ず~/配下にファイルを置くようにしたからで、/mnt/c/配下にファイルを置いていないからかもしれません。
なんやかんや/mnt/c/以下のフォルダに置く方がデバッグ効率や利便性が高かったりすると思いますが、

/mnt/c/以下だと9pの方式でマウントされ、それ由来のよくわからないバグをひく可能性があり、そもそもアクセス速度も遅いので、おとなしく~/以下にファイルを置く方が下手なバグにあたる可能性が低いです。

Dockerがrunできない

もう何も恐くない

すごい雑なことを言いますが、

WSL2上で実行するファイルをSourceTreeなどのWindowsのGitクライアントで管理しない方がいい

おとなしくコマンドラインのWSL2上のgitを使うことをお勧めします。
これは、同僚に「WSL2でとりあえず開発できるよ。」と言って、任せたのですが、どうも開発環境が動かない。という話をされました。挙動を聞くと、docker-composeが動かない。と言うのです。
そういうバグは何度かあたってきているのですが、普通にcheckoutしたばかりのファイルが動かない。ということは、どうも理屈に合わない。
以前、自分がdocker-composeが動かなかったときは、**dockerに含まれるファイルにCR+LFが改行コードが含まれていると動かない。という挙動でした。
で、話を聞いてみると、WindowsのGitでコードをチェックアウトした。という話でした。どうやら
改行コードをCR+LFに書き換えるGitクライアントがいるようです。**実際に、はまってらっしゃる方も居られます。

Windowsでcodeceptionをbuildする際は改行コードに注意

そのため、無用なバグで時間をつぶしたくない場合は、おとなしくWSL2のgitでコマンドラインでcheckoutをお勧めします。

感想

Windows上でネイティブのLinuxが動く。という思想自体、結構昔からありました。私が知っている中では、SUAですかね。

UNIX互換環境を実現するSUA(Subsystem for UNIX-Based Application)を利用する

LinuxはUnixじゃない!いや!SUAはPOSIXの認可を取っているから、実はWindowsはUnixなんだ!!みたいなめんどくさい話はあるんですが、当時は全然使いませんでした。私に使いこなせる技術力がありませんでした。
昔はMSはOSSからEvil的な扱いをされていましたが、本当に時代は変わるものです。
しかし、WSL2はいろいろ使いやすいです。Bash使えると本当に便利。

263
201
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
263
201

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?