0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Kubernetes②(全7回)|minikube|Pod・ReplicaSet・Deployment徹底理解

0
Last updated at Posted at 2026-02-18

シリーズ記事一覧

📑 目次

  1. この記事について
  2. この記事のゴール
  3. 前提条件
  4. Podとは?
  5. ReplicaSetとは?
  6. Deploymentとは?
  7. Deployment YAMLの書き方
  8. ハンズオン:Deploymentを操作する
  9. まとめ

1. この記事について

1-1. シリーズ概要

Docker Compose経験者が「素のKubernetes」を
1週間で実践レベルまで習得する
ことを目指す学習記録です。

1-2. シリーズ構成

テーマ 内容
第1回 全体像と環境構築 Docker Composeとの対比、minikube導入
第2回(本記事) Pod と Deployment コンテナ起動〜スケーリング〜ローリングアップデート
第3回 Service と Ingress ネットワークと外部公開
第4回 ConfigMap / Secret / PV 設定管理と永続化
第5回 模擬プロジェクト 全概念を組み合わせて実践
第6回 トラブルシュートと運用 エラー対応、ログ確認
第7回 総まとめ 振り返り

1-3. 対象読者

  • 第1回を読み終えた方(k8sの全体像・minikube環境構築済み)
  • Docker Composeの servicesscale を使ったことがある方
  • 「Podって何?Deploymentとの違いは?」が曖昧な方

2. この記事のゴール

# ゴール チェック
Pod・ReplicaSet・Deploymentの3層構造を説明できる 各層の役割と関係を言語化
ローリングアップデートの仕組みを説明できる maxSurge/maxUnavailableの動きを図示
ロールバックの履歴管理を理解している revision番号の振り直しを説明できる
Deployment YAMLを読み書きできる DockerComposeとの対比で各フィールドを説明
labels/selectorの仕組みを説明できる なぜ必要か、どこで使われるかを語れる

3. 前提条件

3-1. 環境情報

項目 バージョン / 詳細
OS Windows 11 + WSL2 Ubuntu
minikube インストール済み(第1回で構築)
kubectl インストール済み(第1回で構築)

3-2. 前提知識

  • 第1回の内容(k8sの全体像、各コンポーネントの役割)
  • Docker Composeの services image ports scale の意味

4. Podとは?

4-1. 一言で言うと

Podはk8sでコンテナを動かす最小単位です。

観点 Docker Compose k8s
最小単位 コンテナ(container) Pod
定義場所 services: の中 Pod用のYAML
1つの中身 1コンテナ 1つ以上のコンテナ(通常は1つ)

4-2. 🍽️飲食チェーンで例えると

🍽️ コンテナ = 料理人Pod = 調理台

  • 基本は1つの調理台に1人の料理人(1 Pod = 1コンテナ)
  • まれに、2人で1つの調理台を共有することもある(サイドカーパターン)
    • 例:メインの料理人 + 横で盛り付け専門の人
  • 調理台(Pod)が壊れたら、料理人(コンテナ)も一緒にいなくなる

4-3. なぜ「コンテナ」ではなく「Pod」?

疑問 答え
なぜコンテナを直接管理しない? 複数コンテナをセットで扱いたいケースがあるから
具体的にどんなケース? メインアプリ + ログ収集コンテナ、
メインアプリ + プロキシ等
でも普段は? 99%のケースで1 Pod = 1コンテナ
まずはこれで覚えてOK

4-4. Podの重要な特性

特性 意味 影響
使い捨て Podはいつでも削除・再作成される Pod内にデータを保存してはいけない
IPアドレスが変わる 再作成のたびに新しいIPが振られる IPで直接通信してはいけない
(→ Serviceで解決、第3回)
1 Pod = 1プロセスグループ 同じPod内のコンテナは、
ネットワーク・ストレージを共有
localhost で通信可能

🍽️ Podは 「紙皿」
汚れたら捨てて新しいのを出す。
陶器の皿(永続サーバー)のように大事に使い続けるものではない。


5. ReplicaSetとは?

5-1. 一言で言うと

ReplicaSetは「Podを指定した数だけ維持するコントローラー」

観点 Docker Compose k8s
台数指定 docker-compose up --scale web=3 ReplicaSet の replicas: 3
台数の維持 しない(落ちたら落ちたまま) 自動で維持する
管理対象 コンテナ Pod

5-2. 🍽️飲食チェーンで例えると?

🍽️ Pod = 店員ReplicaSet = シフト管理表

