TL;DR
- 仮想マシン(VM) = パソコンの中に、もう1台パソコンを作る(マシンの仮想化)
- コンテナ = アプリを、動くのに必要なもの一式ごと箱に詰めて動かす(軽量仮想化)
- 決定的な違いは カーネル。VM は1台ごとに自分のカーネルを持ち、コンテナはホストのカーネルを 共有 する
- Docker はコンテナを作って管理する アプリケーション
1. 前提知識:カーネルとユーザーランド
OS は大きく2つに分かれます。
| 部分 | 役割 | 例 |
|---|---|---|
| カーネル | ハードウェア・メモリ・プロセスを管理する OS の中核 | Linux カーネル |
| ユーザーランド | カーネル以外のすべて(コマンド、ライブラリ、アプリ、設定ファイル) |
bash、ls、glibc、apt
|
CPU には カーネルモード と ユーザーモード という権限レベルがあり、ユーザーランドのプログラムはハードウェアを直接触れません。何かしたいときは システムコール という決められた窓口からカーネルに依頼します。
アプリ(ユーザーランド)
↓ システムコール(open, read, write …)
────────── 境界 ──────────
カーネル
↓
ハードウェア
こう分かれている理由は、1つのアプリのバグや悪意が OS 全体を壊さないようにするためです(銀行の客が金庫に直接入れず、窓口で頼むのと同じ)。
ユーザーランドの「ユーザー」は人間のアカウントのことではなく、「ユーザーモードで動く側」という意味です。複数アカウントは 同じユーザーランドを共有 していて、コンテナは ユーザーランドそのものが別 です。
また、Ubuntu と Alpine のような ディストリビューションの違いは、ほぼユーザーランドの違い です。カーネルは同じ Linux です。これがコンテナを理解する鍵になります。
2. 仮想マシン:マシンを仮想化する
仮想マシンは、名前のとおり OS ではなくマシン(コンピュータ本体)を仮想化 します。1974年に Popek と Goldberg は仮想マシンを「本物のマシンの、効率的で隔離された複製」と定義しました。
ハイパーバイザが仮想の CPU・メモリ・ディスク・NIC を作り、そこに OS を カーネルごと インストールします。VM そのものは「OS の入っていない空っぽのパソコン」なので、Linux でも Windows でも好きな OS を入れられます。
使う人の感覚:起動ロゴ → ログイン画面 → デスクトップ。「別のシステム(コンピュータを使っている)」感覚。
3. コンテナ:軽量仮想化
コンテナは、アプリを動くのに必要なもの一式(ユーザーランド)ごと箱に詰めて、ホストのカーネルの上で直接動かす 技術です。いわば 「なんちゃって仮想化」 のような感じです。
使う人の感覚:docker run nginx と打てば数秒で ホストとは隔離した環境でアプリケーションが動く。
名前の由来は貨物船の 輸送用コンテナ です。中身が何でも同じ規格の箱なので、ノートPCでもクラウドでも同じように運んで動かせます。
イメージとコンテナ
| 用語 | 意味 | たとえ |
|---|---|---|
| イメージ | アプリ+必要なファイル一式を固めた読み取り専用の型 | たい焼きの型 |
| コンテナ | イメージから作って実際に動いているもの | たい焼き |
同じイメージから何個でもコンテナを作れます。ファイルは overlayfs で共有され、書き込んだ差分だけが個別に保存される(コピーオンライト)ので、10個作っても容量は10倍になりません。
OS 丸ごとは要らない
コンテナに必要なのは、アプリが使うライブラリやファイルだけです。カーネルはホストから借ります。極端な例では、静的リンクした実行ファイル1つだけのイメージでも動きます。
ただし 借りるカーネルの種類は合っている必要がある ので、Linux 用コンテナは Linux カーネル上でしか動きません。
4. 構造の比較
| 観点 | 仮想マシン | コンテナ |
|---|---|---|
| 仮想化するもの | ハードウェア(マシン) | OS 資源の見え方 |
| カーネル | VM ごとに1つ | ホストのカーネルを共有 |
| 中身 | カーネル+ユーザーランド | ユーザーランドのみ |
| 起動時間 | 数十秒〜分 | 秒以下 |
| サイズ | 数 GB〜 | 数 MB〜数百 MB |
| 動かせる OS | 何でも | ホストと同じ種類のカーネルの OS |
| 隔離の強さ | 強い | やや弱い(カーネル共有のため) |
※ 起動時間・サイズは一般的な目安です。
5. なぜ「別々の OS」があるように見えるのか
コンテナは何かを「増やして見せる」のではなく、各プロセスに 見えるものを制限する ことで独立したマシンのように見せています。つまり、実際にはOSはホストのものを共通して使用しながら、あたかも個々にOSが用意されているように見えるかたちでコンテナ毎に各プロセスを隔離しています。
上で 「なんちゃって仮想化」 と書いたのはそのためです。
使われているのは Linux カーネルの2つの機能です。
- namespace:プロセス一覧、ファイルシステム、ネットワーク、ホスト名、ユーザーIDなどをコンテナごとに分ける
- cgroups:CPU やメモリの使用量を制限する
そのため、コンテナは中から見ると自分専用のマシン、ホストOSから見るとただのプロセスです。
確かめてみる
docker run --rm ubuntu cat /etc/os-release # → Ubuntu
docker run --rm alpine cat /etc/os-release # → Alpine
docker run --rm ubuntu uname -r # → ホストのカーネル
docker run --rm alpine uname -r # → 同じカーネル!
ユーザーランド(/etc/os-release)は違うのに、カーネル(uname -r)は同じ。これが軽量仮想化の正体です。
6. Docker とは
Docker は コンテナを作って管理するアプリケーション です。docker コマンド、デーモンの dockerd、実際にコンテナを起動する containerd や runc などで構成されています。
重要:Mac / Windows の Docker Desktop は VM を使っている
Mac や Windows には Linux カーネルがないため、Docker Desktop は裏で 軽量な Linux VM を1つ 起動し、その中で Docker Engine を動かします。
ただし VM は「カーネルを1つ用意するための土台」にすぎず、コンテナを10個起動しても VM は1つのままです。コンテナ同士の関係は Linux で直接動かす場合と同じです。
7. ハードウェア(カメラ・GPU)は使える?
使えますが、デフォルトでは隠されている ので明示的に許可します。
docker run --device /dev/video0 myapp # カメラを渡す
docker run --gpus all myapp # GPU を渡す(NVIDIA Container Toolkit が必要)
- ドライバは ホストのカーネル側 に必要(コンテナ内でドライバは入れられない)
- GPU は、ユーザーランドの CUDA ライブラリとカーネルの NVIDIA ドライバのバージョンを揃える必要があり、専用ツールがそれを橋渡しする
- Mac / Windows では間に VM が挟まるため、USB デバイスを渡すのは難しい(Windows では
usbipd-winで可能) -
--privilegedはほぼホストの root と同じ権限になるので、必要なデバイスだけ渡すのが基本
8. VM でも分割できるのに、なぜコンテナが使われるのか
| 時代 | 方法 | 課題 |
|---|---|---|
| 物理サーバー | 1台にアプリを直接載せる | 資源の奪い合い、サーバーを増やすと高コスト |
| 仮想化 | 1台を複数の VM に分割 | 分割ごとに OS 丸ごとの重さと管理が付いてくる |
| コンテナ | OS を共有してアプリを箱詰め | 隔離は VM より弱い |
コンテナが選ばれる主な理由は次の3つです。
- 軽くて速い:OS を複製しないので資源が少なく、起動は秒以下。同じサーバーに多く載せられる
- どこでも同じように動く:開発・テスト・本番で環境が一致し、「自分のPCでは動くのに…」が起きにくい
- 管理の単位がアプリになる:OS の面倒を見るのではなく「このアプリを動かす」ことに集中できる
VM とコンテナは対立するものではありません。クラウドでは VM で強い境界を作り、その中でコンテナを大量に動かす 構成が一般的です。
まとめ
- 仮想マシン:マシンを丸ごと仮想化。カーネルごと別の OS を動かせる。重いが隔離は強い
- コンテナ(軽量仮想化):アプリを必要なもの一式ごと箱詰めし、ホストのカーネルを共有して動かす。軽く・速く・どこでも同じに動く
- Docker:コンテナを作って管理するアプリケーション。Mac / Windows では Linux カーネルを用意するために VM を1つ使う
「別のマシン(コンピュータ)が欲しい」なら仮想マシン、「アプリを軽く動かしたい」ならコンテナ、と覚えておくと迷わないと思います。


