🎓 レベル:標準 | 重要度:A(必須)
📎 前提:コンテナとは(名前空間・cgroups) | 関連:Dockerイメージとレイヤ・Docker Composeで複数コンテナ
要点(BLUF)
- コンテナは独自のネットワーク名前空間を持つ。外から使うにはポート公開(-p ホスト:コンテナ)、コンテナ同士はユーザー定義ネットワーク上で名前で通信する。
- コンテナは使い捨てなので、消えても残したいデータはボリュームに逃がす。DBのデータ・アップロードファイルなどが対象。
- 原則:コンテナ本体はステートレス(状態を持たない)、状態はボリューム/外部サービスへ。これがスケール(コストとスケーリングの考え方)の前提。
概念 ── 隔離されたネットワークと消えるストレージ
コンテナは名前空間(コンテナとは(名前空間・cgroups))で自分専用のIP・ポートを持ちます。便利な反面、何もしなければ外からも他コンテナからも届きません。さらにファイルシステムも使い捨て——コンテナを消すと書き込みは消えます。この2つを橋渡しするのが「ポート公開」と「ボリューム」です。
仕組み① ── ネットワーク
ポート公開:ホストのポートをコンテナのポートに転送します。-p 8080:80 は「ホストの8080に来たらコンテナの80へ」。
コンテナ間通信:同じユーザー定義ネットワークに置くと、コンテナはサービス名(コンテナ名)で名前解決して通信できます。Docker内蔵のDNSが効くので、IPを直書きしません。
flowchart LR
client["外部クライアント"] -->|"ホスト:8080"| host["ホスト"]
host -->|"転送 -p 8080:80"| web["webコンテナ:80"]
web -->|"名前 db で接続"| db["dbコンテナ:5432"]
subgraph net["ユーザー定義ネットワーク(内蔵DNSで名前解決)"]
web
db
end
# ユーザー定義ネットワークを作る
docker network create appnet
# DBを参加させる(外には公開しない)
docker run -d --name db --network appnet postgres:16
# Webを参加させ、ホストにだけ公開。アプリは接続先を「db」と書ける
docker run -d --name web --network appnet -p 8080:80 myapp:1.0
ポイントは DB はホストに公開しないこと。外に出すのは入口(web)だけにし、DB は内部ネットワークに隠す。これが最小公開の原則です。
仕組み② ── ボリューム
書き込みを残すには、コンテナの外にストレージを置いてマウントします。2種類。
| 種類 | 形 | 向く用途 |
|---|---|---|
| 名前付きボリューム | Dockerが管理する領域 | DBデータなど本番の永続化 |
| バインドマウント | ホストの実ディレクトリ | 開発中のソース共有 |
# 名前付きボリュームを作り、DBのデータディレクトリにマウント
docker volume create pgdata
docker run -d --name db \
-v pgdata:/var/lib/postgresql/data \
postgres:16
# → コンテナを消して作り直しても pgdata は残る
# 開発:ホストのコードをコンテナに反映(バインドマウント)
docker run -d --name dev -v "$(pwd)":/app myapp:dev
なぜステートレス+ボリュームなのか
- 作り直しを安全にするため:コンテナを使い捨てにできれば、壊れたら置き換えるだけ(構成管理とImmutable Infrastructure)。そのためには「消えて困る物」を本体から分離しておく必要がある。
- 水平スケールのため:同じコンテナを何個も並べたい(コストとスケーリングの考え方)。各コンテナが固有の状態を抱えると並べられない。状態はボリューム/外部DBへ。
- 最小公開のため:公開ポートを入口だけに絞れば攻撃面が小さい。内部通信は名前解決で完結させる。
⚠️ よくある誤解・落とし穴
- 「DBのデータをコンテナ内に置く」→ コンテナ削除でデータ消滅。必ずボリュームへ。
- 「
-p 0.0.0.0:5432:5432で DB を公開」→ DB を世界に晒す事故。内部ネットワークに隠し、入口だけ公開。 - 「コンテナのIPを直書きで接続」→ コンテナは作り直すとIPが変わる。サービス名で名前解決する。
- 「バインドマウントを本番で多用」→ ホストのパスに依存し再現性が落ちる。本番は名前付きボリューム、開発はバインド、と使い分け。
- 「ボリュームのバックアップを取らない」→ 永続化と冗長化は別。ボリュームも壊れる。バックアップは別途。
対応ラボ
cloud-infra-study/labs/03-04_compose.yaml 内で、web と db をネットワークで繋ぎ、db をボリューム永続化する構成を確認(次トピックの Compose と共通)。
関連
- 使い捨てというコンテナの本質は コンテナとは(名前空間・cgroups)
- これらを宣言的に束ねるのは Docker Composeで複数コンテナ
- 永続化される設定/秘密の扱いは ConfigMap・Secret・ボリューム
- 水平スケールの前提(ステートレス)は コストとスケーリングの考え方