Tech Learning Daily

2026-07-25 (Sat) — 第 6 号
AI が毎朝届ける、ソフトウェア技術の基礎解説
Container 🌿 基礎 ⏱ 約 7 分

コンテナはなぜ VM より「軽い」のか? 手放しているものは何か

docker run は数秒でシェルに入れるのに、クラウドで新しい VM を 1 台立ち上げると起動完了まで数十秒〜数分待たされる。同じ「隔離された実行環境」のはずなのに、この差はどこから生まれるのか。そして「軽い」という言葉の裏で、コンテナは VM が持っていた何を手放しているのか。

🎯 3 行まとめ
  • VM はハイパーバイザー上にカーネルごとゲスト OS を丸ごと積むが、コンテナはホストのカーネルを他のコンテナと共有し、名前空間と cgroup でプロセスを区切るだけである
  • 軽さの正体は「新しいカーネルを起動しない」ことにあり、起動はプロセス起動と同程度に速く、イメージにもカーネルを含める必要がない
  • カーネルを 1 つ共有する代わりに隔離境界は弱く、macOS/Windows では結局 1 つの Linux VM を裏で起動してその中でコンテナを動かしている

VM — ハイパーバイザーの上に、もう一つのカーネルを積む

VM(仮想マシン)はハイパーバイザー(物理ハードウェアを仮想化し、複数のゲスト OS を並行して動かす基盤ソフトウェア)が仮想 CPU・仮想ネットワークカードなどの「仮想ハードウェア」を作り、その上でゲスト OS(VM 内で動く、独自のカーネルを持つ OS)を丸ごと起動する構成を取る。ゲスト OS は自分専用のカーネルを持つため、ホスト OS の種類に関わらず Linux でも Windows でも自由に選べる。

この構成の代償が起動コストだ。VM を 1 台立ち上げるたびに、ブートローダーからカーネル初期化までを含む OS の起動シーケンスを丸ごと 1 回実行する必要がある。イメージのサイズもカーネルとシステムライブラリ一式を含むため数百 MB〜数 GB になりやすい。

コンテナ — 名前空間で「見える範囲」を、cgroup で「使える量」を区切る

コンテナはゲスト OS を持たない。ホスト OS のカーネルをそのまま共有し、Linux カーネルの 2 つの機能だけで「隔離された環境らしく見せる」仕組みだ。1 つ目が名前空間(namespace)で、PID・ネットワーク・マウントポイント・ホスト名などについて「そのプロセスから何が見えるか」を区切る。PID 名前空間を分ければコンテナ内では自分が PID 1 に見え、ネットワーク名前空間を分ければ自分専用のネットワークインターフェースを持っているように見える。2 つ目が cgroup(control group)で、そのプロセス群が使える CPU・メモリなどのリソース量に上限をかける。

どちらもカーネルを新たに起動する処理ではない。この設定を実際に行うのが Docker や containerd といったコンテナランタイム(イメージから名前空間・cgroup を組み立ててコンテナプロセスを起動・管理するソフトウェア)で、コンテナ起動とは実質的には「ホストカーネル上で名前空間と cgroup を設定してから 1 個のプロセスを fork/exec する」だけの操作だ。この違いが起動速度とイメージサイズの両方に直結する。

VM
┌────────────────────┐
│App + Libs          │
│Guest Kernel        │
├────────────────────┤
│Hypervisor          │
├────────────────────┤
│Host OS / Host HW   │
└────────────────────┘

Container(Host Kernel を共有)
┌────────────────────┐
│App + Libs          │
├────────────────────┤
│Container Runtime   │
├────────────────────┤
│Host OS / Host HW   │
└────────────────────┘
🍱 たとえるなら

VM は敷地に一戸建てを何棟も建てるようなものだ。各棟が基礎・水道管・電気配線を自前で持ち、隣の工事の影響を受けない代わりに、1 棟ごとに丸ごとの建築期間がかかる。コンテナは 1 棟のマンションの各部屋に近い。壁(名前空間)で見える範囲を区切り、契約(cgroup)で電気・水道の使用量を制限するが、建物の基礎や配管そのものは 1 つ(ホストカーネル)を全戸で共有している。だから入居(起動)は一瞬で済むが、建物の基礎に亀裂(カーネルの脆弱性)が入れば全戸に影響が及びうる。

手放しているもの — カーネル 1 つを共有するリスク

