「コンテナと仮想マシン(VM)はどう違うのか?」「Docker、VMware、WSLはそれぞれどう使い分ければよいのか?」――仮想化技術を学び始めると、必ずこの疑問にぶつかります。
この記事では、コンテナと仮想マシンのアーキテクチャの違いを根本から理解し、Docker・VMware・WSLの3つの技術を性能・セキュリティ・用途の観点で比較解説します。
仮想化技術の全体像を把握する
コンテナと仮想マシンを正しく比較するには、まず仮想化技術の全体像を理解することが重要です。仮想化とは、物理的なハードウェアリソースを論理的に分割・抽象化し、複数の環境を同時に実行する技術の総称です。
仮想化の3つのレベル
仮想化技術は、その抽象化レベルに応じて大きく3つに分類できます。
- ハードウェアレベルの仮想化(VM):ハイパーバイザーがハードウェアを仮想化し、完全なOSを含む仮想マシンを実行。VMware、Hyper-V、KVMが代表例
- OSレベルの仮想化(コンテナ):ホストOSのカーネルを共有しながら、プロセスを隔離して実行。Docker、Podman、LXCが代表例
- アプリケーションレベルの仮想化:JVMやWSLのように、特定のアプリケーション環境を仮想的に提供
それぞれの仮想化レベルには一長一短があり、用途に応じて使い分けることが重要です。
仮想マシン(VM)の仕組み
仮想マシンは、ハイパーバイザーと呼ばれるソフトウェアがハードウェアを仮想化し、その上で完全なゲストOSを動作させる技術です。
Type 1とType 2のハイパーバイザー
ハイパーバイザーは2種類に分類されます。
- Type 1(ベアメタル型):ハードウェア上に直接インストール。VMware ESXi、Microsoft Hyper-V、KVMが該当。サーバー用途で高い性能を発揮
- Type 2(ホスト型):ホストOS上で動作するアプリケーション。VMware Workstation、VirtualBox、Parallelsが該当。デスクトップ用途が中心
VMwareの構成例
VMwareを使った仮想マシンの作成は、GUIで操作することが一般的ですが、CLIでも可能です。
# VMware Workstationでの仮想マシン作成例(vmrunコマンド)
# 仮想マシンの起動
vmrun start /path/to/vm.vmx
# 仮想マシンの停止
vmrun stop /path/to/vm.vmx
# スナップショットの作成
vmrun snapshot /path/to/vm.vmx "backup-2026-03-27"
# スナップショットからの復元
vmrun revertToSnapshot /path/to/vm.vmx "backup-2026-03-27"
VMの大きな利点は、スナップショットによる状態の保存と復元が容易なことです。システム設定の変更前にスナップショットを取っておけば、問題が発生しても簡単にロールバックできます。
VMのリソース消費
仮想マシンは完全なOSを含むため、リソース消費が大きくなります。
# 典型的なVM1台のリソース使用量
# OS: Ubuntu Server 22.04
# メモリ: 最低1GB(実用的には2〜4GB)
# ディスク: 最低10GB(実用的には20〜40GB)
# 起動時間: 30秒〜2分
# 同一ホストでVM3台を稼働する場合
# メモリ: 6〜12GB(OS×3 + アプリ×3)
# ディスク: 60〜120GB
# CPUオーバーヘッド: 各VMのOS処理分
コンテナ(Docker)の仕組み
コンテナは、ホストOSのカーネルを共有しながら、プロセスレベルで隔離された環境を提供します。ゲストOSを持たないため、VMと比べて圧倒的に軽量です。
コンテナを支えるLinuxカーネル技術
Dockerコンテナは、以下のLinuxカーネル技術を組み合わせて実現されています。
- Namespace:プロセスID、ネットワーク、ファイルシステムなどを隔離
- cgroup(Control Groups):CPU、メモリなどのリソース使用量を制限
- Union File System:レイヤー構造のファイルシステムで、イメージの効率的な管理を実現
# コンテナのNamespaceを確認
docker run --rm alpine cat /proc/1/status | grep NSpid
# NSpid: 1 (コンテナ内ではPID 1として見える)
# ホスト側からコンテナのプロセスを確認
docker top my-container
# UID PID PPID CMD
# root 12345 12340 node index.js
# (ホスト側では通常のPIDが割り当てられている)
Dockerの構成例
# Dockerコンテナの起動
docker run -d --name my-app \
-p 3000:3000 \
--memory=256m \
--cpus=0.5 \
my-app:1.0.0
# リソース使用量の確認
docker stats my-app
# CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM %
# abc123 my-app 0.15% 45.2MiB / 256MiB 17.66%
# 同じアプリのコンテナを3台起動
docker run -d --name app-1 -p 3001:3000 --memory=256m my-app:1.0.0
docker run -d --name app-2 -p 3002:3000 --memory=256m my-app:1.0.0
docker run -d --name app-3 -p 3003:3000 --memory=256m my-app:1.0.0
# 3台合計でもメモリ768MB程度(VMなら6GB以上必要)
コンテナ vs VM:7つの観点で比較
コンテナと仮想マシンを7つの観点で詳しく比較します。
1. 起動速度
# コンテナの起動時間
time docker run --rm alpine echo "Hello"
# real 0m0.5s (約0.5秒)
# 仮想マシンの起動時間
# 一般的に30秒〜2分(OSの起動プロセスが必要)
コンテナはカーネルの起動が不要なため、ミリ秒〜数秒で起動します。VMはOSの起動プロセスを経るため、数十秒から数分かかります。
2. リソース効率
# 同一ホスト(メモリ16GB)でのアプリケーション密度
# VM方式:
# - 1台あたり2GB(OS 1GB + アプリ 1GB)= 最大7〜8台
# コンテナ方式:
# - 1台あたり256MB(アプリのみ)= 最大50〜60台
コンテナはゲストOSのオーバーヘッドがないため、同じハードウェアでより多くのアプリケーションを実行できます。
3. 隔離レベル
VMはハードウェアレベルで完全に隔離されるため、セキュリティの観点では優位です。コンテナはカーネルを共有するため、カーネルの脆弱性が全コンテナに影響する可能性があります。
# コンテナの隔離を強化する方法
docker run --rm \
--security-opt=no-new-privileges \
--cap-drop=ALL \
--read-only \
--tmpfs /tmp \
my-app:1.0.0
4. 可搬性
コンテナイメージはDockerfileで定義され、どの環境でも同じように動作します。VMイメージはサイズが大きく(数GB〜数十GB)、異なるハイパーバイザー間での互換性に制約があります。
5. ストレージ効率
# コンテナイメージのサイズ
docker images
# REPOSITORY TAG SIZE
# node 20-alpine 130MB
# golang 1.23 800MB
# alpine 3.19 7MB
# VMイメージのサイズ(典型例)
# Ubuntu Server 22.04: 2.5GB〜(最小インストール)
# Windows Server 2022: 10GB〜
6. ネットワーキング
# Dockerのネットワーク設定
docker network create my-network
docker run -d --name app --network my-network my-app
docker run -d --name db --network my-network postgres:16
# appコンテナからdbに「db」というホスト名でアクセスできる
# VMのネットワーク設定
# ブリッジ、NAT、ホストオンリーなどの設定が必要
# IPアドレスの管理がより複雑
7. ユースケース
それぞれの技術が適するユースケースをまとめます。
- コンテナが適する場面:マイクロサービス、CI/CDパイプライン、同一OSでの大量デプロイ、クラウドネイティブアプリケーション
- VMが適する場面:異なるOSの同時実行、強固な隔離が必要な環境、レガシーアプリケーションの実行、デスクトップ仮想化
WSLの位置付けと使い方
WSL(Windows Subsystem for Linux)は、Windows上でLinux環境を実行するための技術で、コンテナともVMとも異なる独自のアプローチを取っています。
WSL 2のアーキテクチャ
WSL 2は、軽量なHyper-V仮想マシン上で実際のLinuxカーネルを実行します。WSL 1がシステムコール変換層だったのに対し、WSL 2は完全なLinuxカーネル互換を実現しています。
# WSL 2のインストール
wsl --install
# 特定のディストリビューションをインストール
wsl --install -d Ubuntu-24.04
# WSLのバージョン確認
wsl -l -v
# NAME STATE VERSION
# Ubuntu-24.04 Running 2
# WSLのメモリ制限設定(.wslconfigファイル)
# %USERPROFILE%\.wslconfig
[wsl2]
memory=8GB
processors=4
swap=4GB
WSLとDockerの連携
WSL 2はDocker Desktop for Windowsのバックエンドとして使用されます。これにより、Windows上でネイティブに近い性能でDockerコンテナを実行できます。
# WSL 2上でDockerを使用
# Docker Desktopが自動的にWSL 2統合を設定
# WSL内からDockerコマンドを実行
docker run -d -p 3000:3000 my-app:latest
# Windowsのブラウザから http://localhost:3000 でアクセス可能
WSL vs VM vs コンテナの比較
# 起動時間の比較
# WSL 2: 約1〜3秒
# Docker: 約0.5〜2秒
# VMware VM: 約30秒〜2分
# メモリ使用量の比較(最小構成)
# WSL 2: 約300MB〜(カーネル + 最小ユーザーランド)
# Docker: 約10MB〜(アプリによる)
# VMware VM: 約1GB〜(フルOS)
実践:Docker Composeで複数サービスを構成する
コンテナの真価は、複数のサービスを組み合わせたときに発揮されます。VMでは各サービスごとにOSが必要ですが、コンテナなら軽量に複数サービスを連携できます。
Webアプリケーション構成例
# docker-compose.yml
services:
# フロントエンド(Next.js)
frontend:
build: ./frontend
ports:
- "3000:3000"
environment:
- API_URL=http://api:8080
depends_on:
- api
# APIサーバー(Express)
api:
build: ./api
ports:
- "8080:8080"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/mydb
- REDIS_URL=redis://cache:6379
depends_on:
- db
- cache
# データベース(PostgreSQL)
db:
image: postgres:16-alpine
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=mydb
# キャッシュ(Redis)
cache:
image: redis:7-alpine
volumes:
- cache-data:/data
volumes:
db-data:
cache-data:
# 起動
docker compose up -d
# 状態確認
docker compose ps
# 全サービスのログ確認
docker compose logs -f
# すべて停止
docker compose down
この4つのサービスをVMで構成すると、少なくとも4GB×4=16GBのメモリが必要です。コンテナなら合計1〜2GB程度で済みます。
まとめ:技術選択の判断基準
コンテナ、仮想マシン、WSLはそれぞれ異なる強みを持つ技術です。重要なのは優劣ではなく、目的に応じた適切な使い分けです。
- Dockerコンテナを選ぶ場面:マイクロサービスアーキテクチャ、CI/CDパイプライン、クラウドネイティブ開発、開発環境の統一
- 仮想マシン(VMware等)を選ぶ場面:異なるOSの同時実行、セキュリティ要件が厳しい環境、レガシーシステムの運用、デスクトップ仮想化
- WSLを選ぶ場面:Windows上でのLinux開発環境、Docker Desktopのバックエンド、LinuxツールチェーンのWindows統合
現代の開発現場では、これらの技術を組み合わせて使うことが一般的です。たとえば、開発者のWindows PCではWSL 2上でDockerを実行し、本番環境のクラウドではKubernetes上のコンテナで運用し、セキュリティ検証にはVMを使うといった使い分けが考えられます。
それぞれの技術の特性を理解した上で、プロジェクトの要件に最適な選択をしていきましょう。
関連記事
AIエージェント開発入門|自律型AIの仕組みと構築方法を解説【2026年版】
AI駆動コーディングワークフロー|Claude Code・Cursor・Copilotの実践的使い分け
プロンプトエンジニアリング上級編|Chain-of-Thought・Few-Shot・ReActの実践
APIレート制限の設計と実装|トークンバケット・スライディングウィンドウ解説
APIバージョニング戦略|URL・ヘッダー・クエリパラメータの使い分け
BIツール入門|Metabase・Redash・Looker Studioでデータ可視化する方法
チャットボット開発入門|LINE Bot・Slack Botの構築方法と活用事例
CI/CDパイプラインの基礎|継続的インテグレーション・デリバリーの全体像