0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WSLって仮想マシンじゃないの?

Last updated at Posted at 2026-01-24

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のアーキテクチャ概要です。

こちらの図を見るとここまでの関係性がわかりやすいですね。

image.png

こう見るとWSLディストリビューションを複数起動してもそこまでリソースは使わないのではと思ったのですが、ディストリビューションを増やしていくとVMmemWSLのメモリ消費量が目に見えて上がっていくのでDockerコンテナの感覚で増やしていくのはやめた方がよさそうです。

WSLとHyper-V

ドキュメントにはあまり出てきませんが、FAQではWSLはHyper-Vを使用していることが書かれています。

具体的には、WSL2 では、次の 2 つの機能を有効にする必要があります。

  • "仮想マシン プラットフォーム" (Hyper-Vのサブセット)
  • "Linux 用 Windows サブシステム"

WSL の最新バージョンでは、Hyper-V アーキテクチャの サブセット を使用して仮想化を有効にします。 このサブセットは、すべてのデスクトップ SKU で使用可能な "仮想マシン プラットフォーム" という名前のオプション コンポーネントとして提供されます。

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ディストリビューションは仮想マシン内で起動しているコンテナプロセス

という感じでしょうか。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?