「この店舗は常に3人体制」とシフト表に書いておく。

  • 1人休んだら → 代わりの人を自動で呼ぶ
  • 多すぎたら → 1人帰らせる
  • シフト表に書かれた人数を常にキープするのがReplicaSetの仕事

5-3. ReplicaSetの動き

5-4. 数を維持する仕組み:Reconciliation Loop

ReplicaSet は、「理想と現実を常に比較し続ける」ループで動いています。

🍽️ 巡回マネージャーの日常:

  1. シフト表を見る →「渋谷店は3人体制のはず」
  2. 渋谷店を確認 →「今何人いる?」
  3. 比較する → OK or 補充 or 帰らせる
  4. 次の店舗へ…そしてまた渋谷店に戻ってくる
    これを永遠に繰り返す。

5-5. 具体的なシナリオ

5-5-1. Podがクラッシュした場合

時刻 理想 現実 判断 アクション
10:00 3 3 一致 何もしない
10:01 3 2(Pod C死亡) 不足 Pod D を作成
10:02 3 3(Pod D起動完了) 一致 何もしない

5-5-2. replicas を3→5に変更した場合

時刻 理想 現実 判断 アクション
10:00 3 3 一致 何もしない
10:01 5(YAML変更) 3 不足 Pod D, E を作成
10:02 5 5 一致 何もしない

5-6. Docker Composeとの決定的な違い

観点 🚫Docker Compose ✅k8s(ReplicaSet)
台数指定 docker-compose up --scale web=3 replicas: 3
落ちた時 落ちたまま。手動で再起動 自動で補充
監視 なし(自分で確認) 常時監視(Reconciliation Loop)

🚫Docker Compose = 掲示板に「3人体制」と貼るだけ。誰も見てない。
✅k8s = 巡回マネージャーが24時間体制で見回って、3人を維持してくれる。

5-7. 重要:ReplicaSetは直接使わない

疑問 答え
ReplicaSetを直接作るの? いいえ。Deploymentが自動で作ってくれる
じゃあなぜ学ぶ? Deploymentの中身を理解するため

6. Deploymentとは?

6-1. 一言で言うと

DeploymentはReplicaSetを管理し、
さらに「アプリのバージョン更新」を安全に行うコントローラー

観点 ReplicaSet Deployment
Podの数を維持 ✅ できる ✅ できる(ReplicaSet経由)
アプリのバージョン更新 ❌ できない ローリングアップデート
ロールバック(巻き戻し) ❌ できない 前のバージョンに戻せる
実務で使うか 直接は使わない ★これを使う★

6-2. 3層構造

役割 🍽️飲食チェーン比喩
Deployment アプリのバージョン管理 + ReplicaSet管理 店舗マネージャー
ReplicaSet 指定数のPodを維持 シフト管理表
Pod 実際にコンテナが動く 店員

6-3. ローリングアップデート

6-3-1. 全体フロー図

アプリを v1→v2 に更新する時、
DeploymentはPodを1つずつ安全に入れ替えます
サービス停止ゼロで更新完了。

🍽️飲食チェーン:
❌ 危険な方法 = 全店同時に閉店 → 改装 → 全店同時に再開
✅ ローリングアップデート = 1店舗ずつ順番に改装。残りの店舗が営業を続ける。

6-3-2. 分割版フロー図:3つのフェーズで理解する

上の流れを 「開始→入れ替え中→完了」 の3フェーズに分けて見てみます。

Phase 1/更新の開始 — 新ReplicaSetの作成と最初のv2起動(①〜③)

🍽️ オーナーが、
「新メニューに切り替えて」と指示 → 本部が新メニュー担当チームを1人配置するまで

Phase 2/段階的な入れ替え — v1縮小とv2拡大を交互に繰り返す(④〜⑨)

🍽️ 旧メニュー担当を1人ずつ帰し、新メニュー担当を1人ずつ配置。
常に店舗は営業中。

Phase 3/入れ替え完了 — 旧ReplicaSetの停止(⑪〜⑫)

🍽️ 旧メニュー担当が全員退勤。
新メニュー3人体制で営業再開完了。お客さんは一度も待たされていない。

6-4. ローリングアップデートの制御:maxSurge / maxUnavailable

入れ替えの「速さと安全性」を制御する2つのパラメータです。

パラメータ 意味 デフォルト
maxSurge 理想数を超えて同時に存在できるPod数 25%
maxUnavailable 理想数を下回って良いPod数 25%

