第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の作成を学びます。