Day 4: ReplicaSetとDeployment
今日学ぶこと
- ReplicaSetの仕組みとPodの冗長化
- Deploymentによるアプリケーション管理
- ローリングアップデートとロールバック
- スケーリングの基本操作
なぜPodを直接作成しないのか
Day 3でPodを直接作成しましたが、本番環境ではPodを単体で作成することはほぼありません。理由は以下の通りです。
| 問題 | 説明 |
|---|---|
| 単一障害点 | Podが1つだけだと、障害時にサービスが停止する |
| 自動復旧なし | 直接作成したPodは削除されると復活しない |
| スケーリング不可 | 手動で1つずつPodを作る必要がある |
| 更新が困難 | アプリ更新時にダウンタイムが発生する |
この問題を解決するのがReplicaSetとDeploymentです。
flowchart TB
DEP["Deployment"] --> RS["ReplicaSet"]
RS --> P1["Pod 1"]
RS --> P2["Pod 2"]
RS --> P3["Pod 3"]
style DEP fill:#8b5cf6,color:#fff
style RS fill:#3b82f6,color:#fff
style P1 fill:#22c55e,color:#fff
style P2 fill:#22c55e,color:#fff
style P3 fill:#22c55e,color:#fff
ReplicaSet
ReplicaSetは、指定した数のPodレプリカが常に実行されていることを保証するリソースです。
ReplicaSetの仕組み
flowchart LR
RS["ReplicaSet\nreplicas: 3"] -->|"監視"| CHECK{"現在のPod数は?"}
CHECK -->|"2つ(不足)"| CREATE["Podを1つ作成"]
CHECK -->|"3つ(正常)"| OK["何もしない"]
CHECK -->|"4つ(過剰)"| DELETE["Podを1つ削除"]
CREATE --> RS
OK --> RS
DELETE --> RS
style RS fill:#3b82f6,color:#fff
style CREATE fill:#22c55e,color:#fff
style DELETE fill:#ef4444,color:#fff
ReplicaSetのYAML
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: web-rs
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
| フィールド | 説明 |
|---|---|
replicas |
維持するPodの数 |
selector |
管理対象のPodを特定するラベルセレクター |
template |
作成するPodのテンプレート |
重要:
selector.matchLabelsとtemplate.metadata.labelsは一致する必要があります。
ReplicaSetの自己修復
# ReplicaSetを作成
kubectl apply -f web-rs.yaml
# Pod一覧を確認(3つのPodが起動)
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# web-rs-abc12 1/1 Running 0 30s
# web-rs-def34 1/1 Running 0 30s
# web-rs-ghi56 1/1 Running 0 30s
# Podを1つ削除してみる
kubectl delete pod web-rs-abc12
# すぐに新しいPodが作成される!
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# web-rs-def34 1/1 Running 0 2m
# web-rs-ghi56 1/1 Running 0 2m
# web-rs-xyz78 1/1 Running 0 5s ← 新しいPod
Deployment
実際の運用では、ReplicaSetを直接作成せず、Deploymentを使います。DeploymentはReplicaSetを管理し、さらにローリングアップデートとロールバックの機能を提供します。
DeploymentのYAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deployment
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "250m"
memory: "256Mi"
ReplicaSetとほぼ同じ構造ですが、
kind: Deploymentに変わっています。
Deploymentの作成と確認
# Deploymentの作成
kubectl apply -f web-deployment.yaml
# Deployment一覧
kubectl get deployments
# NAME READY UP-TO-DATE AVAILABLE AGE
# web-deployment 3/3 3 3 30s
# ReplicaSetも自動的に作成される
kubectl get replicasets
# NAME DESIRED CURRENT READY AGE
# web-deployment-7f8b9c6d4 3 3 3 30s
# Podも3つ起動
kubectl get pods
# NAME READY STATUS RESTARTS AGE
# web-deployment-7f8b9c6d4-abc12 1/1 Running 0 30s
# web-deployment-7f8b9c6d4-def34 1/1 Running 0 30s
# web-deployment-7f8b9c6d4-ghi56 1/1 Running 0 30s
flowchart TB
D["Deployment\nweb-deployment"] --> RS["ReplicaSet\nweb-deployment-7f8b9c6d4"]
RS --> P1["Pod\nweb-deployment-7f8b9c6d4-abc12"]
RS --> P2["Pod\nweb-deployment-7f8b9c6d4-def34"]
RS --> P3["Pod\nweb-deployment-7f8b9c6d4-ghi56"]
style D fill:#8b5cf6,color:#fff
style RS fill:#3b82f6,color:#fff
ローリングアップデート
Deploymentの最大の利点は、ゼロダウンタイムでアプリケーションを更新できることです。
アップデートの実行
# イメージを更新
kubectl set image deployment/web-deployment web=nginx:1.27-alpine
# または、YAMLを編集して適用
kubectl apply -f web-deployment.yaml
# アップデートの進捗を確認
kubectl rollout status deployment/web-deployment
# Waiting for deployment "web-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
# Waiting for deployment "web-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
# deployment "web-deployment" successfully rolled out
ローリングアップデートの流れ
flowchart TB
subgraph Step1["ステップ 1"]
RS1a["旧 ReplicaSet\n(3 Pod)"]
RS2a["新 ReplicaSet\n(0 Pod)"]
end
subgraph Step2["ステップ 2"]
RS1b["旧 ReplicaSet\n(2 Pod)"]
RS2b["新 ReplicaSet\n(1 Pod)"]
end
subgraph Step3["ステップ 3"]
RS1c["旧 ReplicaSet\n(1 Pod)"]
RS2c["新 ReplicaSet\n(2 Pod)"]
end
subgraph Step4["ステップ 4"]
RS1d["旧 ReplicaSet\n(0 Pod)"]
RS2d["新 ReplicaSet\n(3 Pod)"]
end
Step1 --> Step2 --> Step3 --> Step4
style RS1a fill:#f59e0b,color:#fff
style RS1b fill:#f59e0b,color:#fff
style RS1c fill:#f59e0b,color:#fff
style RS1d fill:#f59e0b,color:#fff
style RS2a fill:#22c55e,color:#fff
style RS2b fill:#22c55e,color:#fff
style RS2c fill:#22c55e,color:#fff
style RS2d fill:#22c55e,color:#fff
アップデート戦略の設定
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 追加で作成できるPod数
maxUnavailable: 1 # 一度に停止できるPod数
| パラメータ | 説明 | デフォルト |
|---|---|---|
maxSurge |
replicasを超えて作成できるPodの数(または割合) | 25% |
maxUnavailable |
更新中に利用不可にできるPodの数(または割合) | 25% |
ロールバック
アップデートに問題があった場合、簡単に前のバージョンに戻せます。
# ロールアウト履歴の確認
kubectl rollout history deployment/web-deployment
# REVISION CHANGE-CAUSE
# 1 <none>
# 2 <none>
# 特定のリビジョンの詳細
kubectl rollout history deployment/web-deployment --revision=2
# 直前のバージョンにロールバック
kubectl rollout undo deployment/web-deployment
# 特定のリビジョンにロールバック
kubectl rollout undo deployment/web-deployment --to-revision=1
# ロールアウトの一時停止・再開
kubectl rollout pause deployment/web-deployment
kubectl rollout resume deployment/web-deployment
スケーリング
手動スケーリング
# レプリカ数を変更
kubectl scale deployment/web-deployment --replicas=5
# 確認
kubectl get deployment web-deployment
# NAME READY UP-TO-DATE AVAILABLE AGE
# web-deployment 5/5 5 5 10m
YAMLでスケーリング
spec:
replicas: 5 # 3から5に変更
kubectl apply -f web-deployment.yaml
Deploymentの全体像
実践的なDeploymentの完全な例です。
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: web
version: v1.0
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "250m"
memory: "256Mi"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 5
| 設定 | 値 | 意味 |
|---|---|---|
replicas: 3 |
3 | 常に3つのPodを維持 |
maxSurge: 1 |
1 | 更新中、最大4つまでPodを起動 |
maxUnavailable: 0 |
0 | 更新中もダウンタイムなし |
まとめ
| 概念 | 説明 |
|---|---|
| ReplicaSet | 指定数のPodレプリカを維持するリソース |
| Deployment | ReplicaSetを管理し、ローリングアップデート・ロールバックを提供 |
| ローリングアップデート | 段階的にPodを更新し、ゼロダウンタイムを実現 |
| ロールバック | 問題発生時に前のバージョンに戻す機能 |
| スケーリング | レプリカ数を変更してPod数を増減 |
重要ポイント
- 本番環境ではPodを直接作成せず、Deploymentを使う
- Deploymentはローリングアップデートにより、ダウンタイムなしでアプリを更新できる
maxUnavailable: 0に設定すれば、更新中もサービスが中断しない
練習問題
問題1: 基本
以下の要件でDeploymentを作成するYAMLを書いてください。
- 名前:
api-server - イメージ:
node:20-alpine - レプリカ数: 3
- CPUリクエスト: 200m、リミット: 500m
問題2: アップデート
作成したDeploymentのイメージをnode:22-alpineに更新し、ローリングアップデートの進捗を確認してください。その後、ロールバックを実行してください。
チャレンジ問題
maxSurge: 0, maxUnavailable: 1とmaxSurge: 1, maxUnavailable: 0の違いを実際に試して、アップデートの挙動の違いを観察してください。
参考リンク
次回予告: Day 5では「Serviceによるネットワーキング」について学びます。Pod間の通信や外部からのアクセスをServiceで管理する方法を習得しましょう。