WSL2/Dockerのトラブル治療室

# 初めに
こんにちは、システムヒーラーもやっている @CinTAKE です。

- 改定
    - 2025/06/04:WSLのリセット方法を追記

WSL2は新しいツールであるため、未知の問題が発覚したり、既知であるが対処法が固まっておらず未修正のままの問題がある。その中から重大なものを取り上げ、原因や治療法を解説する。

# 事例と治療法

## WSLが停止してもすぐ自動起動してくる

### 前提
- 発生時期： 2025年6月
- バージョンおよび確認方法：
- (マシンスペック：)
### 現象
　``` wsl --shutdown ``` を実行してWSLを停止すると、一時的に停止するが、１分も待たずに再起動されてしまう。

```cmd
C:\home> wsl --shutdown

:REM 直後の状態
C:\home> wsl -l -vvv
  NAME      STATE           VERSION
* Ubuntu    Stopped         2

:REM 数十秒経過後
PS C:\home> wsl -l -vvv
  NAME      STATE           VERSION
* Ubuntu    Running         2
```
 
### 原因

　VSCodeが起動していると、こいつがWSLの停止を検知して再起動してくれているらしいとの情報あり。 [Redditの記事](https://www.reddit.com/r/wsl2/comments/10ocx0y/wsl2_restarting_after_shutdown/)

### 治療
　VSCodeを停止して様子を見る
 
### 結果と予防
　見事、停止した。

 ```cmd
C:\home> wsl --shutdown

:REM 何分経っても停止状態のまま
C:\home> wsl -l -vvv
  NAME      STATE           VERSION
* Ubuntu    Stopped         2
 ```

## WSLがフリーズ状態なのでリセットしたい

### 前提
- 発生時期：2023年秋
- バージョンおよび確認方法：
- (マシンスペック：)
### 現象
- bashなど、WSLのDistroを起動しても反応がない

### 原因
WSL自体がフリーズしていると想定される。

### 治療
以下のスクリプトを```resetWsl.ps1```というファイル名で作成し、パスの通る場所(本シリーズの環境を使っている場合は、C:\opt\bin\ など)に配置して呼び出すことで、リセットできる。

```powershell
# :resetwsl.ps1

$scriptBlock = {
    Write-Host "Restarting WSL2"
    taskkill /f /im wslservice.exe /im wslhost.exe /im wsl.exe
    wsl --shutdown
    sleep 3
    powershell -Command "{Get-Service LxssManager|Restart-Service}"
    sleep 3
    Write-Host "Restarted WSL2"
}

sudo powershell -Command "& { $scriptBlock }"

bash
```

### 結果と予防
使用しない場合はWSLから抜けて ``` wsl --shutdown ``` しておく。

## マシンのメモリーを使い果たしてしまって、WSL2以外のアプリが動かなくなる

### 前提
- 発生時期：2021年卯月
- バージョンおよび確認方法：下記に記載
- マシンスペック：下記に記載

```text
[WSL]
10.0.19041.867
[Windows]
WindowsProductName WindowsVersion OsHardwareAbstractionLayer
------------------ -------------- --------------------------
Windows 10 Pro     2009           10.0.19041.844
[CPU]
CsNumberOfLogicalProcessors CsNumberOfProcessors CsProcessors
--------------------------- -------------------- ------------
                          8                    1 {Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz}
[Nemory]
CsTotalPhysicalMemory
---------------------
          21327122432
```

```powershell
# 情報取得：PowerShellにて、以下のコマンドを実行
(Get-Command wsl).FileVersionInfo.ProductVersion
Get-ComputerInfo | select WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer
Get-ComputerInfo -Property "*processor*"
Get-ComputerInfo -Property CsTotalPhysicalMemory
```

### 現象
- マシンのメモリがほぼ(98%)使い果たされてしまう。[^1]
- 「Vmmem」というプロセスが80%近いメモリーを使用している。[^2]

### 原因
以下の記事に書いてあった。 @yoichiwo7 さん、ありがとう。
結論から言うと、WSL初期設定とLinuxのメモリー利用方針の相互作用で発生していた。

- デフォルト設定のWSLは、メモリーを自動拡張して使用し、上限は80%
- Linux側はメモリーの空きをファイルキャッシュなどに割当てる
- 完全なフリーエリアが極小となり、マシンメモリを使い果たす

https://qiita.com/yoichiwo7/items/e3e13b6fe2f32c4c6120

### 治療
対症療法ではあるが、治療法も記事にあり、メモリー自動拡張をやめ、さらにSWAPも無効にするとよいとのこと。以下のように、「.wslconfig」というWSL設定ファイルを作成・修正する。

```powershell
sakura $ENV:Userprofile/.wslconfig
```
以下がファイルの内容。物理メモリー(20G)の60%程度を指定し、swapは4Gとした。これは、自分のマシンと使用状況により調節することになる。なお、設定値などの詳細は、[MS: WSL での詳細設定の構成](https://learn.microsoft.com/ja-jp/windows/wsl/wsl-config)を参照。

```text
[wsl2]
memory=12GB
swap=4G
# swapFile=%USERPROFILE%\\AppData\\Local\\Temp\\swap.vhdx
# safeMode=true
# https://learn.microsoft.com/ja-jp/windows/wsl/wsl-config
# Enable experimental features
[experimental]
autoMemoryReclaim=gradual
```

- experimental の項目
    - autoMemoryReclaim: <dropCache|gradual> CPUアイドル時、キャッシュメモリを自動解放

### 結果と予防
メモリー使用量は劇的に減り、初期状態での「Vmmem」は約2.2Gのみとなった。VSCodeでDocker開発した場合でも、9G程度であり、食い尽くすことはなくなった。
このままだと、複数コンテナを起動するときに、メモリー不足になることも想定できる。定期的にモニターしておいて、リソースプランニングすればいいのだが、適当なツールが思いつかず、当面はタスクマネージャを手動で起動て監視し、割当量を調整することとする。

## bashでスクリプトが異常動作する
### 前提
- 発生時期：2021年卯月
- バージョンおよび確認方法：下記に記載

```text
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
. . . . .

Linux LAPTOP-4SVL7A92 5.4.72-microsoft-standard-WSL2 #1 SMP Wed Oct 28 23:40:43 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
. . . . .
```

```bash
# 情報取得：bashにて、以下のコマンドを実行
bash --version
uname -a
cat /etc/os-release
```

### 現象
bashスクリプトを実行すると、以下のようなエラーとなる。

```bash
: No such file or directory
```

### 原因
「set -xe」で実行するも原因特定できず、別のスクリプトを試していると、以下のようなエラーが出た。

```bash
bash: /usr/bin/systemctl: /usr/bin/bash^M: bad interpreter: No such file or directory
```
改行コードが問題であった。
<details><summary>初心者向けの詳細説明</summary>文字列の改行を制御する「改行コード」は、扱っている言語やOSなどで違いがあり、表示は同じに見えても内部コードとしては異なっている事がある。今回のbashスクリプトも、改行コードの違いで動作しなかった。よく遭遇する代表例としては、Windows(MS-Dos)系とLinux(*nix/BSD...)系の違いであり、それぞれAscii/UTF-8の文字セットではWindows系がCR+LF(16進数で0D0A)、Linux系がLF(0A)となる。</details>

### 治療
Visual Studio Codeの設定を変更し、改行コードをLinuxと同じLFにする。[^3][^4]
Gitの設定も変える。(デフォルトではテキスト系の書類はpullするときに改行コードがOS標準に変換される)[^5]

### 結果と予防
無事動作するようになった。改行コードや行末の余分はスペースを表示する拡張機能を入れることで可視化し、再発防止に役立てる。

## WSL2 Docker が Windowsの C: ドライブを食い尽くして戻らない
### 前提
- 発生時期：2021年春
- バージョンおよび確認方法：下記
- マシンスペック： CドライブHDD：250G SSD

```powershell
PS C:\home> winver
# バージョン 20H2 (OSビルド 19042.1237)
PS C:\home> docker --version
Docker version 20.10.8, build 3967b7d
```
### 現象
C:ドライブの空き領域サイズが残り少なくなり、Docker領域が大きかったので、system prune などをして不要なイメージ等を削除。しかし、Docker領域が解放されず、ディスクの空き領域サイズに変化がない。？？？

### 原因
色々調べると[^6]、WSL2が仮想ディスクとして領域を抱え込んでしまい、自動的には解放してくれないとのこと、しかもその領域がC:ドライブで、サイズは250Gであることが判明。


### 治療
以下のリンクを参考に対処する、Windowsの環境やバージョンによって使える・使えないものがあるので、注意。なお、領域を変更するときに壊れる可能性もあるため、重要なデータはバックアップすること。

https://qiita.com/sarisia/items/5c53c078ab30eb26bc3b

https://qiita.com/siruku6/items/c91a40d460095013540d

<details><summary>その他参考リンク集</summary><div>

- https://7me.nobiki.com/2020/10/12/wsl2-docker-re-use-disk-space/
- https://dev.to/marzelin/how-to-reduce-size-of-docker-data-volume-in-docker-desktop-for-windows-v2-5d38
- https://www.curict.com/item/f4/f46da60.html
- https://marcroussy.com/2020/12/01/cleaning-up-docker-disk-space-in-wsl2/
- https://note.com/yulianess/n/n8d2b1a43369a
- https://blog.dreamhive.co.jp/mkoba/?p=4033
</div></details>

[MSの学習記事 How to manage WSL disk space](https://learn.microsoft.com/en-us/windows/wsl/disk-space)

### 結果と予防
無事に領域が戻ってきてC:ドライブの空領域サイズも増えたのだが、250GというWSL2領域サイズの指定自体を変える方法が見つからないので、時々メンテしてあげる必要が残っている。

# 終りに
困ったときほど、成長するチャンス。

親記事：[WSL2とVSCで作るWindowsでのDocker内開発環境(2021年睦月)](https://qiita.com/CinTAKE/items/ee348acec54195ef5bd1)

**テンプレート**

```
## 事象のタイトル
### 前提
- 発生時期：
- バージョンおよび確認方法：
- (マシンスペック：)
### 現象
### 原因
### 治療
### 結果と予防
```

[^1]: ![タスクマネージャ：パフォーマンス](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/1051adfb-ed51-e622-213c-50a4a6b91d73.png)

[^2]: ![タスクマネージャー：プロセス](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352975/5ecbc9a2-45fe-df66-0f8a-5b77453deb84.png)

[^3]: [VS Codeで改行コードを変更するには](https://www.atmarkit.co.jp/ait/articles/1809/14/news025.html)

[^4]: [改行コードの取り扱い [VSCode]](https://site-builder.wiki/posts/22953)

[^5]: [gitの改行コード自動変換でハマッた話（WindowsでもLFでチェックアウトする方法）](https://qiita.com/naoqoo2/items/dbc4f55d1ce0162d97a7)

[^6]: [Github:Microsoft/WSL でのイシュー](https://github.com/microsoft/WSL/issues/4699)