こんにちは、みねです。
「そろそろ Kubernetes に移行すべきだろうか」——Docker Compose で運用してきたサービスがある程度育つと、必ず出てくる問いです。流行に乗って早すぎる移行をすると運用コストで疲弊し、遅すぎると本番障害で痛い目を見ます。
この記事では、Docker Compose から Kubernetes(K8s)への移行を、「スケールすると壊れるポイント」を起点に判断する軸を整理します。
TL;DR
- Compose で十分なケース: 単一ホスト・少数サービス・トラフィックが予測可能・チームが小さい。ここで K8s を入れると運用コストだけが先行します
- K8s が必要になる分岐点: 複数ホストへの水平スケール、ゼロダウンタイム更新、セルフヒーリング、宣言的な構成管理が「運用上の必須要件」になった瞬間
- 最初の一歩: いきなり全面移行せず、まず1サービスをマネージドK8s(EKS / GKE / AKS)へ載せ、移行判断フロー(§5)で全体適用を判定する
この記事でできるようになること
- Docker Compose の限界(単一ホスト・スケール・自己修復)を技術根拠つきで説明できる
- 自社の状況が「Compose で十分」か「K8s が必要」かを判断軸で切り分けられる
- 早すぎる/遅すぎる移行の両方を避け、現実的な移行ステップを設計できる
対象読者
- Docker Compose で本番または検証環境を運用しているエンジニア
- K8s 移行を検討しているが、判断材料がそろっていないチームリード
- インフラの技術選定を任されたバックエンド/SRE担当
1. 結論:移行は「機能要件」ではなく「運用要件」で決める
先に結論です。Docker Compose から Kubernetes への移行は、アプリの機能ではなく運用要件で決めるべきです。
Docker Compose は公式ドキュメントでも「複数コンテナを単一ホスト上で定義・実行するためのツール」と位置づけられています(Docker Compose overview)。つまり Compose は「1台のマシンの中でコンテナを束ねる」道具であり、複数ホストにまたがるオーケストレーションは守備範囲外です。
一方 Kubernetes は公式に「コンテナ化されたワークロードとサービスを管理するための、ポータブルで拡張可能なオープンソースプラットフォーム」と定義されています(Kubernetes Overview)。スケール・自己修復・宣言的構成といった「運用の自動化」が本質です。
判断軸はシンプルです。次の運用要件が「あったら嬉しい」ではなく「ないと困る」になったかで見ます。
| 運用要件 | Compose | Kubernetes |
|---|---|---|
| 単一ホストでの複数コンテナ起動 | 得意 | 可能だが過剰 |
| 複数ホストへの水平スケール | 非対応 | 標準機能 |
| ローリングアップデート/ロールバック | 手動 | 宣言的に標準対応 |
| コンテナ障害の自動復旧 | restart程度 | セルフヒーリング |
| 宣言的な望ましい状態の維持 | 弱い | 中核機能 |
2. Docker Compose で十分なケース
まず「移行しなくてよい」ケースをはっきりさせます。次の条件にすべて当てはまるなら、Compose のままで問題ありません。
- サービスが単一ホストに収まる(CPU/メモリに十分な余裕がある)
- トラフィックが予測可能で、急激なスパイクがない
- デプロイ頻度が低く、数分のダウンタイムが許容できる
- 運用チームが小規模で、K8s の学習・保守コストを賄えない
このゾーンで K8s を導入すると、コントロールプレーンの保守、マニフェスト管理、ネットワーク(CNI)やストレージ(CSI)の理解など、本質的でない運用負荷が一気に増えます。スタートアップの初期や社内ツール、PoC では Compose で十分なことがほとんどです。[経験則] 小規模サービスで早すぎるK8s移行を行ったチームの多くが、半年以内に「運用工数が増えただけ」という後悔を口にします。
services:
web:
image: myapp:1.4.0
ports:
- "8080:8080"
environment:
- DATABASE_URL=postgres://db:5432/app
depends_on:
- db
restart: unless-stopped
db:
image: postgres:16
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
この restart: unless-stopped が、Compose における「自己修復」の実質的な上限です。プロセスが落ちたら再起動はしますが、ホストごと落ちたら誰も助けてくれません。ここが次節の「壊れるポイント」につながります。
3. スケールすると壊れるポイント
Compose で運用を続け、サービスが育っていくと、決まった場所で壊れ始めます。移行判断の核心はここです。
3.1 単一ホストの限界(スケールアウト不能)
最初に壁になるのが単一ホスト前提です。Compose の deploy.replicas は Swarm モード前提の設定で、docker compose up 単体では複数ホストへ分散できません。トラフィックが1台の上限を超えると、垂直スケール(より大きいマシン)でしのぐしかなくなり、いずれ頭打ちになります。
Kubernetes なら Deployment の replicas と HorizontalPodAutoscaler で、複数ノードへ自動的にスケールアウトできます(Horizontal Pod Autoscaling)。
3.2 自己修復の不在(ホスト障害で全停止)
前述の通り Compose の復旧は restart ポリシー止まりです。ホスト自体のダウンには無力で、SPOF(単一障害点)になります。K8s はノード障害を検知し、別ノードへ Pod を再スケジュールするセルフヒーリングを標準で持ちます。可用性が事業要件になった瞬間、ここが移行の決定打になります。
3.3 ゼロダウンタイム更新の手作り化
Compose でのデプロイは「新イメージで up し直す」ため、切り替え中に短い断が出ます。これを無停止にしようとすると、ロードバランサ前段での Blue/Green を自前で組むことになり、複雑なシェルスクリプトが育ちます。K8s は RollingUpdate と readinessProbe による段階切り替えを宣言的に提供します。
3.4 構成管理が暗黙知になる
.env の手編集、ホストへの直接 SSH、手順書の口伝——Compose 運用は宣言的でない操作が混ざりやすく、属人化します。K8s は「望ましい状態」をマニフェストで宣言し、GitOps(Argo CD / Flux)と組み合わせれば構成がコードに集約されます。
同じ web サービスを K8s で表すと、最小でもこうなります。Compose の簡潔さと比べ、宣言する情報量が増える代わりに、スケールと自己修復が手に入ります。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: myapp:1.4.0
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
resources:
requests:
cpu: "250m"
memory: "256Mi"
replicas: 3 で複数ノードに分散し、readinessProbe で無停止更新の起点になり、resources でスケジューリングと自動スケールの基準が決まります。Compose で曖昧だったものが、すべて明示を強いられる——これが K8s の学習コストの正体でもあります。
:::message 途中段階として Docker Swarm という選択肢もあります。Compose 記法のまま複数ホストへ広げられますが、エコシステムの勢いは Kubernetes に集まっています。長期運用なら、Swarm を挟むより最初からマネージドK8sを検討する方が無難です。 :::
4. K8s が必要になる分岐点
§3 の壊れるポイントを、移行を決断すべき分岐シグナルとして整理します。1つでも「ないと困る」に変わったら、移行検討フェーズに入る合図です。
- 可用性 SLO: ホスト1台障害でサービス全停止が許されなくなった
- スケール: 垂直スケールが頭打ち、または負荷が時間帯で大きく変動する
- デプロイ頻度: 1日複数回デプロイし、断やロールバックの手作業が無視できない
- マルチサービス化: マイクロサービスが増え、サービス間通信・スケール単位の分離が必要になった
- チーム規模: 専任で運用基盤を見られる人員が確保でき、学習コストを吸収できる
最後の「チーム規模」は見落とされがちです。CNCF も Kubernetes を「本番グレードのコンテナオーケストレーション」として位置づけていますが(CNCF Kubernetes)、本番グレードの運用には相応の人的投資が要ります。技術要件が満たされても、運用体制がなければ移行は失敗します。マイクロサービス化に伴う失敗パターンは とりあえず microservices が失敗する理由 でも整理しているので、分割の判断と合わせて読むと精度が上がります。
5. 現実的な移行ステップ
「移行する」と決めたら、いきなり全面移行はしません。リスクを段階的に下げる順序で進めます。
- マネージドK8sを選ぶ: EKS / GKE / AKS のいずれか。コントロールプレーンの自前運用は避け、まず管理負荷を最小化する
- 1サービスだけ移行: ステートレスで影響の小さいサービスを Deployment + Service として載せ、運用感覚をつかむ
- 可観測性を先に整える: メトリクス・ログ・ヘルスチェックを K8s 流儀に合わせる。ここが弱いとセルフヒーリングが逆に障害を隠す
- ステートフルを慎重に: DB は安易に Pod 化せず、マネージドDBの利用を第一候補にする
- GitOps で構成を固定: マニフェストを Git 管理し、手作業の構成変更を禁止する
この移行そのものが大きな技術選定です。可逆性の設計や撤退条件の決め方は 技術選定で後悔しないための判断軸 の枠組みがそのまま使えます。「移行したが運用しきれない」を避けるため、戻せる設計と撤退条件の数値化をセットで持っておくことを強くおすすめします。
:::message alert
移行のアンチパターンは「Compose の docker-compose.yml を変換ツールで機械的に K8s 化して終わり」です。probe・resources・スケール戦略を設計せずに移すと、K8s の利点を得られないまま複雑さだけを抱え込みます。
:::
6. まとめ
Docker Compose から Kubernetes への移行判断は、次の3点に集約できます。
- 運用要件で決める: 機能ではなく「可用性・スケール・デプロイ頻度」が必須要件になったか
- 壊れるポイントを見る: 単一ホスト限界・自己修復の不在・無停止更新の手作り化が顕在化したか
- 段階的に移す: マネージドK8s + 1サービス先行 + 可観測性 + GitOps の順で、戻せる形で進める
小規模なうちは Compose のままが正解です。壊れるポイントが「予兆」から「実害」に変わった瞬間こそ、移行の適期です。
FAQ
Q. 小規模サービスでも最初からKubernetesにすべきですか? A. いいえ。単一ホストに収まり、トラフィックが予測可能で、短時間のダウンタイムが許容できる小規模サービスは、Docker Composeで十分です。早すぎる移行は運用コストだけが先行します。
Q. Docker ComposeとKubernetesは何が根本的に違いますか? A. Composeは単一ホスト上で複数コンテナを束ねるツールで、Kubernetesは複数ホストにまたがってスケール・自己修復・宣言的構成管理を行うオーケストレーション基盤です。守備範囲が異なります。
Q. 移行を判断する最大のシグナルは何ですか? A. ホスト1台の障害でサービス全停止が許されなくなったとき、垂直スケールが頭打ちになったとき、デプロイ頻度が上がり無停止更新の手作業が無視できなくなったときです。1つでも「ないと困る」に変われば検討の合図です。
Q. Docker Swarmではダメですか? A. Compose記法のまま複数ホストへ広げられる利点はありますが、エコシステムの勢いはKubernetesに集まっています。長期運用ならSwarmを挟まず、マネージドK8sを直接検討する方が無難です。
Q. データベースもKubernetesに載せるべきですか? A. 安易にPod化せず、まずマネージドDBの利用を第一候補にしてください。ステートフルなワークロードはK8s上でも運用可能ですが、設計難度が高く、初回移行では避けるのが現実的です。