🍽️ 3人体制の店舗でスタッフを入れ替える場面:

  • maxSurge = 「一時的に何人まで多くてOK?」
  • maxUnavailable = 「一時的に何人まで少なくてOK?」

6-4-1. パターン比較(replicas: 3)

パターン maxSurge maxUnavailable 特徴
安全重視 1 0 常に3つ以上を維持
新Podを先に起動
速度重視 1 1 起動と停止を同時実行
一瞬2つになる
リソース節約 0 1 追加Pod不要
先に停止してから起動

🔰 ネットワークエンジニア的な対比:

  • maxSurge:1, maxUnavailable:0 → Make-before-break(新経路確立→旧経路切断)
  • maxSurge:0, maxUnavailable:1 → Break-before-make(旧経路切断→新経路確立)

6-4-2. デフォルト25%の計算例

端数処理ルール:maxSurge は切り上げ、maxUnavailable は切り捨て

replicas maxSurge(25%) maxUnavailable(25%) 最大Pod数 最小稼働数
1 1(0.25→切り上げ→1) 0(0.25→切り捨て→0) 2 1
3 1(0.75→切り上げ→1) 0(0.75→切り捨て→0) 4 3
4 1(1.0→そのまま) 1(1.0→そのまま) 5 3
10 3(2.5→切り上げ→3) 2(2.5→切り捨て→2) 13 8
100 25(25.0→そのまま) 25(25.0→そのまま) 125 75

🔰 注目:
replicas:3 だとmaxUnavailableが0になる。
つまり「1つも減らせない」ので、
必ず先に新Podを起動してから旧Podを停止する安全な動きになる。

⚠️ 注意:
maxSurge:0 かつ maxUnavailable:0 は、
デッドロック(増やせない、減らせない → 入れ替え不可能)になるため設定不可です。

6-5. ロールバック:前のバージョンに戻す

Deploymentは旧ReplicaSetを削除しないで残しているため、すぐに前のバージョンに戻せます。

🍽️ 新メニューが不評だった → 「旧メニューの印刷物は倉庫に保管してある」→ すぐ旧メニューに戻せる。

# 更新履歴一覧を確認
kubectl rollout history deployment/web-app

# 1つ前に戻す
kubectl rollout undo deployment/web-app

# 特定のrevisionに戻す
kubectl rollout undo deployment/web-app --to-revision=1

6-6. revision番号の振り直し

ロールバック時のrevision番号の動きは直感に反するため注意が必要だと思います。

操作 やったこと revision 1 revision 2 revision 3 revision 4
① 初回デプロイ nginx:1.19 RS-A(稼働中) - - -
② v2に更新 nginx:1.20 RS-A(待機) RS-B(稼働中) - -
③ v3に更新 nginx:1.21 RS-A(待機) RS-B(待機) RS-C(稼働中) -
④ v2にロールバック undo --to-revision=2 RS-A(待機) 消滅 RS-C(待機) RS-B(稼働中)

ポイント:

ルール 説明
revision番号は常に増加 巻き戻しても番号は進む。「rev 2に戻す」≠「rev番号が2に戻る」
使ったrevisionは最新番号に昇格 RS-Bがrevision 2 → revision 4に移動
旧revision番号は消滅 revision 2の枠は空(欠番)になる

🍽️「冬メニューから春メニューに戻す」場合
「改定2に戻す」ではなく「春メニューを改定4として再採用した」

🔰 gitで例えると:
git revert に近い(過去の状態に戻すが履歴は進む)。
ただし仕組みは異なり、既存のReplicaSetを再昇格させる(新しい「打ち消し」は作らない)。revision番号は進む。

6-6-1. 履歴保持数の制限

設定 デフォルト値 意味
revisionHistoryLimit 10 保持するReplicaSetの数
spec:
  revisionHistoryLimit: 5  # 直近5世代まで保持

🍽️ 倉庫のスペースには限りがある。
「直近の10版分のメニューだけ保管、それ以前は廃棄」→ 古すぎバージョンには戻せなくなる。

6-7. Docker Composeとの最終比較

やりたいこと Docker Compose k8s Deployment
コンテナ起動 docker-compose up kubectl apply -f deployment.yaml
台数変更 --scale web=5 replicas: 5 に変更 → apply
バージョン更新 イメージ変更 → up -d瞬断あり イメージ変更 → apply → ゼロダウンタイム
元に戻す 手動でイメージを戻して再起動 kubectl rollout undo1コマンド
自動復旧 なし Podが落ちたら自動復旧

