10日で覚えるKubernetesDay 4: ReplicaSetとDeployment
books.chapter 410日で覚えるKubernetes

Day 4: ReplicaSetとDeployment

今日学ぶこと

  • ReplicaSetの仕組みとPodの冗長化
  • Deploymentによるアプリケーション管理
  • ローリングアップデートとロールバック
  • スケーリングの基本操作

なぜPodを直接作成しないのか

Day 3でPodを直接作成しましたが、本番環境ではPodを単体で作成することはほぼありません。理由は以下の通りです。

問題 説明
単一障害点 Podが1つだけだと、障害時にサービスが停止する
自動復旧なし 直接作成したPodは削除されると復活しない
スケーリング不可 手動で1つずつPodを作る必要がある
更新が困難 アプリ更新時にダウンタイムが発生する

この問題を解決するのがReplicaSetDeploymentです。

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.matchLabelstemplate.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数を増減

重要ポイント

  1. 本番環境ではPodを直接作成せず、Deploymentを使う
  2. Deploymentはローリングアップデートにより、ダウンタイムなしでアプリを更新できる
  3. maxUnavailable: 0に設定すれば、更新中もサービスが中断しない

練習問題

問題1: 基本

以下の要件でDeploymentを作成するYAMLを書いてください。

  • 名前: api-server
  • イメージ: node:20-alpine
  • レプリカ数: 3
  • CPUリクエスト: 200m、リミット: 500m

問題2: アップデート

作成したDeploymentのイメージをnode:22-alpineに更新し、ローリングアップデートの進捗を確認してください。その後、ロールバックを実行してください。

チャレンジ問題

maxSurge: 0, maxUnavailable: 1maxSurge: 1, maxUnavailable: 0の違いを実際に試して、アップデートの挙動の違いを観察してください。


参考リンク


次回予告: Day 5では「Serviceによるネットワーキング」について学びます。Pod間の通信や外部からのアクセスをServiceで管理する方法を習得しましょう。