初級ではコンテナを「アプリを箱ごと運ぶ仕組み」と捉えました。中級では、その箱の正体——イメージ・レイヤ・レジストリ——と、なぜ軽いのかの中身を見ます。
概要 — まず全体をつかむ
詳細 — 1段階ずつ追う
これは何をする係?
Docker の世界は、イメージとコンテナの2語で回っています。
- イメージ(※1)— 箱の設計図。不変のテンプレートで、これ自体は動かない
- コンテナ — イメージを起動して動いている実体(実行インスタンス)
イメージは1枚岩ではなく、レイヤ(※2)=差分の積み重ねでできています。下からベースOS層・ランタイム/ライブラリ層・アプリ層…と重なり、同じ層は共有・キャッシュされます。だから配布もビルドも速く済みます。
アニメーション『イメージとコンテナのレイヤ』を開く
登場人物メモ:
- ※1 イメージ — アプリと環境を固めた不変のテンプレート
- ※2 レイヤ — イメージを構成する差分の層。共有・再利用でき、キャッシュが効く
- ※3 レジストリ — イメージを保管・配布する倉庫(Docker Hub など)
この部分をもっと深く(上級)
コンテナは「小さな仮想マシン」ではありません。ホストのカーネルをそのまま使う、ただのプロセスです。ただしそのプロセスに対して、カーネルが「見える景色」と「使える資源」を絞っている——それだけです。
- VM — ハイパーバイザの上で ゲストOS(カーネルごと) を丸ごと動かす。境界はハードウェアの仮想化
- コンテナ — ホストの1つのカーネルを共有し、namespace(※1)で景色を、cgroups(※2)で資源を 仕切る
アニメーション『VMとコンテナの違い』を開く
だから起動はプロセス生成と同じ速さ(ミリ秒〜秒)で、メモリのフットプリントも小さい。「軽い」の正体は、OSを2枚重ねていないことにあります。逆に言えば、ホストと違うカーネルが要る環境(別系統のOS)はそのままでは動かせない、という制約もここから来ます。
登場人物メモ:
- ※1 namespace — プロセスから見える範囲(PID・ネットワーク等)を仕切るカーネル機能
- ※2 cgroups — CPU・メモリなど使える資源に上限をかけるカーネル機能
- ※3 overlayfs — 複数の層を1枚に重ねて見せる、コピーオンライトのファイルシステム
やさしく言うと(初級)
コンテナは、アプリ本体と、それが動くのに必要な環境(※1 ライブラリなどの部品)を、まとめて1つの箱に詰める仕組みです。
引っ越しにたとえると、家具を1つずつ運ぶのではなく、中身ごと箱に詰めて そのまま運ぶイメージ。箱の中は行き先が変わっても同じなので、どこでも同じように動きます。
Docker はこの箱を作ったり動かしたりするための、いちばん有名な道具です。
登場人物メモ:
- ※1 環境 — アプリが動くのに必要な部品一式(ライブラリ・設定など)
- ※2 カーネル — OSの中核。ハードウェアとのやり取りを担う土台の部分
仕事の流れ
- Dockerfile(手順書)にアプリと環境の作り方を書く
- それをビルドしてイメージ(設計図)を作る
- イメージをレジストリ(※3 倉庫)へ push(アップロード)する
- 使う場所で pull(ダウンロード)し、run でコンテナとして起動する
同じイメージを配れば、開発でも本番でも同じものが立ち上がる——これが ポータビリティ(持ち運びやすさ)の本質です。
やさしく言うと(初級)
- アプリと必要な環境を箱に詰める(設計図を書く)
- 箱をそのまま別の場所へ運ぶ(開発PC → 本番サーバなど)
- どこでも同じ状態で起動する
- 要らなくなったら箱ごと捨てる(後片付けが簡単)
仕組みの勘所
なぜ「軽いのに隔離されている」のか。土台の OSの仕組み が鍵です。
- namespace(名前空間) — プロセスから見える範囲を仕切る。他のコンテナやホストが見えないので、独立して見える
- cgroups — CPUやメモリなど使える資源に上限をかける。1つが暴走しても巻き込まれにくい
- カーネルは共有 — 別OSを積まないので、起動は秒単位で軽い
つまりコンテナは「小さな仮想マシン」ではなく、隔離して資源制限したプロセスだと捉えると腑に落ちます。
この部分をもっと深く(上級)
中級では「namespaceで見える範囲を仕切る」と一言でまとめました。実際には 種類ごとに別々のnamespace があり、組み合わせて1つのコンテナの隔離を作ります。
- pid — プロセス番号を独立させる。コンテナ内の最初のプロセスがPID 1に見える
- net — ネットワーク(インターフェース・ルーティング表・ポート)を独立させる
- mnt — マウント点(見えるファイルシステムの木)を独立させる
- uts — ホスト名・ドメイン名を独立させる
- ipc — プロセス間通信(共有メモリ等)を独立させる
- user — ユーザ/グループIDを対応づけ直す。コンテナ内のroot(0)をホストの非特権IDへ写せる
一方 cgroups は「見える/見えない」ではなく 量 を扱います。CPU時間の割り当て、メモリ上限(超えるとOOMで停止)、ブロックI/Oやプロセス数の制限。1つのコンテナが暴走してもホストごと道連れにしにくいのは、この資源の壁があるからです。namespaceが隔離、cgroupsが制限——この二本立てが腑に落ちれば、コンテナの体は見えたも同然です。
やさしく言うと(初級)
同じ「隔離して動かす」でも、仮想マシン(VM) はゲストOSを丸ごと積むため重くなります。コンテナは OSの中核(※2 カーネル)を土台と共有し、上にアプリと必要な部品だけを載せるので、軽くて起動も速いのが特長です。
アニメーション『VMとコンテナの違い』を開く
⚠️ うまくいかないとき
- イメージの肥大化 — 不要な物まで層に積むと重くなる(最小限の土台を選ぶ)
- 状態の消失 — コンテナは使い捨て前提。消えて困るデータは外部(ボリューム等)へ
- カーネル依存 — ホストと大きく異なるOSは共有カーネルでは動かせない
- latest 頼み — バージョンを固定しないと、環境ごとに中身がずれて「動かない」が再発する
この部分をもっと深く(上級)
--privilegedの乱用 — capabilitiesもseccompも実質無効化され、隔離はほぼ名ばかりになる。抜け出されればホストごと危ない- 共有カーネルの脆弱性 — VMより境界が薄い。カーネルの穴は全コンテナに響くので、ホストのパッチ運用が命綱
- 書き込み層への溜め込み — 使い捨て前提のupperにデータを書き続けると肥大化し、コンテナ削除で消える。永続化はボリュームへ
- latestとキャッシュの罠 — タグ固定を怠ると、同じDockerfileでも下層イメージが変わって再現性を失う
やさしく言うと(初級)
- 箱に入れ忘れ — 必要な部品を詰め忘れると、別の場所で動かない
- データが消える — 箱を捨てると中のデータも消える(保存先は別に分ける必要がある)
- 軽い=万能ではない — カーネルを共有するため、土台と大きく違う環境向けには不向きなこともある
理解度チェック
そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。
問1. Dockerイメージが「レイヤ(層)」の積み重ねでできていることの利点として正しいのは?
問2. Dockerfile の役割として最も正しいのは?
問3. コンテナの隔離で「プロセスから見える範囲を仕切る」役割を担うのはどれ?
問4. コンテナが軽量で速いのは なぜ?
問5. イメージとコンテナの関係で正しいのは?
問6. コンテナで「消えて困るデータ」の正しい扱いはどれ?
問7. 作ったイメージを保管・配布する倉庫(Docker Hub など)を何と呼ぶか、カタカナで答えてください。
問8. CPUやメモリなど「使える資源に上限」をかけ、1つのコンテナの暴走を他へ波及させないカーネルの仕組みを何と呼ぶか答えてください。