第2章:コンテナの理論
はじめに
Dockerコンテナは、Linuxカーネルの機能(namespaces、cgroups)を利用して実現されています。本章では、コンテナ技術の理論的基盤を学びます。
---
1. Linux Namespaces
1.1 Namespacesとは
Namespaces:
- カーネルリソースの分離
- プロセスごとに異なるビューを提供
- 各namespaceは独立した空間
種類(7つ):
1. mnt (Mount) - ファイルシステム
2. pid (PID) - プロセスID
3. net (Network) - ネットワーク
4. ipc (IPC) - プロセス間通信
5. uts (UTS) - ホスト名・ドメイン名
6. user (User) - ユーザー/グループID
7. cgroup - cgroup階層
1.2 PID Namespace
ホスト: コンテナ:
PID 1: systemd PID 1: /app/main
PID 2: sshd PID 2: /app/worker
PID 3: docker ...
...
PID 1234: /app/main ←→ (コンテナ内ではPID 1)
PID 1235: /app/worker ←→ (コンテナ内ではPID 2)
特徴:
- コンテナ内のPID 1は特別(init)
- シグナル処理の責任
- コンテナ外のプロセスは見えない
1.3 Network Namespace
ホスト: コンテナ:
eth0: 192.168.1.100 eth0: 172.17.0.2
lo: 127.0.0.1 lo: 127.0.0.1
+--------+ +--------+
| Host | |Container|
| eth0 |←--veth---| eth0 |
+--------+ pair +--------+
↓
+--------+
| docker0| (bridge)
+--------+
veth pair:
- 仮想イーサネットペア
- 一方がホスト、もう一方がコンテナ
1.4 Mount Namespace
ホスト: コンテナ:
/ /
├── bin ├── bin (alpine)
├── etc ├── etc (config)
├── var ├── var
│ └── lib │ └── data → ボリューム
│ └── docker └── app
特徴:
- 独立したファイルシステムビュー
- ボリュームマウントで共有可能
- オーバーレイファイルシステム
1.5 User Namespace
ホスト: コンテナ:
UID 0: root UID 0: root (container)
UID 1000: user ↓
マッピング:
Container UID 0 → Host UID 1000
セキュリティ:
- コンテナ内のrootはホストでは非特権
- 権限昇格の防止
---
2. Control Groups (cgroups)
2.1 cgroupsとは
cgroups:
- リソース制限・監視
- 2006年にGoogleが開発
- 2008年にLinuxカーネルにマージ
制御可能なリソース:
1. CPU
2. メモリ
3. ディスクI/O
4. ネットワークI/O
5. デバイスアクセス
2.2 CPU制限
# Docker での CPU 制限
docker run --cpus="1.5" nginx # 1.5 CPU相当
docker run --cpu-shares=512 nginx # 相対的な重み
docker run --cpuset-cpus="0,1" nginx # 特定CPUに固定
# cgroups v2 の階層構造
/sys/fs/cgroup/
└── system.slice/
└── docker-<container_id>.scope/
├── cpu.max # CPU制限
├── cpu.weight # CPU優先度
└── cpu.stat # 統計情報
2.3 メモリ制限
# Docker でのメモリ制限
docker run --memory="512m" nginx # 最大メモリ
docker run --memory="512m" --memory-swap="1g" nginx # スワップ含む
docker run --memory-reservation="256m" nginx # ソフトリミット
# OOM Killer
# メモリ超過時にプロセスを強制終了
docker run --oom-kill-disable nginx # 無効化(非推奨)
# cgroups ファイル
/sys/fs/cgroup/docker/<id>/memory.max
/sys/fs/cgroup/docker/<id>/memory.current
2.4 I/O制限
# Docker での I/O 制限
docker run --device-read-bps /dev/sda:1mb nginx
docker run --device-write-bps /dev/sda:1mb nginx
docker run --device-read-iops /dev/sda:1000 nginx
docker run --device-write-iops /dev/sda:1000 nginx
# Blkio (Block I/O) コントローラ
# 読み書きの帯域幅とIOPSを制限
---
3. Union File System
3.1 オーバーレイファイルシステム
+------------------------+
| Container Layer (RW) | ← 書き込み可能
+------------------------+
| Image Layer 3 (RO) | ← アプリケーション
+------------------------+
| Image Layer 2 (RO) | ← 依存関係
+------------------------+
| Image Layer 1 (RO) | ← ベースイメージ
+------------------------+
OverlayFS:
- 複数のレイヤーを1つに見せる
- Copy-on-Write (CoW)
- 元のレイヤーは変更されない
3.2 Copy-on-Write
読み込み:
1. 上位レイヤーから検索
2. 見つからなければ下位へ
書き込み:
1. 下位レイヤーのファイルを上位にコピー
2. 上位レイヤーで変更
3. 元のファイルは不変
削除:
1. 上位レイヤーに「ホワイトアウト」ファイル作成
2. 下位のファイルを隠す
3.3 ストレージドライバ
主要なドライバ:
1. overlay2(推奨)
- Linux 4.0+
- 最も効率的
2. aufs
- 古いUbuntu
- 非推奨
3. devicemapper
- RHEL/CentOS
- ブロックレベル
4. btrfs / zfs
- 高度な機能
- 特定のファイルシステムが必要
確認:
docker info | grep "Storage Driver"
---
4. コンテナランタイム
4.1 アーキテクチャ
+------------------+
| Docker CLI |
+------------------+
↓
+------------------+
| Docker Daemon |
+------------------+
↓
+------------------+
| containerd | ← 高レベルランタイム
+------------------+
↓
+------------------+
| runc | ← 低レベルランタイム
+------------------+
↓
+------------------+
| Linux Kernel |
| (namespaces, |
| cgroups) |
+------------------+
4.2 containerd
containerd:
- コンテナライフサイクル管理
- イメージ管理
- ストレージ管理
- ネットワーク管理
機能:
- イメージのプル/プッシュ
- コンテナの作成/実行/停止
- スナップショット管理
4.3 runc
runc:
- OCI(Open Container Initiative)準拠
- コンテナの実際の実行
- namespace/cgroups の設定
OCI Runtime Specification:
- コンテナ設定(config.json)
- ファイルシステムバンドル
- ライフサイクル定義
---
5. コンテナネットワーキング
5.1 ネットワークモード
1. bridge(デフォルト):
- docker0 ブリッジ
- NAT経由で外部接続
- コンテナ間通信可能
2. host:
- ホストのネットワークスタック共有
- ポートマッピング不要
- 分離なし(Inception禁止)
3. none:
- ネットワークなし
- 完全分離
4. overlay:
- 複数ホスト間
- Docker Swarm用
5.2 Bridgeネットワーク
+------------------+
| Host |
| |
| +------------+ |
| | docker0 | | ← ブリッジ
| | 172.17.0.1 | |
| +-----+------+ |
| | |
| +-----+------+ |
| | Container | |
| | eth0 | |
| | 172.17.0.2 | |
| +------------+ |
| |
| eth0 |
| 192.168.1.100 |
+------------------+
通信フロー:
Container → docker0 → eth0 → Internet
↓
iptables NAT
5.3 ユーザー定義ネットワーク
# ネットワーク作成
docker network create inception
# コンテナを接続
docker run --network inception --name nginx nginx
docker run --network inception --name wp wordpress
# DNS解決
# nginx コンテナから:
ping wp # → 172.20.0.3 (自動解決)
利点:
- 自動DNS解決
- 分離されたネットワーク
- ユーザー定義サブネット
---
6. データ永続化
6.1 ボリュームの種類
1. Named Volumes:
docker run -v mydata:/data nginx
- Docker管理
- 永続的
- 推奨
2. Bind Mounts:
docker run -v /host/path:/container/path nginx
- ホストパス指定
- 開発時に便利
- セキュリティ注意
3. tmpfs Mounts:
docker run --tmpfs /tmp nginx
- メモリ上
- 一時データ
- 高速
6.2 ボリュームドライバ
ローカルドライバ(デフォルト):
/var/lib/docker/volumes/<name>/_data
リモートドライバ:
- NFS
- AWS EBS
- Azure Files
# NFS ボリュームの作成
docker volume create --driver local \
--opt type=nfs \
--opt o=addr=nfs.example.com,rw \
--opt device=:/path/to/share \
nfs_volume
---
7. セキュリティ機構
7.1 Capabilities
Linux Capabilities:
- root権限の分割
- 必要な権限のみ付与
デフォルトで削除されるcap:
- CAP_SYS_ADMIN
- CAP_NET_ADMIN
- CAP_SYS_PTRACE
# 追加・削除
docker run --cap-add NET_ADMIN nginx
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx
7.2 Seccomp
Seccomp (Secure Computing Mode):
- システムコールのフィルタリング
- ホワイトリスト/ブラックリスト
デフォルトで制限されるシステムコール:
- reboot
- kexec_load
- mount(一部)
# カスタムプロファイル
docker run --security-opt seccomp=profile.json nginx
7.3 AppArmor / SELinux
AppArmor:
- Ubuntu/Debian デフォルト
- パス基準のアクセス制御
SELinux:
- RHEL/CentOS
- ラベル基準のアクセス制御
# AppArmor プロファイル
docker run --security-opt apparmor=docker-default nginx
# SELinux
docker run --security-opt label=type:svirt_sandbox_file_t nginx
---
まとめ
本章で学んだこと:
- Namespaces: 7種類のリソース分離
- Cgroups: リソース制限(CPU, メモリ, I/O)
- Union FS: レイヤー構造、Copy-on-Write
- ランタイム: containerd, runc
- ネットワーク: bridge, overlay
- ボリューム: 永続化の種類
- セキュリティ: Capabilities, Seccomp
次章では、Dockerfileの作成を学びます。