VM の隔離はハイパーバイザーによるハードウェアレベルの仮想化に支えられており、ゲスト OS のカーネルがどれだけ壊れても、その影響は基本的に自分の VM の中に閉じる。一方コンテナは全員が同じホストカーネルの上で動いているため、そのカーネル自体の脆弱性は隔離の前提ごと崩す。例えば 2022 年に報告された CVE-2022-0492 は、cgroup v1 の release_agent という通知の仕組みを悪用し、コンテナ内の一般ユーザーでもホスト上で root 権限のスクリプトを実行できてしまう欠陥だった。名前空間で「見えない」はずのホストに、カーネルの穴を突いて到達できてしまう。

この種のリスクへの現実的な緩和策が seccomp(許可するシステムコールを絞る)や AppArmor・SELinux(プロセスの権限をポリシーで縛る)であり、それでも隔離をハイパーバイザー相当まで引き上げたい場合は、KVM を使ってワークロードごとに専用の軽量ゲストカーネルを与える Kata Containers や、システムコールをユーザー空間で横取りしてホストカーネルに直接渡さない gVisor のような、コンテナのインターフェースのまま VM に近い隔離を提供するランタイムを選ぶ、という判断になる。

余談 — Mac の Docker Desktop はなぜ VM を使うのか

ここまでの説明からすると意外に思えるかもしれないが、Mac や Windows で Docker Desktop を使う場合、コンテナは結局 1 つの Linux VM の中で動いている。名前空間や cgroup は Linux カーネルの機能であり、macOS や Windows のカーネルには存在しない。そのため Docker Desktop は裏で軽量な Linux VM(Mac では Apple Virtualization Framework または HyperKit、Windows では WSL2 上の Linux)を 1 つ起動し、コンテナ群はその Linux カーネルを共有する形で動く。「コンテナは VM を使わない」という理解は Linux ホスト上の話であって、非 Linux ホストでは VM が 1 段挟まっている。

💼 実務でどう出会うか

ローカルの docker compose up や Kubernetes の Pod が秒単位でスケールアウトできるのは、コンテナがカーネルを起動し直さないからだ。逆に、他社のワークロードと同じホストにコンテナを同居させるマルチテナント SaaS や、信頼できないコードを実行するサービスでは、カーネル共有のリスクを重く見て Kata Containers や gVisor のようなランタイムを選ぶ判断が出てくる。GitHub Actions のホスト型ランナーのように、CI が毎回まっさらな VM を 1 台起動してからその中でコンテナを動かす構成も、同じ「コンテナだけでは隔離が弱い場面がある」という判断の表れだ。

⌨️ 手を動かす(5 分)

見た目の違う Linux ディストリのコンテナを 3 つ起動しても、カーネルのバージョンは全部同じ(ホストと共有している)ことを確かめる。

docker run --rm ubuntu:22.04 uname -r
docker run --rm alpine uname -r
docker run --rm fedora uname -r

ディストリはバラバラなのに、3 つとも同じバージョン文字列が返ってくるはずだ。これは各コンテナが自分専用のカーネルを積んでいるのではなく、Docker を動かしているホスト(Mac の場合は Docker Desktop が裏で起動している Linux VM)のカーネルをそのまま覗いているために起きる。

🙅 よくある誤解
  • コンテナは「軽量な VM」だ — VM はゲスト OS ごと自分専用のカーネルを新たに起動するが、コンテナは新しいカーネルを一切起動しない。ゲスト OS という概念自体が無く、ホストカーネルの上で名前空間により区切られたプロセスに過ぎない。
  • Docker Desktop for Mac はコンテナをネイティブに動かしている — 実際には裏で 1 つの軽量 Linux VM を起動し、その中の Linux カーネル上でコンテナを動かしている。macOS のカーネルは Linux ではなく、Linux 専用機能である名前空間・cgroup をそのままでは使えないためだ。
  • コンテナは VM と同等かそれ以上に安全に隔離されている — 全コンテナがホストカーネルを 1 つ共有しているため、カーネル自体の脆弱性は隔離の前提ごと崩れうる(例: CVE-2022-0492)。VM はハイパーバイザーによるハードウェアレベルの隔離があるため、この種の脆弱性の影響範囲がより狭い。
📖 用語ミニ辞典
名前空間(namespace)
プロセスから見える PID・ネットワーク・マウントポイントなどの範囲を区切る Linux カーネルの機能。
cgroup
プロセス群が使える CPU・メモリなどのリソース量を制限・計測する Linux カーネルの機能。
ハイパーバイザー
物理ハードウェアを仮想化し、複数のゲスト OS を並行して動かす基盤ソフトウェア。
ゲスト OS
ハイパーバイザー上で動く、独自のカーネルを持つ仮想マシン内の OS。
コンテナランタイム
イメージから名前空間・cgroup を設定してコンテナプロセスを起動・管理するソフトウェア。
🔗 もっと深く