7. Deployment YAMLの書き方

7-1. Docker Compose と k8s YAML の対比

やりたいこと: nginxコンテナを3つ起動

7-1-1. Docker Compose

# docker-compose.yml

version: '3.8'
services:
  web:
    image: nginx:1.21
    ports:
      - "80:80"
    deploy:
      replicas: 3

7-1-2. k8s Deployment

# deployment.yaml

apiVersion: apps/v1        # どのAPIバージョンを使うか
kind: Deployment            # リソースの種類
metadata:                   # このリソースの名前やラベル
  name: web-app
spec:                       # Deploymentの仕様
  replicas: 3               # Pod数
  selector:                 # 管理対象のPodを特定する条件
    matchLabels:
      app: web
  strategy:                 # 更新戦略
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:                 # Podのテンプレート(設計図)
    metadata:
      labels:               # Podに貼るラベル
        app: web
    spec:                   # Podの中身
      containers:
        - name: nginx       # コンテナ名
          image: nginx:1.21 # コンテナイメージ
          ports:
            - containerPort: 80  # コンテナのポート

7-2. 対応マップ

DockerCompose k8s Deployment 備考
services: web: kind: Deployment + metadata.name リソースの定義
image: spec.template.spec.containers[].image 同じ
ports: containerPort: k8sでは外部公開は別(Service、第3回)
replicas: spec.replicas 同じ概念
(なし) selector + labels k8s特有。重要
(なし) strategy k8s特有。ローリングアップデート制御

7-3. YAMLの全体構造マップ

7-4. k8s特有の重要概念:labels と selector

7-4-1. labelsとは?

キー:値のペアで、k8sのあらゆるリソースに貼れるタグです。

metadata:
  labels:
    app: web           # アプリ名
    env: production    # 環境
    team: backend      # チーム
    version: v2        # バージョン

🍽️ labels = 店員に貼る複数のネームプレート
「所属:ホール」「店舗:渋谷」「スキル:バリスタ」「シフト:朝番」
複数のプレートを組み合わせて「渋谷店のホール担当で朝番の人」と検索できる

7-4-2. selectorとは?

labelsを使って「どのリソースを管理対象にするか」を指定する仕組みです。

selector:
  matchLabels:
    app: web    # 「app=web」のPodを管理対象にする

7-4-3. なぜ DockerCompose では不要だった?

疑問 答え
DockerComposeでは? services: web: という名前で1対1対応が暗黙的に決まる
k8sでは? 大量のPodが混在する。「誰が誰を管理するか」を明示する必要がある
selectorとlabelsが一致しないと? Deploymentがどのpodも管理できず、エラーになる

7-4-4. labels/selector が使われる場面は?

Deploymentだけの仕組みではなく、k8s全体を貫く仕組みです。

使う側 何のために selector を使う 学ぶ回(記事)
Deployment 管理対象のPodを特定 第2回(本記事)
ReplicaSet 数を維持するPodを特定 第2回(本記事)
Service 通信を振り分けるPodを特定 第3回
NetworkPolicy 通信を許可するPodを特定 第3回〜4回

🍽️ labelsは「店員のネームプレート」だが、読む人がたくさんいる:

  • シフト管理表(Deployment/ReplicaSet)→ 「ホール担当を3人維持」
  • 電話交換台(Service)→ 「ホール担当に電話を振り分ける」
  • セキュリティ(NetworkPolicy)→ 「ホール担当は厨房には入れない」

7-4-5. 実務でよく使うlabelパターンは?

ラベルキー 用途
app アプリケーション名 app: web, app: api
env 環境 env: production, env: staging
version バージョン version: v2, version: canary
team 担当チーム team: backend, team: infra
tier アーキテクチャ層 tier: frontend, tier: backend

7-4-6. ⚠️ 実務テクニック:labelを手動で剥がしてデバッグ

問題のあるPodのlabelを外すと、Deploymentの管理から外れます。
代わりの健全なPodが自動で補充されつつ、問題のPodは調査用に残せます。

# Pod Aのlabelを剥がす
kubectl label pod web-app-xxx app-

# 結果:
# - Pod A は管理外になる(でもまだ動いてる)
# - Deploymentは「Podが足りない」と判断して新しいPod Dを作成

🍽️ 店員Aのネームプレート(「ホール担当」)を外した → シフト管理表は「ホール担当が足りない!」と新人Dを補充 → Aは「誰の管理下でもない野良スタッフ」として調査可能


