What'?
最近、やっとWSLを使い始めました。
あまり事前知識がなく、仮想マシンのように思っていたのですが実際に使ってみるとそんな気がしなかったので少し調べてみることにしました。
環境
今回の環境はこちらです。
PS > [System.Environment]::OSVersion
Platform ServicePack Version VersionString
-------- ----------- ------- -------------
Win32NT 10.0.26200.0 Microsoft Windows NT 10.0.26200.0
PS > $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
5 1 26100 7462
PS > wsl --version
WSL バージョン: 2.6.3.0
カーネル バージョン: 6.6.87.2-1
WSLg バージョン: 1.0.71
MSRDC バージョン: 1.2.6353
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.26100.1-240331-1435.ge-release
Windows バージョン: 10.0.26200.7623
準備
WSLディストリビューションとしては以下の準備をしておきます。
PS > wsl --install Ubuntu-24.04
PS > wsl --install Ubuntu-22.04
PS > wsl --install AlmaLinux-9
PS > wsl --list
Linux 用 Windows サブシステム ディストリビューション:
Ubuntu-24.04 (既定値)
AlmaLinux-9
Ubuntu-22.04
気になったこと
いくつか使っていて気になったことを書いてみます。
ディストリビューションを跨いでカーネルのバージョンが同じ
WSLではいくつかのディストリビューションを選べますが、どのディストリビューションを選んでもカーネルのバージョンが同じです。
PS > wsl -d Ubuntu-24.04 -e bash -c "cat /etc/os-release; echo; uname -srvmpio"
PRETTY_NAME="Ubuntu 24.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.3 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=noble
LOGO=ubuntu-logo
Linux 6.6.87.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
PS > wsl -d Ubuntu-22.04 -e bash -c "cat /etc/os-release; echo; uname -srvmpio"
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
Linux 6.6.87.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
PS > wsl -d AlmaLinux-9 -e bash -c "cat /etc/os-release; echo; uname -srvmpio"
NAME="AlmaLinux"
VERSION="9.7 (Moss Jungle Cat)"
ID="almalinux"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.7"
PLATFORM_ID="platform:el9"
PRETTY_NAME="AlmaLinux 9.7 (Moss Jungle Cat)"
ANSI_COLOR="0;34"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:almalinux:almalinux:9::baseos"
HOME_URL="https://almalinux.org/"
DOCUMENTATION_URL="https://wiki.almalinux.org/"
BUG_REPORT_URL="https://bugs.almalinux.org/"
ALMALINUX_MANTISBT_PROJECT="AlmaLinux-9"
ALMALINUX_MANTISBT_PROJECT_VERSION="9.7"
REDHAT_SUPPORT_PRODUCT="AlmaLinux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.7"
SUPPORT_END=2032-06-01
Linux 6.6.87.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
今回だと、どのディストリビューションを使っても以下のカーネルになっていますね。
Linux 6.6.87.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
これはWSLのバージョンを確認した時に表示されていたカーネルのバージョンです。
PS > wsl --version
WSL バージョン: 2.6.3.0
カーネル バージョン: 6.6.87.2-1
WSLg バージョン: 1.0.71
MSRDC バージョン: 1.2.6353
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.26100.1-240331-1435.ge-release
Windows バージョン: 10.0.26200.7623
起動しているプロセスが妙に少ない
ディストリビューション内で起動しているプロセスはかなり少なくなっています。
PS > wsl -d Ubuntu-24.04
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 12.4 0.2 21868 12516 ? Ss 20:49 0:00 /sbin/init
root 2 0.5 0.0 3120 2048 ? Sl 20:49 0:00 /init
root 6 0.0 0.0 3120 1792 ? Sl 20:49 0:00 plan9 --control-socket 7 --log-level 4 --server-fd 8 --pipe-fd 10 --log-truncate
root 42 4.6 0.2 42096 15616 ? S<s 20:49 0:00 /usr/lib/systemd/systemd-journald
root 95 3.5 0.0 24740 5760 ? Ss 20:49 0:00 /usr/lib/systemd/systemd-udevd
systemd+ 107 1.5 0.2 21456 12672 ? Ss 20:49 0:00 /usr/lib/systemd/systemd-resolved
systemd+ 108 0.5 0.1 91024 7680 ? Ssl 20:49 0:00 /usr/lib/systemd/systemd-timesyncd
root 111 0.1 0.0 25172 4656 ? S 20:49 0:00 (udev-worker)
root 112 0.0 0.0 24744 3120 ? S 20:49 0:00 (udev-worker)
root 113 0.1 0.0 24744 4272 ? S 20:49 0:00 (udev-worker)
root 114 0.1 0.0 24744 4108 ? S 20:49 0:00 (udev-worker)
root 115 0.3 0.0 24744 4424 ? S 20:49 0:00 (udev-worker)
root 116 0.0 0.0 24744 3516 ? S 20:49 0:00 (udev-worker)
root 117 1.1 0.0 24744 5208 ? S 20:49 0:00 (udev-worker)
root 119 0.0 0.0 24744 3580 ? S 20:49 0:00 (udev-worker)
root 120 0.3 0.0 24852 5096 ? S 20:49 0:00 (udev-worker)
root 121 0.0 0.0 24744 3204 ? S 20:49 0:00 (udev-worker)
root 122 0.0 0.0 24848 4584 ? S 20:49 0:00 (udev-worker)
root 123 0.0 0.0 24744 3716 ? S 20:49 0:00 (udev-worker)
root 124 0.0 0.0 24744 3204 ? S 20:49 0:00 (udev-worker)
root 126 0.0 0.0 24744 3464 ? S 20:49 0:00 (udev-worker)
root 127 0.5 0.0 24900 4528 ? S 20:49 0:00 (udev-worker)
root 128 0.0 0.0 24744 3208 ? S 20:49 0:00 (udev-worker)
root 134 0.1 0.0 24744 3592 ? S 20:49 0:00 (udev-worker)
root 135 0.3 0.0 24744 3848 ? S 20:49 0:00 (udev-worker)
root 136 0.0 0.0 24744 3212 ? S 20:49 0:00 (udev-worker)
root 139 0.0 0.0 24744 3852 ? S 20:49 0:00 (udev-worker)
root 140 0.0 0.0 24744 3216 ? S 20:49 0:00 (udev-worker)
root 144 0.0 0.0 24744 3608 ? S 20:49 0:00 (udev-worker)
root 145 0.0 0.0 24744 3996 ? S 20:49 0:00 (udev-worker)
root 146 0.0 0.0 24744 3228 ? S 20:49 0:00 (udev-worker)
root 152 0.0 0.0 4236 2560 ? Ss 20:49 0:00 /usr/sbin/cron -f -P
message+ 153 0.8 0.0 9592 4992 ? Ss 20:49 0:00 @dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
root 161 6.6 0.5 1847452 31488 ? Ssl 20:49 0:00 /usr/lib/snapd/snapd
root 162 1.2 0.1 17960 8320 ? Ss 20:49 0:00 /usr/lib/systemd/systemd-logind
root 164 3.4 0.2 1755840 12416 ? Ssl 20:49 0:00 /usr/libexec/wsl-pro-service -vv
root 167 0.1 0.0 3160 1920 hvc0 Ss+ 20:49 0:00 /sbin/agetty -o -p -- \u --noclear --keep-baud - 115200,38400,9600 vt220
syslog 173 1.2 0.0 222508 5248 ? Ssl 20:49 0:00 /usr/sbin/rsyslogd -n -iNONE
root 184 0.0 0.0 3116 1792 tty1 Ss+ 20:49 0:00 /sbin/agetty -o -p -- \u --noclear - linux
root 190 4.6 0.3 107028 22400 ? Ssl 20:49 0:00 /usr/bin/python3 /usr/share/unattended-upgrades/unattended-upgrade-shutdown --wait-for-signal
root 239 0.4 0.1 17280 7296 ? Ss 20:49 0:00 /usr/lib/systemd/systemd-timedated
root 282 0.0 0.0 3128 1024 ? Ss 20:49 0:00 /init
root 283 0.2 0.0 3144 1156 ? S 20:49 0:00 /init
xxxxxxx 284 0.8 0.0 6072 4992 pts/0 Ss 20:49 0:00 -bash
root 285 0.8 0.0 6692 4352 pts/1 Ss 20:49 0:00 /bin/login -f
xxxxxxx 330 3.5 0.1 20332 11008 ? Ss 20:49 0:00 /usr/lib/systemd/systemd --user
xxxxxxx 331 0.0 0.0 21148 3516 ? S 20:49 0:00 (sd-pam)
xxxxxxx 351 0.7 0.0 6056 4992 pts/1 S+ 20:49 0:00 -bash
xxxxxxx 389 0.0 0.0 8280 4096 pts/0 R+ 20:49 0:00 ps aux
ディストリビューションに入っていないと順次停止していく
ディストリビューション内に入っていないと、ディストリビューションが順次停止していきます(Running → Stopped)。
PS > wsl --list --verbose
NAME STATE VERSION
* Ubuntu-24.04 Stopped 2
AlmaLinux-9 Stopped 2
Ubuntu-22.04 Stopped 2
ApacheのようなDaemonプロセスをインストールして、systemdで起動していてもやっぱり停止しました。
$ sudo apt update && sudo apt install apache2
なので、ディストリビューション内にいたりして起動している間はいいのですが
PS > wsl --list --verbose
NAME STATE VERSION
* Ubuntu-24.04 Stopped 2
AlmaLinux-9 Stopped 2
Ubuntu-22.04 Running 2
PS > curl http://localhost
StatusCode : 200
StatusDescription : OK
Content : <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
Modified from the Debia...
RawContent : HTTP/1.1 200 OK
Vary: Accept-Encoding
Accept-Ranges: bytes
Content-Length: 10671
Content-Type: text/html
Date: Sat, 24 Jan 2026 11:55:38 GMT
ETag: "29af-64920ee0ad527"
Last-Modified: Sat, 24 Ja...
Forms : {}
Headers : {[Vary, Accept-Encoding], [Accept-Ranges, bytes], [Content-Length, 10671], [Content-Type, text/html]...}
Images : {@{innerHTML=; innerText=; outerHTML=<IMG class=floating_element style="HEIGHT: 146px; WIDTH: 184px" alt="Ubuntu Logo" src="icons/ubuntu-logo.png">; outerText=; tag
Name=IMG; class=floating_element; style=HEIGHT: 146px; WIDTH: 184px; alt=Ubuntu Logo; src=icons/ubuntu-logo.png}}
InputFields : {}
Links : {@{innerHTML=manual; innerText=manual; outerHTML=<A href="/manual">manual</A>; outerText=manual; tagName=A; href=/manual}, @{innerHTML=public_html; innerText=public
_html; outerHTML=<A href="http://httpd.apache.org/docs/2.4/mod/mod_userdir.html" rel=nofollow>public_html</A>; outerText=public_html; tagName=A; href=http://httpd.a
pache.org/docs/2.4/mod/mod_userdir.html; rel=nofollow}, @{innerHTML=existing bug reports; innerText=existing bug reports; outerHTML=<A href="https://bugs.launchpad.
net/ubuntu/+source/apache2" rel=nofollow>existing bug reports</A>; outerText=existing bug reports; tagName=A; href=https://bugs.launchpad.net/ubuntu/+source/apache2
; rel=nofollow}}
ParsedHtml : System.__ComObject
RawContentLength : 10671
しばらくすると停止してしまいます。
PS > wsl --list --verbose
NAME STATE VERSION
* Ubuntu-24.04 Stopped 2
AlmaLinux-9 Stopped 2
Ubuntu-22.04 Stopped 2
PS > curl http://localhost
curl : リモート サーバーに接続できません。
At line:1 char:1
+ curl http://localhost
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
エクスポートしたDockerコンテナをインポートできる
ちょっと驚きですが、DockerコンテナをエクスポートしてWSLディストリビューションとしてインポートできます。
やたら起動が速く、リソース消費が少ない
仮想マシンのようなとらえ方をしていると、やたら起動が速く感じます。
ディストリビューション間で見えるリソースが同じ?
どうもディストリビューション間で見ているリソースが同じような気がします。
## Ubuntu-24.04
$ nproc
4
$ free -h
total used free shared buff/cache available
Mem: 5.8Gi 573Mi 4.6Gi 16Mi 782Mi 5.2Gi
Swap: 2.0Gi 0B 2.0Gi
## Ubuntu-22.04
$ nproc
4
$ free -h
total used free shared buff/cache available
Mem: 5.8Gi 411Mi 4.6Gi 16Mi 782Mi 5.2Gi
Swap: 2.0Gi 0B 2.0Gi
## AlmaLinux-9
$ nproc
4
$ free -h
total used free shared buff/cache available
Mem: 5.8Gi 569Mi 4.6Gi 16Mi 782Mi 5.2Gi
Swap: 2.0Gi 0B 2.0Gi
1Gのファイルを作成してcatしてみます。
## Ubuntu-24.04
$ dd if=/dev/zero of=testfile bs=1G count=1
$ cat testfile > /dev/null
すると面白いことに、全ディストリビューションのbuff/cacheに反映されます。
## Ubuntu-24.04
$ free -h
total used free shared buff/cache available
Mem: 5.8Gi 587Mi 3.6Gi 12Mi 1.8Gi 5.2Gi
Swap: 2.0Gi 0B 2.0Gi
## Ubuntu-22.04
$ free -h
total used free shared buff/cache available
Mem: 5.8Gi 414Mi 3.6Gi 12Mi 1.8Gi 5.2Gi
Swap: 2.0Gi 0B 2.0Gi
## AlmaLinux-9
$ free -h
total used free shared buff/cache available
Mem: 5.8Gi 586Mi 3.6Gi 12Mi 1.8Gi 5.2Gi
Swap: 2.0Gi 0B 2.0Gi
またddコマンドの実行中は全ディストリビューションのavailableが減っていくのでおもしろいです。
今回はメモリを見ましたが、CPU使用率も同じようにディストリビューション間で共有されているような挙動をします。
systemdを特別扱いしている
systemdをサポートするためのパラメータがあります。
[boot]
systemd=true
WSLを仮想マシンのように思っていると、「どうしてわざわざ?」という感覚になります。
印象?
こういう動作を見ていると、どこか既視感があります。「Dockerっぽい」んですよね。
ディストリビューションを停止してもストレージに保存した内容がなくなったりはしませんし、あくまで「Dockerを連想する」だけでこれはDockerだなとは思いませんけれど。
ただ、最初は仮想マシンのように考えていたのでギャップと既視感からこう思うようになりました。
WSLのドキュメントに戻る
というわけで、WSLのドキュメントをあらためて見てみましょう。
なんとなく先入観で仮想マシンのように思っていましたが、ドキュメントの1行目から仮想マシンだなんて言っていません。
Windows Subsystem for Linux (WSL) を使用すると、開発者は GNU/Linux 環境 (ほとんどのコマンド ライン ツール、ユーティリティ、アプリケーションを含む) を Windows 上で直接実行でき、従来の仮想マシンやデュアルブートセットアップのオーバーヘッドは発生しません。
「Windows Subsystem for Linux とは」ページを見ても、やっぱり仮想マシンとはちょっと違いそうです。
Windows Subsystem for Linux (WSL) は Windows の機能であり、別の仮想マシンやデュアル ブートを必要とせずに、Windows マシンで Linux 環境を実行できます。
このページ内のWSL2の説明を見ると、ほぼ答えが書いていますね。
WSL 2 では、仮想化テクノロジを使用して、軽量ユーティリティ仮想マシン (VM) 内で Linux カーネルを実行します。 Linux ディストリビューションは、WSL 2 マネージド VM 内の分離コンテナーとして実行されます。
WSL自体は仮想マシンを実行するものの、その中で起動するLinuxディストリビューションはコンテナとして実行されるようです。
このあたりなんてDockerを連想しますよね。
WSL 2 を介して実行される Linux ディストリビューションは、同じネットワーク名前空間、デバイス ツリー (/dev/pts以外)、CPU/カーネル/メモリ/スワップ、/init バイナリを共有しますが、独自の PID 名前空間、マウント名前空間、ユーザー名前空間、Cgroup 名前空間、および init プロセスがあります。
WSL全体の設定ファイルである.wslconfigでは、たとえばmemoryパラメータが「WSL 2 VM に割り当てるメモリの量。」と説明してあったりWSLで使われる仮想マシンの存在が見えています。
WSLのコンポーネントの概要はこちら。
ここからWSLのオープンソースドキュメントサイトをたどってみましょう。
ブートプロセスを見ると、wslservice.exeがWSLの仮想マシンを扱うことがわかります。
WSL仮想マシンで最初に起動するのはmini_initプロセスです。
そしてWSLディストリビューション(Linuxディストリビューション)を開始するにはmini_initを介してinitを呼び出します。
こちらがWSLのアーキテクチャ概要です。
こちらの図を見るとここまでの関係性がわかりやすいですね。
こう見るとWSLディストリビューションを複数起動してもそこまでリソースは使わないのではと思ったのですが、ディストリビューションを増やしていくとVMmemWSLのメモリ消費量が目に見えて上がっていくのでDockerコンテナの感覚で増やしていくのはやめた方がよさそうです。
WSLとHyper-V
ドキュメントにはあまり出てきませんが、FAQではWSLはHyper-Vを使用していることが書かれています。
具体的には、WSL2 では、次の 2 つの機能を有効にする必要があります。
- "仮想マシン プラットフォーム" (Hyper-Vのサブセット)
- "Linux 用 Windows サブシステム"
WSL の最新バージョンでは、Hyper-V アーキテクチャの サブセット を使用して仮想化を有効にします。 このサブセットは、すべてのデスクトップ SKU で使用可能な "仮想マシン プラットフォーム" という名前のオプション コンポーネントとして提供されます。
- Windows Subsystem for Linux についてよく寄せられる質問 / WSL 2 / WSL 2 は Windows 10 Home と Windows 11 Home で使用できますか?
- Windows Subsystem for Linux についてよく寄せられる質問 / WSL 2 / WSL 2 は Hyper-V を使用しますか?
PS > Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V –All
ただ、サブセットと書かれているようにHyper-Vの仮想マシンとして動作しているかどうかはちょっとわかりませんでした。
「Windowsの機能の有効化と無効化」でHyper-Vにまったくチェックが入っていなくてもWSLは使えますし、Hyper-Vを有効にしてGet-VMコマンドを使ってもWSLの仮想マシンは一覧には現れませんでした。
じゃあどうやって確認すればよいかというと、hcsdiag listというコマンドで確認できます。
PS > hcsdiag list
6E65A261-2E6C-4ED0-9124-65C1A875467D
VM, Running, 6E65A261-2E6C-4ED0-9124-65C1A875467D, WSL
この「WSL」というVMは、WSLディストリビューションが複数起動しても数は増えません。
これはHost Compute System(HCS)の機能で作られる仮想マシンのようです。
The WSL2 virtual machine is created via the Host Compute System (HCS) service (see src/windows/service/exe/WslCoreVm.cpp).
使用しているAPIはこちら。
これはWSLのブートプロセスのドキュメントから追うことができます。
まとめ
「WSLは仮想マシンではないのか?」という疑問から見ていってみましたが、結論としては
- WSL自体はHyper-Vのサブセットを使った仮想マシンをバックエンドに使っている
- この仮想マシンは利用者にはあまり見えない
- 利用者が実際に操作するWSLディストリビューションは仮想マシン内で起動しているコンテナプロセス
という感じでしょうか。
