Kubernetes ローリングアップデート
Pod を段階的に新バージョンに置き換え、ゼロダウンタイムでアプリケーションを更新するデプロイ戦略
Kubernetesデプロイ
Kubernetes ローリングアップデートとは
ローリングアップデートは、Deployment のデフォルトのデプロイ戦略で、Pod を 1 つずつ (または設定した数ずつ) 新バージョンに置き換える。全 Pod を同時に停止しないため、ゼロダウンタイムでアプリケーションを更新できる。
設定
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 同時に追加できる新 Pod 数
maxUnavailable: 0 # 同時に停止できる Pod 数
template:
spec:
containers:
- name: app
image: myapp:2.0
readinessProbe:
httpGet:
path: /ready
port: 3000
更新の流れ
初期状態: [v1] [v1] [v1] ← 3 Pod 稼働中
Step 1: [v1] [v1] [v1] [v2] ← 新 Pod 追加 (maxSurge: 1)
Step 2: [v1] [v1] [v2↑] [v2] ← v2 が Ready になったら v1 を 1 つ削除
Step 3: [v1] [v2] [v2] [v2]
Step 4: [v2] [v2] [v2] ← 完了
maxUnavailable: 0 にすると、新 Pod が Ready になるまで旧 Pod を削除しない。サービスの可用性が最大限保たれる。
maxSurge と maxUnavailable の組み合わせ
| 設定 | 動作 | 特徴 |
|---|---|---|
| maxSurge: 1, maxUnavailable: 0 | 1 つずつ追加→削除 | 最も安全、時間がかかる |
| maxSurge: 0, maxUnavailable: 1 | 1 つ削除→追加 | リソース節約、一時的に容量低下 |
| maxSurge: 25%, maxUnavailable: 25% | 高速に更新 | デフォルト設定 |
Readiness プローブとの連携
ローリングアップデートの成否は Readiness プローブにかかっている。
- 新 Pod が起動する
- Readiness プローブが成功するまで、Service のエンドポイントに追加されない
- Readiness が成功したら、旧 Pod を削除する
- Readiness が失敗し続けると、更新が停止する
Readiness プローブがないと、起動中の Pod にトラフィックが流れてエラーが発生する。
ロールバック
# 直前のバージョンにロールバック
kubectl rollout undo deployment/api-server
# 特定のリビジョンにロールバック
kubectl rollout history deployment/api-server
kubectl rollout undo deployment/api-server --to-revision=3
# 更新状況の確認
kubectl rollout status deployment/api-server
Deployment は過去のリビジョンを保持しており (デフォルト 10 世代)、任意のリビジョンに戻せる。
Blue/Green デプロイとの比較
| 観点 | ローリングアップデート | Blue/Green |
|---|---|---|
| リソース | 一時的に +1 Pod | 2 倍のリソースが必要 |
| 切り替え速度 | 段階的 (数分) | 即座 (DNS/LB 切り替え) |
| ロールバック | 段階的 | 即座 |
| 新旧混在 | 更新中は混在する | 混在しない |
よくある落とし穴
Graceful Shutdown の未実装
旧 Pod が削除される際、処理中のリクエストが中断される。preStop フックと SIGTERM ハンドラーで、処理中のリクエストを完了してから終了する。
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 5"] # LB からの除外を待つ
Kubernetes ローリングアップデートの関連書籍も参考になる。