コンテナ技術の概要
ストーリー
ある日、チームリーダーの村上先輩があなたのデスクにやってきた。
「来週リリース予定の新しいWebアプリ、開発環境では動くんだけど、ステージング環境だと動かないんだよ」
「えっ、また環境差異の問題ですか?」
村上先輩は頷いた。
「そうだ。Node.jsのバージョンが違う、ライブラリのバージョンが違う...... もうこういう問題とはおさらばしたい。そこで、アプリをコンテナ化して Kubernetesにデプロイしてほしいんだ」
「コンテナ......ですか。名前は聞いたことありますけど、実際に使ったことは......」
「大丈夫。一から教えるよ。コンテナの海を一緒に航海しよう。 まずは、コンテナとは何かから始めよう」
コンテナとは何か
「環境ごと運ぶ」という発想
コンテナ技術の核心は、アプリケーションとその実行環境をまとめてパッケージ化することです。
従来の方法:
┌──────────────────────────┐
│ 本番サーバー │
│ Node.js 18.x ← 16.xのはず!│
│ npm 9.x ← 8.xのはず! │
│ libssl 1.1 ← 3.0のはず! │
│ アプリケーション │
└──────────────────────────┘
→ 「俺の環境では動くのに......」が頻発
コンテナの方法:
┌──────────────────────────┐
│ 本番サーバー │
│ ┌────────────────────┐ │
│ │ コンテナ │ │
│ │ Node.js 18.17.0 │ │
│ │ npm 9.6.7 │ │
│ │ libssl 3.0 │ │
│ │ アプリケーション │ │
│ └────────────────────┘ │
└──────────────────────────┘
→ どこでも同じ環境で動く
コンテナと仮想マシンの違い
コンテナはよく仮想マシン(VM)と比較されますが、大きな違いがあります。
仮想マシン: コンテナ:
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│App A│ │App B│ │App C│ │App A│ │App B│ │App C│
├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤
│Libs │ │Libs │ │Libs │ │Libs │ │Libs │ │Libs │
├─────┤ ├─────┤ ├─────┤ └──┬──┘ └──┬──┘ └──┬──┘
│Guest│ │Guest│ │Guest│ │ │ │
│ OS │ │ OS │ │ OS │ ┌──┴──────┴──────┴──┐
├─────┴─┴─────┴─┴─────┤ │ コンテナランタイム │
│ ハイパーバイザ │ ├─────────────────────┤
├──────────────────────┤ │ ホスト OS │
│ ホスト OS │ ├─────────────────────┤
├──────────────────────┤ │ ハードウェア │
│ ハードウェア │ └─────────────────────┘
└──────────────────────┘
| 比較項目 | 仮想マシン | コンテナ |
|---|---|---|
| 起動時間 | 数分 | 数秒 |
| サイズ | 数GB | 数十MB〜数百MB |
| OS | ゲストOSが必要 | ホストOSのカーネルを共有 |
| 分離レベル | 完全分離 | プロセスレベルの分離 |
| リソース消費 | 大きい | 小さい |
| ポータビリティ | 低い | 高い |
コンテナの仕組み
Linuxの2つの技術
コンテナは、Linuxカーネルの以下の機能を利用しています。
1. 名前空間(Namespace)
プロセスごとに独立した「視界」を提供する仕組みです。
| 名前空間 | 分離する対象 |
|---|---|
| PID | プロセスID |
| NET | ネットワーク |
| MNT | ファイルシステム |
| UTS | ホスト名 |
| IPC | プロセス間通信 |
| USER | ユーザーID |
2. cgroups(Control Groups)
プロセスが使用できるリソースを制限する仕組みです。
- CPU使用率の制限
- メモリ使用量の制限
- ディスクI/Oの制限
- ネットワーク帯域の制限
┌─────────────────────────────────────┐
│ ホスト OS │
│ │
│ ┌───────────┐ ┌───────────┐ │
│ │ コンテナA │ │ コンテナB │ │
│ │ │ │ │ │
│ │ Namespace │ │ Namespace │ │
│ │ - PID │ │ - PID │ │
│ │ - NET │ │ - NET │ │
│ │ - MNT │ │ - MNT │ │
│ │ │ │ │ │
│ │ cgroups │ │ cgroups │ │
│ │ - CPU: 1 │ │ - CPU: 2 │ │
│ │ - Mem:512M│ │ - Mem: 1G │ │
│ └───────────┘ └───────────┘ │
│ │
│ Linux Kernel │
└─────────────────────────────────────┘
なぜコンテナが普及したのか
1. 環境の一貫性
開発環境、テスト環境、本番環境で同じコンテナイメージを使うことで、環境差異の問題を解消できます。
2. 高速なデプロイ
コンテナは数秒で起動するため、スケーリングやデプロイが高速に行えます。
3. マイクロサービスとの親和性
各サービスを独立したコンテナとして運用することで、個別にスケーリングや更新が可能になります。
4. CI/CDパイプラインとの統合
ビルド、テスト、デプロイの各段階でコンテナを活用し、パイプライン全体を効率化できます。
まとめ
| ポイント | 内容 |
|---|---|
| コンテナとは | アプリと実行環境をまとめてパッケージ化する技術 |
| VMとの違い | ホストOSのカーネルを共有し、軽量・高速 |
| 仕組み | Linuxの名前空間とcgroupsを利用 |
| 普及の理由 | 環境の一貫性、高速デプロイ、マイクロサービスとの親和性 |
チェックリスト
- コンテナの基本概念を理解した
- 仮想マシンとの違いを説明できる
- 名前空間とcgroupsの役割を理解した
次のステップへ
次のセクションでは、コンテナ技術の事実上の標準である「Docker」のアーキテクチャについて学びます。 Dockerがどのような仕組みでコンテナを管理しているのかを理解しましょう。
推定読了時間: 15分