コンテナ(containers)と仮想マシン(VMs)の違い - Docker入門の前に知る基礎
この記事で解決できること
- コンテナと仮想マシン(VM)が 何を仮想化しているのか を仕組みから区別できる
- 「なぜコンテナは軽くて速いのか」「なぜ VM は隔離が強いのか」を 理屈で 説明できる
- Docker に触る前に、どちらを使うべきか の判断軸が身につく
結論(先に要点)
- VM は ハードウェアごと 仮想化し、各 VM が独自の ゲスト OS カーネル を持つ
- コンテナは ホストのカーネルを共有 し、
namespaceとcgroupsでプロセスを隔離する - 軽さ・速さはコンテナ、隔離の強さは VM。用途で使い分ける(併用も一般的)
前提(対象環境)
- Linux ホスト(Ubuntu / RHEL 系いずれも考え方は同じ)
- コンテナは Linux コンテナ(Docker / Podman 等)を想定
- VM は KVM / VirtualBox / VMware 等のハイパーバイザ型を想定
コンテナと仮想マシンは何が違うのか?
結論: VM は OS まるごとを仮想化し、コンテナはアプリのプロセスだけを隔離する。仮想化する「層」が違う。
両者は「1 台のマシンで複数の環境を動かす」点では同じだが、仮想化する対象のレイヤーが違う。
| 観点 | 仮想マシン(VM) | コンテナ |
|---|---|---|
| 仮想化の対象 | ハードウェア(CPU/メモリ/NIC) | プロセス(OS リソースの見え方) |
| カーネル | VM ごとに独自のゲストカーネル | ホストカーネルを共有 |
| 起動時間 | 数十秒〜数分 | ミリ秒〜数秒 |
| イメージサイズ | 数 GB | 数 MB〜数百 MB |
| オーバーヘッド | ハイパーバイザ層の分だけ重い | ほぼネイティブ |
| 隔離の強さ | 強い(カーネルが別) | 中(カーネルを共有) |
| 異種 OS | 可能(Linux 上で Windows 等) | 不可(ホストと同じカーネル) |
VM は「物理マシンをまるごとソフトウェアで再現する」発想。コンテナは「同じ OS の上で、各アプリに専用の世界を見せる」発想だと捉えると整理しやすい。
なぜコンテナは軽量で速いのか?
結論: コンテナはホストのカーネルをそのまま使うため、OS を起動し直さない。だから速く、メモリも食わない。
コンテナの軽さの正体は カーネル共有 にある。VM が起動のたびにゲスト OS(カーネル + 初期化プロセス群)をブートするのに対し、コンテナは すでに動いているホストカーネルの上で、ただプロセスを 1 つ起動するだけ。
その「プロセスを隔離して、あたかも独立した OS に見せる」仕組みが Linux カーネルの 2 つの機能だ。
namespace(分離する)
namespace は、プロセスから見える OS リソースを 区切る 仕組み。種類ごとに見える範囲を分離する。
- PID: プロセス ID 空間(コンテナ内では自分が PID 1 に見える)
- mount: ファイルシステムのマウント状態
- network: ネットワークインターフェース・ルーティング
- UTS: ホスト名
- IPC: プロセス間通信
- user: UID/GID のマッピング
現在のホストの namespace は lsns で確認できる。
$ lsns
cgroups(制限する)
cgroups(control groups)は、プロセスが使える リソース量を制限・計測 する仕組み。CPU・メモリ・I/O などに上限を設けられる。
$ systemd-cgls
namespace は「見える範囲」、cgroups は「使える量」 この 2 つを組み合わせて、1 つのプロセスを「独立した OS のように」隔離したものがコンテナの実体。
仮想マシンはどんな仕組みなのか?
結論: VM はハイパーバイザがハードウェアを仮想化し、その上でゲスト OS をまるごと起動する。
VM は ハイパーバイザ(hypervisor)と呼ばれる層が、CPU・メモリ・ディスク・NIC といった ハードウェアを仮想化 する。ゲスト OS はそれが本物のハードウェアだと信じてブートする。
ハイパーバイザには大きく 2 種類ある。
- Type 1(ベアメタル型): ハードウェア直上で動く。KVM / Xen / VMware ESXi。サーバ・クラウドの基盤。
- Type 2(ホスト型): ホスト OS の上で動く。VirtualBox / VMware Workstation。手元の検証用。
ゲストごとに独立したカーネルが走るため、Linux ホスト上で Windows を、その隣で別バージョンの Linux を といった異種 OS の同居ができる。これはカーネルを共有するコンテナにはできない芸当だ。
隔離(セキュリティ)はどちらが強いのか?
結論: 隔離の強さは VM が上。コンテナはカーネルを共有するぶん、カーネルの脆弱性が全コンテナに波及しうる。
VM はゲストごとにカーネルが分かれているため、1 つの VM が侵害されても他の VM・ホストへ直接は波及しにくい。境界がハードウェア仮想化のレベルにある。
一方コンテナは ホストカーネルを共有 する。利点(軽さ)の裏返しで、カーネルに脆弱性があれば、コンテナからホストへ抜ける「コンテナブレイクアウト」のリスクが理屈上は残る。
コンテナは「軽量な VM」ではない。隔離レベルが異なるため、強い分離が要件なら VM、あるいは VM とコンテナの併用を検討する。
実務では、クラウド上で VM の中でコンテナを動かす 構成が一般的。VM で強い境界を確保しつつ、その内側でコンテナの軽さ・可搬性を活かす、いいとこ取りの形だ。
どちらを使うべきか?
結論: アプリのパッケージング・配布・高密度ならコンテナ、異種 OS・強い隔離・カーネル検証なら VM。
用途別の目安は次のとおり。
| やりたいこと | 向いている方 |
|---|---|
| アプリを環境ごとパッケージして配布 | コンテナ |
| マイクロサービス・CI/CD | コンテナ |
| 1 台に多数の環境を高密度に詰める | コンテナ |
| Linux 上で Windows など異種 OS を動かす | VM |
| 強い隔離・マルチテナント境界 | VM |
| カーネルモジュールや OS そのものの検証 | VM |
判断に迷ったら、こう問うと早い。
- ホストと同じカーネルで足りるか? → 足りるならコンテナが第一候補
- 異種 OS や独自カーネルが要るか? → 要るなら VM
- 隔離はどこまで厳しく要求されるか? → 厳しいほど VM(または VM 内コンテナ)
Docker入門の前に知っておくべきこと
結論: Docker は namespace と cgroups を使いやすく包んだツール。仕組みを知っていれば「魔法」ではなく理屈で読める。
Docker を触り始めると イメージ と コンテナ という言葉が出てくる。ここまでの仕組みと対応づけておくと混乱しない。
- イメージ: コンテナの「設計図」。アプリと依存をまとめた読み取り専用のテンプレート
- コンテナ: イメージから起動した「実行中のプロセス」。その正体は namespace と cgroups で隔離された Linux プロセス
つまり Docker は、ここで見た カーネル機能を人間が扱いやすい形に包んだ道具にすぎない。「コンテナ = 超軽量 VM」という誤解さえ手放せば、Docker のコマンドは素直に読めるようになる。
ここまでの理解で十分 「カーネルを共有し、namespace で分離、cgroups で制限」——この一文が頭に入っていれば、Docker 入門はスムーズに進む。