はじめに
Windowsで開発環境を整えるとなったら
WSLを使ってUbuntuで〜Debianで〜
というケースがそれなりにあるのではないでしょうか?
今まで便利なものぐらいに思っていたのですが、
最近になってどういう理屈なんだろうかと気になり始めて調査をしました。
この記事では、
- Windowsの中でLinuxが動くって、どういうこと?
- 仮想マシン(VM)とは違うの?
- コンテナって聞くけど、これも関係あるの?
といった点を解説します。
まずは全体像:OSを動かす3つの方法
WSLを理解する前に、「別のOSを動かす方法」を整理しましょう。
大きく分けて3つの方法があります。
1. デュアルブート(物理的に分ける)
一番シンプルな方法です。
パソコンの電源を入れた時に「今日はWindowsで起動する?それともLinuxで起動する?」と選ぶ方式です。
起動時に選択
↓
┌─────────┐ または ┌─────────┐
│ Windows │ │ Linux │
└─────────┘ └─────────┘
ハードウェア
メリット: OSが直接ハードウェアを使うので高速
デメリット: 同時に2つのOSは使えない(再起動が必要)
2. 仮想マシン(VM:Virtual Machine)
パソコンを「ソフトウェアで再現」する方法です。
Windowsの中に「仮想的なパソコン」を作って、そこにLinuxをインストールします。
仮想マシンという名の通り、ハードウェア構成なども仮想で再現するものです。
┌─────────────────────────┐
│ Windowsアプリ │ VM │
│ │┌─────┐│
│ ││Linux││ ← 仮想パソコンの中で動作
│ │└─────┘│
├─────────────────────────┤
│ Windows OS │
├─────────────────────────┤
│ ハードウェア │
└─────────────────────────┘
メリット: WindowsとLinuxを同時に使える
デメリット: 「パソコンの中にパソコン」なので重い
3. コンテナ(軽量な仮想化)
VMよりも軽量な方法です。
OSの「カーネル」という核心部分だけを共有して、アプリケーションとその周辺環境だけを分離します。
┌────┐ ┌────┐ ┌────┐
│App1│ │App2│ │App3│ ← それぞれ独立
├────┤ ├────┤ ├────┤
│Libs│ │Libs│ │Libs│ ← 必要なライブラリだけ
└────┘ └────┘ └────┘
コンテナエンジン
───────────────
OSカーネル(共有) ← ここは共有
メリット: 軽量で起動が速い
デメリット: 完全に別のOSは動かせない(Linuxカーネル上でLinuxアプリのみ)
WSL 1:翻訳方式で動かす
それでは本題のWSLです。まずWSL 1から見ていきましょう。
WSL 1の仕組み
WSL 1は翻訳で動いています。
Linuxアプリが「Linux語」で話しかけてきたら、それを「Windows語」に翻訳してWindowsに伝える、という方式です。
┌─────────────────────────────────┐
│ Linuxアプリ │
│ 「ファイルを開いて!」 │
└──────────┬──────────────────────┘
│ Linux語で命令
↓
┌─────────────────────────────────┐
│ WSL翻訳レイヤー │
│ 「Windowsでファイルを開く │
│ 命令に変換するね」 │
└──────────┬──────────────────────┘
│ Windows語に翻訳
↓
┌─────────────────────────────────┐
│ Windowsカーネル │
│ 「了解、ファイル開くよ」 │
└─────────────────────────────────┘
例えるなら:
海外旅行で通訳さんがいるイメージです。あなた(Linuxアプリ)が英語で話しても、通訳さん(WSL翻訳レイヤー)が日本語に訳してくれるので、日本人の店員さん(Windowsカーネル)とコミュニケーションできます。
WSL 1の特徴:
- Linuxカーネルは不要(翻訳だけで動く)
- 起動が速い
- メモリをあまり使わない
- 翻訳できない命令がある(Dockerなど、カーネルに直接触る処理)
なぜ翻訳だけでは限界があったのか?
「翻訳」は便利ですが、問題もあります。
LinuxとWindowsでは「できること」が違うため、翻訳できない命令があります。
特に、Linuxカーネルに直接触る処理(Dockerやカーネルモジュール)は翻訳不可能でした。これがWSL 1の限界です。
WSL 2:本物のLinuxを軽量VMで動かす
そこで登場したのがWSL 2です。
WSL 2は「翻訳」をやめて、本物のLinuxカーネルを動かす方式に変わりました。
WSL 2の仕組み
┌────────────────────────────────┐
│ Windows 10/11 │
│ │
│ ┌──────────────────────┐ │
│ │ WSL 2 (Ubuntu等) │ │
│ │ ┌────────────────┐ │ │
│ │ │ Linuxアプリ │ │ │
│ │ ├────────────────┤ │ │
│ │ │本物のLinux │ │ │ ← 翻訳なし!
│ │ │カーネル │ │ │ 本物のLinuxが動く
│ │ └────────────────┘ │ │
│ └──────────────────────┘ │
│ ↕ │
│ ┌──────────────────────┐ │
│ │ Hyper-V │ │ ← これについては後で説明
│ │ (ハイパーバイザー) │ │
│ └──────────────────────┘ │
└────────────────────────────────┘
翻訳を使うのをやめて、「日本に住んでいる外国人」を呼んでくるようなものです。
その人は母国語を普通に話せますし、日本でも普通に生活できます。
WSL 2の特徴:
- 本物のLinuxカーネルが動く
- LinuxのすべてのAPIが使える(Dockerも動く!)
- Linuxとの互換性100%
- WSL 1より少しメモリを使う(でもVMよりは軽い)
「軽量VM」って何?
WSL 2は「軽量仮想マシン(Lightweight VM)」と呼ばれています。
普通のVMとは違う特別な設計です。
普通のVM vs WSL 2の軽量VM:
| 項目 | 普通のVM(VirtualBoxなど) | WSL 2の軽量VM |
|---|---|---|
| 起動時間 | 30〜60秒 | 2〜3秒 |
| メモリ | 最初に確保(例:4GB固定) | 必要な分だけ自動調整 |
| ディスク | 仮想ディスク作成が必要 | 自動で拡張 |
| ネットワーク | 設定が必要 | Windowsと自動統合 |
| ファイル共有 | 設定が必要 |
/mnt/cで自動アクセス可能 |
WSL 2は「すぐ起動、すぐ終了、メモリも節約」という、
普通のVMにはない軽快さがあります。
メモリ使用量の調整
WSL 2のメモリは自動調整されますが、上限を設定することもできます。
Windowsのユーザーフォルダに.wslconfigファイルを作成すると、メモリやCPUの上限を制御できます。
# C:\Users\<ユーザー名>\.wslconfig
[wsl2]
memory=4GB # メモリの上限
processors=2 # CPUコア数の上限
ハイパーバイザーって何? VMを動かす裏側の仕組み
さて、WSL 2の図に出てきた「Hyper-V(ハイパーバイザー)」について説明します。
ハイパーバイザーは「仮想マシンの管理人」
ハイパーバイザーは、1台のパソコンの中で複数の仮想マシンを動かすための管理ソフトです。
例えるなら:
マンションの管理人のようなものです。
1つの建物(パソコン)の中に複数の部屋(仮想マシン)があって、
それぞれの部屋に電気(CPU)、水道(メモリ)、ガス(ストレージ)を分配します。
┌──────────────────────────────────────┐
│ 1台のパソコン │
│ │
│ ┌─────┐ ┌─────┐ ┌────┐ │
│ │VM1 │ │VM2 │ │VM3 │ ← 複数のVMが動く
│ │Linux│ │Linux│ │Win │ │
│ └─────┘ └─────┘ └────┘ │
│ ↑ ↑ ↑ │
│ ┌──────────────────────┐ │
│ │ ハイパーバイザー │ ← リソースを分配
│ │ (Hyper-V) │ │
│ └──────────────────────┘ │
│ ↓ │
│ ┌──────────────────────┐ │
│ │ 物理ハードウェア │ │
│ │ (CPU/メモリ/SSD) │ │
│ └──────────────────────┘ │
└──────────────────────────────────────┘
ハイパーバイザーには2つのタイプがある
Type 1(ベアメタル型):
ハードウェアの上に直接インストールされるタイプです。
┌─────────┐ ┌─────────┐ ┌─────────┐
│ VM 1 │ │ VM 2 │ │ VM 3 │
└────┬────┘ └────┬────┘ └────┬────┘
└──────┬──────────┬─────┘
┌───────────────────────────────────┐
│ ハイパーバイザー (Hyper-V, ESXi) │ ← OSの下ではなく直接
└───────────────────────────────────┘
ハードウェア
- 高性能(OSを挟まないので)
- サーバーやクラウドで使われる
- Hyper-VやVMware ESXiが有名
Type 2(ホスト型):
通常のOSの上にアプリとしてインストールするタイプです。
┌─────────┐ ┌─────────┐
│ VM 1 │ │ VM 2 │
└────┬────┘ └────┬────┘
┌───────────────────────────────────┐
│ ハイパーバイザー (VirtualBox) │ ← アプリとして動く
├───────────────────────────────────┤
│ ホストOS (Windows等) │
└───────────────────────────────────┘
ハードウェア
- インストールが簡単
- 個人の開発用途向け
- VirtualBoxやVMware Workstationが有名
WSL 2が使うHyper-Vはちょっと特殊
WSL 2が使うHyper-Vの仮想化技術は、通常のHyper-Vとは少し異なる動作をします。
┌────────────────────────────────┐
│ ┌────────┐ ┌──────────┐ │
│ │Windows │ │WSL 2 │ │
│ │ │ │(Linux VM)│ │ ← どちらも同じレベルで動く
│ └────────┘ └──────────┘ │
├────────────────────────────────┤
│ Hyper-V ハイパーバイザー │ ← この上で全部動く
├────────────────────────────────┤
│ ハードウェア │
└────────────────────────────────┘
実は、Hyper-Vを有効にすると、Windows自体もHyper-Vの上で動くようになります。
そのため、WindowsとWSL 2のLinuxが「兄弟」のような関係で、同レベルで動かせます。
これが「軽量で高速」の秘密です。
厳密に言うと・・・その①
ハイパーバイザーとは
ハイパーバイザーとは、仮想マシン(VM)を実行・管理するための**仮想化レイヤの総称(概念)**です。
特定の製品名を指すものではなく、アーキテクチャ上の役割を表す用語です。
ハイパーバイザーは一般に以下の2種類に分類されます。
-
Type-1(ベアメタル型)
- ハードウェア上で直接動作する
- OSよりも低いレイヤに存在する
-
Type-2(ホスト型)
- 既存のホストOS上でアプリケーションとして動作する
厳密に言うと・・・その②
Hyper-Vとは
Hyper-V は、Microsoft が提供する Type-1(ベアメタル型)ハイパーバイザーの具体的実装です。
Windows の機能として提供されていますが、アーキテクチャ上は
「Windows の上で動作する仮想化ソフト」ではありません。
Hyper-V を有効化すると、
- ハードウェアの直上に Hyper-V が配置され
- Windows 自身も Hyper-V 上の 管理用パーティション(root partition) として動作します
つまり、構造としては
- Windows の上で Hyper-V が動く
- Hyper-V の上で Windows が動く
という関係になります。
コンテナとVMの違いを理解しよう
「コンテナ」と「VM」、どちらもよく聞く言葉ですが、実は全然違うものです。順番に見ていきましょう。
仮想マシン(VM):パソコンを丸ごと再現
VMは、パソコンを丸ごとソフトウェアで再現したものです。
┌──────────────────────────────────┐
│ あなたのパソコン(ホスト) │
│ │
│ ┌────────────────────────┐ │
│ │ 仮想マシン(VM) │ │
│ │ ┌──────────────────┐ │ │
│ │ │ アプリ │ │ │
│ │ ├──────────────────┤ │ │
│ │ │ Linux OS全部 │ │ │ ← OS全体が入ってる
│ │ │ (カーネル含む) │ │ │
│ │ └──────────────────┘ │ │
│ └────────────────────────┘ │
│ ハイパーバイザー │
└──────────────────────────────────┘
例えるなら:
家の中にもう1軒、小さな家を建てるようなものです。
小さな家には玄関も台所もお風呂も全部あります。
VMの特徴:
- 完全に独立したOS(Linuxも、別のWindowsも動く)
- 強い分離性(セキュリティ的に安全)
- 起動が遅い(OSを立ち上げるから)
- メモリやストレージを大量に消費(OS全部を入れるから)
コンテナ:アプリと最小限の荷物だけ持ち歩く
コンテナは、アプリとそれに必要なファイルだけを分離したものです。
OSのカーネル(核心部分)は共有します。
┌──────────────────────────────────┐
│ Linuxパソコン │
│ │
│ ┌────┐ ┌────┐ ┌────┐ │
│ │App1│ │App2│ │App3│ │
│ │+Lib│ │+Lib│ │+Lib│ ← 必要な分だけ
│ └────┘ └────┘ └────┘ │
│ コンテナエンジン(Docker) │
│ ────────────────────────── │
│ Linuxカーネル(共有) │ ← カーネルは1つだけ
└──────────────────────────────────┘
例えるなら:
アパートのようなものです。
各部屋(コンテナ)は独立していますが、水道やガスの配管(カーネル)は共有しています。
コンテナの特徴:
- 起動が超高速(1〜2秒、小規模なコンテナの場合)
- メモリ消費が少ない(カーネルを共有するから)
- ディスク容量が少ない
- カーネルは共有なので、別のOSは動かせない
- Linuxカーネル上ではLinuxアプリのみ
- Windowsカーネル上ではWindowsアプリのみ
コンテナの起動時間について
「1〜2秒」は小規模なコンテナ(例:Alpine LinuxベースのNode.jsアプリ)の場合です。
大規模なアプリケーション(データベース、機械学習環境など)は、初回起動時に数秒〜数十秒かかることもあります。
それでもVMの起動時間(30秒〜数分)と比べれば、圧倒的に高速です。
なぜコンテナが軽いのか?
OSの構造を理解すると、理由が分かります。
OS全体の構成
┌────────────────┐
│ アプリ │ ← コンテナはここだけ持つ
├────────────────┤
│ ライブラリ │ ← コンテナはここだけ持つ
├────────────────┤
│ カーネル │ ← これは共有(持たない)
└────────────────┘
VMは「カーネル」まで含めたOS全体を持ちますが、コンテナは「アプリとライブラリ」だけ持ちます。だから軽いんです。
VMとコンテナの比較表
| 項目 | VM | コンテナ |
|---|---|---|
| 起動時間 | 30秒〜数分 | 1〜2秒 |
| メモリ消費 | 多い(GB単位) | 少ない(MB単位) |
| ディスク | 数GB〜数十GB | 数MB〜数百MB |
| 分離レベル | ハードウェアレベル | プロセスレベル |
| 分離の強度 | 非常に強い(完全分離) | カーネル共有のため相対的に弱い |
| 別のOS | 動く | 動かない |
| 用途 | 完全に別の環境が必要 | 同じOS上で軽く分離したい |
DockerとWSL 2の関係
さて、ここまでの知識を使って、「なぜWSL 2でDockerが動くのか?」を理解しましょう。
Dockerって何?
Dockerは、コンテナを作って動かすためのツールです。先ほど説明した「コンテナ」を実際に使うためのソフトウェアですね。
WindowsでDockerを動かす2つの方法
昔の方法(WSL 1時代):
┌────────────────────────────────┐
│ Windows │
│ │
│ ┌──────────────────────┐ │
│ │ Docker専用のLinux VM │ │ ← Docker専用のVM
│ │ ┌────────────────┐ │ │
│ │ │ Docker Engine │ │ │
│ │ └────────────────┘ │ │
│ └──────────────────────┘ │
│ │
│ ┌──────────────────────┐ │
│ │ WSL 1 (Ubuntu) │ │ ← WSLとDockerは別々
│ └──────────────────────┘ │
└────────────────────────────────┘
問題点:
- DockerとWSLが別々のVM
- メモリを2倍消費
- ファイル共有が複雑
今の方法(WSL 2時代):
┌────────────────────────────────┐
│ Windows │
│ │
│ ┌──────────────────────┐ │
│ │ WSL 2 (Ubuntu) │ │
│ │ ┌────────────────┐ │ │
│ │ │ Docker Engine │ │ │ ← WSL 2の中で動く!
│ │ ├────────────────┤ │ │
│ │ │コンテナ群 │ │ │
│ │ ├────────────────┤ │ │
│ │ │ Linuxカーネル │ │ │
│ │ └────────────────┘ │ │
│ └──────────────────────┘ │
└────────────────────────────────┘
メリット:
- WSL 2の中でDockerが動く(環境が1つに統合)
- メモリ節約
- 速い
なぜWSL 2だとDockerが動くの?
答えは簡単:WSL 2は本物のLinuxカーネルを持っているからです。
Dockerを動かすには、Linuxカーネルの特別な機能が必要です:
-
Namespaces(名前空間)
- プロセスやネットワークを「仕切り」で分ける機能
- 例:コンテナAとBが同じポート番号を使っても衝突しない
-
cgroups(コントロールグループ)
- CPUやメモリの使用量を制限する機能
- 例:「このコンテナはメモリ512MBまで」と制限
-
Union File System
- ファイルシステムを層(レイヤー)で重ねる機能
- 例:アプリのバージョンアップで変更した部分だけ追加
┌─────────────────────────────┐
│ WSL 1 │
│ 翻訳レイヤー方式 │
│ ❌ Linuxカーネルなし │
│ ❌ Namespaces使えない │ ← Dockerに必要な機能なし
│ ❌ cgroups使えない │
└─────────────────────────────┘
┌─────────────────────────────┐
│ WSL 2 │
│ 本物のLinuxカーネル │
│ ✅ Namespaces使える │ ← Dockerに必要な機能あり!
│ ✅ cgroups使える │
└─────────────────────────────┘
つまり、WSL 2は本物のLinuxだから、Dockerが普通に動くということです。
全体像のまとめ:3つの技術の関係
ここまで学んだ「VM」「コンテナ」「WSL」の関係を整理しましょう。
┌──────────────────────────────────────────┐
│ あなたのWindowsパソコン │
│ │
│ ┌────────────────────────────────┐ │
│ │ WSL 2 (Ubuntu) │ │
│ │ │ │
│ │ ┌──────────────────────┐ │ │
│ │ │ Docker Engine │ │ │
│ │ │ ┌───────┐ ┌──────┐ │ │ │
│ │ │ │コンテナ│ │コンテナ│ │ │ │ ← コンテナ(軽量)
│ │ │ │1 │ │2 │ │ │ │
│ │ │ └───────┘ └──────┘ │ │ │
│ │ └──────────────────────┘ │ │
│ │ ┌──────────────────────┐ │ │
│ │ │ Linuxカーネル │ │ │
│ │ └──────────────────────┘ │ │
│ └────────────────────────────────┘ │ ← WSL 2(軽量VM)
│ │
│ ┌────────────────────────────────┐ │
│ │ Hyper-V ハイパーバイザー │ │ ← VMを管理
│ └────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────┐ │
│ │ 物理ハードウェア │ │
│ └────────────────────────────────┘ │
└──────────────────────────────────────────┘
3つの技術の役割:
-
ハイパーバイザー(Hyper-V)
- 役割:仮想マシンを管理する「マンションの管理人」
- WSL 2を動かすために必要
-
WSL 2(軽量VM)
- 役割:Windowsの中でLinuxを動かす「軽い仮想マシン」
- 本物のLinuxカーネルを持つ
-
コンテナ(Docker)
- 役割:アプリを分離して動かす「軽量な箱」
- WSL 2のLinuxカーネルを使う
どう使い分ければいい?
実際の開発では、どれを使えばいいでしょうか?
シナリオ1:Linuxコマンドを使いたいだけ
おすすめ:WSL 2だけでOK
wsl
cd ~/my-project
python app.py
理由: シンプルで軽い。Dockerは不要。
シナリオ2:Node.jsやPythonの開発
おすすめ:WSL 2だけでOK
wsl
cd ~/my-project
npm install
npm run dev
理由: WSL 2の中で直接開発できる。
シナリオ3:データベースと一緒に開発したい
おすすめ:WSL 2 + Docker
# WSL 2の中でDockerを使う
docker run -d -p 5432:5432 postgres
npm run dev
理由: PostgreSQLやMySQLをコンテナで簡単に起動できる。
シナリオ4:チーム開発で環境を統一したい
おすすめ:WSL 2 + Docker
docker-compose up
理由: メンバー全員が同じ環境で開発できる。
よくある質問
Q1. WSL 1とWSL 2、どっちを使えばいい?
A. 基本的にはWSL 2がおすすめです。
理由:
- Dockerが動く
- Linuxとの互換性が高い
- ファイルI/Oが速い(Linuxファイルシステム上)
WSL 1を使うのは、特殊な事情(Windowsファイルシステムへの頻繁なアクセスが必要など)がある場合だけです。
Q2. VMとWSL 2、何が違うの?
A. WSL 2は「軽量に特化したVM」です。
| 項目 | 普通のVM | WSL 2 |
|---|---|---|
| 起動 | 遅い(30秒〜) | 速い(2〜3秒) |
| メモリ | 固定(例:4GB) | 必要な分だけ |
| 設定 | 複雑 | 簡単 |
| Windowsとの連携 | 難しい | 簡単 |
Q3. コンテナとVMの違いは?
A. コンテナの方が圧倒的に軽いです。
VM: OS全体を持つ(重い)
┌────────────┐
│ アプリ │
│ ライブラリ │
│ カーネル │ ← ここまで持つ
└────────────┘
コンテナ: アプリだけ持つ(軽い)
┌────────────┐
│ アプリ │
│ ライブラリ │ ← ここまで
└────────────┘
カーネルは共有 ← 持たない
Q4. 結局、何を覚えればいい?
A. この3つを理解すればOKです:
-
WSL 2は軽量なLinux VM
- Windowsの中でLinuxが動く
- 本物のLinuxカーネルを持つ
-
Dockerはコンテナを動かすツール
- アプリを軽量に分離できる
- WSL 2のLinuxカーネルを使う
-
Hyper-Vはハイパーバイザー
- VMを管理する基盤
- WSL 2を動かすために必要
おわりに
この記事では、WSLの仕組みを「VM」「コンテナ」「ハイパーバイザー」という3つの視点から解説しました。
重要なポイント:
- WSL 1は「翻訳」、WSL 2は「軽量VM」
- ハイパーバイザー(Hyper-V)はVMの管理人
- コンテナはVMより軽量(カーネルを共有するから)
- WSL 2は本物のLinuxカーネルを持つからDockerが動く
これらを理解すれば、エラーが起きた時の調査や、パフォーマンスチューニングがしやすくなります。
WindowsとLinuxの「いいとこ取り」ができるWSL 2を使って、快適な開発ライフを送りましょう!