8. ハンズオン:Deploymentを操作する

8-1. 作業ディレクトリ

# ホームディレクトリで実行
cd ~
mkdir -p k8s-practice/pod-deployment
cd k8s-practice/pod-deployment

8-2. この記事で作成するファイル

~/k8s-practice/
└── pod-deployment/           ← 今回はここ
    └── deployment.yaml

8-3. Deployment YAMLの作成

# deployment.yaml

# Deployment: nginxコンテナを3つ起動
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.21
          ports:
            - containerPort: 80

8-4. Deploymentの作成と確認

# Deploymentを作成
kubectl apply -f deployment.yaml

期待される出力:

deployment.apps/web-app created
# Deploymentの状態を確認
kubectl get deployment web-app

期待される出力:

NAME      READY   UP-TO-DATE   AVAILABLE   AGE
web-app   3/3     3            3           30s

🔰 出力の読み方:

意味 今回の値
READY 準備完了のPod数/理想数 3/3(全部OK)
UP-TO-DATE 最新テンプレートで動いてるPod数 3
AVAILABLE 利用可能なPod数 3
# Pod一覧を確認
kubectl get pods -l app=web

期待される出力:

NAME                       READY   STATUS    RESTARTS   AGE
web-app-xxxxxxxxx-xxxxx    1/1     Running   0          30s
web-app-xxxxxxxxx-yyyyy    1/1     Running   0          30s
web-app-xxxxxxxxx-zzzzz    1/1     Running   0          30s
# ReplicaSetも自動で作られていることを確認
kubectl get replicaset

期待される出力:

NAME                 DESIRED   CURRENT   READY   AGE
web-app-xxxxxxxxx    3         3         3       30s

8-5. スケーリングを試す

# 3→5にスケールアップ
kubectl scale deployment web-app --replicas=5

# Pod数を確認
kubectl get pods -l app=web

期待される出力: Podが5つに増えている。

# 5→2にスケールダウン
kubectl scale deployment web-app --replicas=2

# Pod数を確認
kubectl get pods -l app=web

期待される出力: Podが2つに減っている。

# 元の3に戻す
kubectl scale deployment web-app --replicas=3

8-6. ローリングアップデートを試す

# イメージを nginx:1.21 → nginx:1.22 に更新
kubectl set image deployment/web-app nginx=nginx:1.22

# ロールアウトの状況をリアルタイム確認
kubectl rollout status deployment/web-app

期待される出力:

Waiting for deployment "web-app" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "web-app" rollout to finish: 2 out of 3 new replicas have been updated...
deployment "web-app" successfully rolled out
# 更新履歴を確認
kubectl rollout history deployment/web-app

8-7. ロールバックを試す

# 1つ前のバージョンに戻す
kubectl rollout undo deployment/web-app

# 戻ったことを確認
kubectl describe deployment web-app | grep Image

期待される出力:

    Image:      nginx:1.21

8-8. お片付け

# Deploymentを削除(関連するReplicaSet、Podも全て削除される)
kubectl delete deployment web-app

# 確認
kubectl get all

9. まとめ

9-1. 本記事で学んだこと

# 学んだこと キーポイント
Podの基本 k8sの最小単位。使い捨て。99%は1 Pod = 1コンテナ
ReplicaSetの仕組み Reconciliation Loopで指定数を常時維持
Deploymentの3層構造 Deployment → ReplicaSet → Pod の階層で管理
ローリングアップデート ゼロダウンタイムでバージョン更新。maxSurge/maxUnavailableで制御
ロールバック 旧ReplicaSetを保持。1コマンドで巻き戻し。revision番号は常に増加
labels/selector k8s全体を貫くタグ付けと検索の仕組み

9-2. ゴールの達成確認

# ゴール 達成状況
3層構造を説明できる ✅ セクション6-2で解説
ローリングアップデートを説明できる ✅ セクション6-3, 6-4で解説
ロールバックの履歴管理を理解している ✅ セクション6-5, 6-6で解説
Deployment YAMLを読み書きできる ✅ セクション7で解説
labels/selectorを説明できる ✅ セクション7-4で解説

9-3. 次回予告

第3回:Service と Ingress でネットワークを理解する

次回は、Podへの通信経路を作るServiceと、外部からのアクセスを制御するIngressを学びます。Docker Composeの ports に対応する概念ですが、k8sではより柔軟で強力な仕組みになっています。


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?