Day 9: スケーリングとアップデート戦略
今日学ぶこと
- Horizontal Pod Autoscaler(HPA)による自動スケーリング
- Vertical Pod Autoscaler(VPA)の概要
- Blue/GreenデプロイメントとCanaryデプロイメント
- StatefulSetの基本
自動スケーリング
Day 4で手動スケーリング(kubectl scale)を学びましたが、Kubernetesは負荷に応じて自動でPod数を調整する仕組みも提供しています。
flowchart TB
subgraph Scaling["スケーリングの種類"]
HPA["Horizontal Pod Autoscaler\n(Pod数を増減)"]
VPA["Vertical Pod Autoscaler\n(リソース量を増減)"]
CA["Cluster Autoscaler\n(ノード数を増減)"]
end
style HPA fill:#3b82f6,color:#fff
style VPA fill:#8b5cf6,color:#fff
style CA fill:#22c55e,color:#fff
| 種類 | 対象 | 説明 |
|---|---|---|
| HPA | Pod数 | CPU/メモリ使用率に応じてレプリカ数を自動調整 |
| VPA | リソース量 | Podのrequests/limitsを自動調整 |
| Cluster Autoscaler | ノード数 | クラスタのノード数を自動調整(クラウド環境) |
Horizontal Pod Autoscaler(HPA)
HPAは、CPU使用率やカスタムメトリクスに基づいてDeploymentのレプリカ数を自動的に増減します。
前提: Metrics Server
HPAにはMetrics Serverが必要です。
# Metrics Serverの確認
kubectl top nodes
kubectl top pods
# Minikubeの場合
minikube addons enable metrics-server
# Docker Desktopの場合は通常プリインストール済み
HPAの作成
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70
# コマンドでも作成可能
kubectl autoscale deployment web-app \
--min=2 --max=10 --cpu-percent=50
HPAの動作
flowchart LR
MS["Metrics Server"] -->|"メトリクス取得"| HPA["HPA"]
HPA -->|"CPU > 50%"| UP["スケールアップ\n(Pod数を増加)"]
HPA -->|"CPU < 50%"| DOWN["スケールダウン\n(Pod数を減少)"]
UP --> DEP["Deployment"]
DOWN --> DEP
style HPA fill:#3b82f6,color:#fff
style UP fill:#22c55e,color:#fff
style DOWN fill:#f59e0b,color:#fff
HPAの確認と負荷テスト
# HPAの状態確認
kubectl get hpa
# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
# web-hpa Deployment/web-app 10%/50% 2 10 2 5m
# 詳細確認
kubectl describe hpa web-hpa
# 負荷をかけてスケーリングを確認
kubectl run load-test --image=busybox:1.37 --rm -it -- \
/bin/sh -c "while true; do wget -q -O- http://web-service; done"
# 別ターミナルでHPAの変化を監視
kubectl get hpa -w
HPAのパラメータ
| パラメータ | 説明 |
|---|---|
minReplicas |
最小レプリカ数 |
maxReplicas |
最大レプリカ数 |
averageUtilization |
目標使用率(%) |
scaleDown.stabilizationWindowSeconds |
スケールダウン前の安定化期間(デフォルト300秒) |
HPAを使用するDeploymentのPodには必ず
resources.requestsを設定してください。
アップデート戦略
Day 4で学んだローリングアップデート以外にも、いくつかのデプロイメント戦略があります。
1. Recreate(再作成)
全てのPodを停止してから新しいPodを起動します。ダウンタイムが発生します。
spec:
strategy:
type: Recreate
2. Rolling Update(ローリングアップデート)
Day 4で学んだ方式。段階的にPodを更新します(デフォルト)。
3. Blue/Green デプロイメント
Kubernetesのネイティブ機能ではありませんが、ServiceのラベルセレクターとDeploymentを使って実現できます。
flowchart TB
SVC["Service\nselector: version=green"]
subgraph Blue["Blue (旧バージョン)"]
B1["Pod v1"]
B2["Pod v1"]
end
subgraph Green["Green (新バージョン)"]
G1["Pod v2"]
G2["Pod v2"]
end
SVC -->|"切り替え"| Green
style Blue fill:#3b82f6,color:#fff
style Green fill:#22c55e,color:#fff
style SVC fill:#8b5cf6,color:#fff
# blue-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: app
image: myapp:1.0
---
# green-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: app
image: myapp:2.0
---
# service.yaml(Blue/Green切り替え)
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp
version: blue # green に変更して切り替え
ports:
- port: 80
# Blue → Greenに切り替え
kubectl patch service app-service -p '{"spec":{"selector":{"version":"green"}}}'
# 問題があればBlueに戻す
kubectl patch service app-service -p '{"spec":{"selector":{"version":"blue"}}}'
4. Canary デプロイメント
新バージョンを少数のPodで試験的に公開し、問題がなければ徐々に拡大する戦略です。
flowchart TB
SVC["Service\nselector: app=myapp"]
subgraph Stable["Stable (90%)"]
S1["Pod v1"]
S2["Pod v1"]
S3["Pod v1"]
S4["Pod v1"]
S5["Pod v1"]
S6["Pod v1"]
S7["Pod v1"]
S8["Pod v1"]
S9["Pod v1"]
end
subgraph Canary["Canary (10%)"]
C1["Pod v2"]
end
SVC --> Stable
SVC --> Canary
style Stable fill:#3b82f6,color:#fff
style Canary fill:#f59e0b,color:#fff
# stable-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-stable
spec:
replicas: 9
selector:
matchLabels:
app: myapp
track: stable
template:
metadata:
labels:
app: myapp
track: stable
spec:
containers:
- name: app
image: myapp:1.0
---
# canary-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 1
selector:
matchLabels:
app: myapp
track: canary
template:
metadata:
labels:
app: myapp
track: canary
spec:
containers:
- name: app
image: myapp:2.0
---
# service.yaml(両方のDeploymentに送る)
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp # trackは指定しない → 両方にルーティング
ports:
- port: 80
デプロイメント戦略の比較
| 戦略 | ダウンタイム | ロールバック | リソース | 複雑さ |
|---|---|---|---|---|
| Recreate | あり | 遅い | 少 | 低 |
| Rolling Update | なし | 自動 | 中 | 低 |
| Blue/Green | なし | 瞬時 | 倍 | 中 |
| Canary | なし | 瞬時 | 少し多い | 高 |
StatefulSet
これまでのDeploymentはステートレスなアプリケーション向けでした。データベースやメッセージキューなどのステートフルなアプリケーションにはStatefulSetを使います。
DeploymentとStatefulSetの違い
| 特性 | Deployment | StatefulSet |
|---|---|---|
| Pod名 | ランダム(app-7f8b-abc) | 連番(app-0, app-1, app-2) |
| 起動順序 | 並行 | 順番(0 → 1 → 2) |
| ストレージ | 共有PVC | Pod固有のPVC |
| ネットワーク | ランダムIP | 安定したDNS名 |
StatefulSetの例
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres-headless
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:17
ports:
- containerPort: 5432
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
---
# Headless Service(StatefulSetに必要)
apiVersion: v1
kind: Service
metadata:
name: postgres-headless
spec:
clusterIP: None
selector:
app: postgres
ports:
- port: 5432
StatefulSetのPodは安定したDNS名を持ちます:
postgres-0.postgres-headless.default.svc.cluster.localpostgres-1.postgres-headless.default.svc.cluster.localpostgres-2.postgres-headless.default.svc.cluster.local
まとめ
| 概念 | 説明 |
|---|---|
| HPA | CPU/メモリに基づくPod数の自動スケーリング |
| VPA | Podのリソース量の自動調整 |
| Blue/Green | 2つの環境を切り替えるデプロイメント戦略 |
| Canary | 少数のPodで新バージョンを試験的に公開 |
| StatefulSet | ステートフルアプリケーション用のコントローラー |
重要ポイント
- HPAを使えば負荷に応じてPod数が自動調整される。
resources.requestsの設定が必須 - Blue/Greenは瞬時の切り替え、Canaryは段階的なリリースに適している
- データベースなどステートフルなアプリケーションにはStatefulSetを使う
練習問題
問題1: HPA
WebアプリのDeploymentにHPAを設定してください。CPU使用率50%で2〜8Podの範囲でスケーリングするようにしましょう。
問題2: Blue/Green
2つのバージョンのアプリ(nginx:1.26とnginx:1.27)でBlue/Greenデプロイメントを実装し、Serviceの切り替えを試してください。
チャレンジ問題
StatefulSetでRedisの3ノードクラスタを構成してください。各Podが固有のPVCを持ち、安定したDNS名でアクセスできることを確認しましょう。
参考リンク
次回予告: Day 10では「本番環境への準備とベストプラクティス」について学びます。Namespace、RBAC、リソース管理、モニタリング、そして本番運用のための総合的なベストプラクティスを習得しましょう。