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回)|kind|Pod / ReplicaSet / Deployment — コンテナ管理の3層構造を理解する

0
Last updated at Posted at 2026-02-18

シリーズ記事一覧

📑 目次

  1. この記事について
  2. この記事のゴール
  3. 前提条件
  4. Docker Composeではこうだった(Before)
  5. k8sではこうなる(After)
  6. ハンズオン:壊して学ぶ3層構造
  7. つまずきポイント(体験談)
  8. まとめ
  9. 次回予告

1. この記事について

前回、kindでKubernetesクラスタを構築しました。
チェーンレストランの「本部」を建てた状態です。

でもまだスタッフ(コンテナ)は配置していません

今回はコンテナを動かしてみます。
ただし、k8sでは docker run のようにコンテナを直接動かすのではなく、3層の仕組みを使います。

「コンテナ動かすだけなのに、なぜ3つも概念がいるの?」

私もそう思いました。
実際に壊して体験してみたら、その理由がよくわかりました。


2. この記事のゴール

この記事で書いていること:

  • Pod / ReplicaSet / Deployment の違いを整理
  • マニフェストYAMLの読み方
  • Podを削除して自動復旧を体験してみた話
  • スケールアウト・ローリングアップデートを試してみた話

3. 前提条件

項目 要件
前回の完了 第1回でkindクラスタを構築済み
クラスタ状態 起動中であること
# WSL2 Ubuntu で実行

# クラスタが動いているか確認
kubectl get nodes

期待される出力:

NAME                         STATUS   ROLES           AGE   VERSION
my-first-cluster-control-plane   Ready    control-plane   ...   v1.xx.x

❌ クラスタがない場合は、再作成してください:

kind create cluster --name my-first-cluster

4. Docker Composeではこうだった(Before)

4-1. Docker Composeのコンテナ管理

Docker Composeでは、services に書いたものがそのままコンテナになります。

# docker-compose.yml

services:
  web:
    image: nginx:1.25
    ports:
      - "8080:80"    # ホスト8080 → コンテナ80

シンプルで分かりやすい。
docker-compose up で起動、docker-compose down で停止。

4-2. でもこの壁がある

# コンテナが落ちたら…
docker-compose ps
# → web が Exit 1 になっている

# 手動で再起動するしかない
docker-compose restart web
困ること Docker Composeの現実
コンテナが落ちた 手動で再起動
3台に増やしたい docker-compose up --scale web=3… でもロードバランスは?
新バージョンに更新 止めて → 上げ直し(ダウンタイム発生)

5. k8sではこうなる(After)

5-1. なぜ「3層」必要なのか?

🍽️ 比喩:チェーンレストランの人材管理

コンテナ1個だけ動かすなら、概念は1つで十分です。
でも本番運用では「常に3台動かしたい」「新バージョンに切り替えたい」が出てくる。

これを人材管理に例えると…

k8s概念 比喩 責任
層1 Pod 調理スタッフ1人 実際に働く。倒れたらそれまで
層2 ReplicaSet シフト表 「常に3人体制」を保証。欠員が出たら補充
層3 Deployment 店長 シフト表の更新・メニュー切替を管理

スタッフ1人(Pod)だけだと、倒れたら終わり。
シフト表(ReplicaSet)があれば、自動で補充される。
店長(Deployment)がいれば、「来月から新メニュー」も段階的に切り替えてくれる。

5-2. 3層構造の関係図

この3層がどのような関係で動いているかを図で見てみましょう。

5-3. 各層の詳細

各層を詳しく見ていきます。

5-3-1. Pod(調理スタッフ1人)

項目 内容
定義 k8sの最小デプロイ単位
中身 1つ以上のコンテナ(通常は1つ)
特徴 IPアドレスを持つ、壊れたら消える(使い捨て)
Docker比較 docker run で起動するコンテナ1個に近い

🔰 Memo: 最初は「Pod ≒ コンテナ」と思っておけば大丈夫でした。
厳密には「コンテナを包む薄い箱」ですが、同じものとして扱って問題なかったです。

5-3-2. ReplicaSet(シフト表)

項目 内容
定義 「Podを常にN個維持する」ための仕組み
特徴 Podが減ったら自動補充、増えすぎたら削除
Docker比較 docker-compose up --scale に近いが、自動維持する

5-3-3. Deployment(店長)

項目 内容
定義 ReplicaSetを管理し、バージョン更新を制御
特徴 ローリングアップデート、ロールバック
Docker比較 Docker Composeにはこの概念がない

🔰 Note: 調べてみると、実務ではPodを直接作ることはほぼないそうです。
Deploymentを作れば、ReplicaSetとPodは自動で作られる。
つまり普段意識するのはDeploymentだけ、ということでした。


6. ハンズオン:壊して学ぶ3層構造

6-1. Step1:Podを直接作って、壊してみる(限界体験)

まず「Podだけだと何が困るか」を体験します。

# WSL2 Ubuntu で実行

# Pod を直接作成(nginx コンテナ)
kubectl run solo-pod --image=nginx:1.25

# Podが起動したか確認
kubectl get pods

期待される出力:

NAME       READY   STATUS    RESTARTS   AGE
solo-pod   1/1     Running   0          10s

では、このPodを意図的に壊します

# Podを削除
kubectl delete pod solo-pod

# もう一度確認
kubectl get pods

期待される出力:

No resources found in default namespace.

🔰 ここが重要: Podは消えたまま、誰も復活させてくれません。

🍽️ 調理スタッフが倒れたのに、シフト表がないから誰も代わりを呼ばない状態です。


6-2. Step2:Deploymentで作って、壊してみる(自動復旧体験)

次に、Deploymentを使って同じことをします。

6-2-1. マニフェストYAMLの作成

💡 マニフェスト(manifest) とは、「こういうリソースを作ってほしい」と k8s に伝えるための定義ファイルです。レストランの比喩でいえば 指示書 そのもの。YAML形式で書くので、本シリーズでは「マニフェストYAML」と呼びます。

# WSL2 Ubuntu で実行

# 作業ディレクトリを作成
mkdir -p ~/k8s-handson/pod-deployment
cd ~/k8s-handson/pod-deployment

以下のファイルを作成します:

~/k8s-handson/pod-deployment/
└── nginx-deployment.yaml   # ここに作成
# nginx-deployment.yaml
# Deployment = 店長への指示書

# API バージョンと種類の宣言
apiVersion: apps/v1
kind: Deployment

# Deploymentの名前
metadata:
  name: nginx-deployment

# Deploymentの仕様(店長への指示内容)
spec:
  # レプリカ数 = 「常に3人体制で」
  replicas: 3

  # どのPodを管理するか(ラベルで紐づけ)
  selector:
    matchLabels:
      app: nginx

  # Podのテンプレート(スタッフの募集要項)
  template:
    # Podに付けるラベル
    metadata:
      labels:
        app: nginx

    # Podの中身(コンテナの定義)
    spec:
      containers:
        - name: nginx
          image: nginx:1.25       # 使用するイメージ
          ports:
            - containerPort: 80   # コンテナ内のポート

6-2-2. マニフェストの構造解説

🍽️ このYAMLは「店長への指示書」です。
読み方を整理してみます。

YAMLの項目 比喩 意味
kind: Deployment 「これは店長への指示書です」 リソースの種類
replicas: 3 「常に3人体制にしてください」 維持するPod数
selector 「app: nginx のタグが付いたスタッフを管理して」 管理対象の特定
template 「こういうスタッフを雇ってください」 Pod のひな形
image: nginx:1.25 「スキル:nginx 1.25」 使用コンテナイメージ

6-2-3. Deploymentを適用

# WSL2 Ubuntu で実行
# ~/k8s-handson/pod-deployment/ で実行

# マニフェストを適用(店長に指示書を渡す)
kubectl apply -f nginx-deployment.yaml

# Podの状態を確認
kubectl get pods

期待される出力:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxxxxxxxx-xxxxx   1/1     Running   0          10s
nginx-deployment-xxxxxxxxx-yyyyy   1/1     Running   0          10s
nginx-deployment-xxxxxxxxx-zzzzz   1/1     Running   0          10s

💡 エラーが出た場合 → セクション7-1(YAMLのインデントずれ)を確認

3つのPodが起動しました。
では1つ壊してみましょう

# Podの名前を1つコピーして削除
# (出力に表示された名前を使ってください)
kubectl delete pod nginx-deployment-xxxxxxxxx-xxxxx

# すぐに確認(watchモードで監視)
kubectl get pods --watch

期待される出力:

NAME                                READY   STATUS              RESTARTS   AGE
nginx-deployment-xxxxxxxxx-yyyyy   1/1     Running             0          1m
nginx-deployment-xxxxxxxxx-zzzzz   1/1     Running             0          1m
nginx-deployment-xxxxxxxxx-aaaaa   0/1     ContainerCreating   0          2s
nginx-deployment-xxxxxxxxx-aaaaa   1/1     Running             0          5s

自動復旧(Self-healing)しました。
1つ削除しても、すぐに新しいPodが作られて3台体制に戻ります。
これは実際に見ると「おお」となります。

Ctrl + C でwatchモードを終了してください。

🍽️ スタッフが1人倒れても、シフト表(ReplicaSet)が「3人体制」を守るために自動で補充してくれた、ということです。


6-3. Step3:スケールアウト体験

「3人体制」を「5人体制」に変更してみます。

# WSL2 Ubuntu で実行

# レプリカ数を5に変更
kubectl scale deployment nginx-deployment --replicas=5

# 確認
kubectl get pods

期待される出力:

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxxxxxxxx-yyyyy   1/1     Running   0          3m
nginx-deployment-xxxxxxxxx-zzzzz   1/1     Running   0          3m
nginx-deployment-xxxxxxxxx-aaaaa   1/1     Running   0          2m
nginx-deployment-xxxxxxxxx-bbbbb   1/1     Running   0          5s
nginx-deployment-xxxxxxxxx-ccccc   1/1     Running   0          5s

5台に増えました。
逆に減らすこともできます。

# 2台に減らす
kubectl scale deployment nginx-deployment --replicas=2

# 確認
kubectl get pods

🍽️ 「今日は空いてるから2人体制で」と店長が判断。
余剰スタッフは帰宅(Pod削除)。


6-4. Step4:ローリングアップデート体験

nginx のバージョンを 1.251.26 に更新します。

# WSL2 Ubuntu で実行

# まず3台に戻す
kubectl scale deployment nginx-deployment --replicas=3

# 現在のイメージを確認
kubectl describe deployment nginx-deployment | grep Image

期待される出力:

    Image:        nginx:1.25
# イメージを更新(ローリングアップデート開始)
kubectl set image deployment/nginx-deployment nginx=nginx:1.26

# 更新の進行状況を監視
kubectl rollout status deployment/nginx-deployment

期待される出力:

Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out
# 更新後のイメージを確認
kubectl describe deployment nginx-deployment | grep Image

期待される出力:

    Image:        nginx:1.26

ゼロダウンタイムで更新完了。
古いPodを1つずつ新しいPodに入れ替えていく「ローリングアップデート」が行われました。
ダウンタイムなしで切り替わるのは、触ってみると想像以上にスムーズでした。

🍽️ 営業中のレストランで、スタッフを1人ずつ「旧メニュー担当 → 新メニュー担当」に切り替えていくイメージです。
お客さんには中断なし。

6-4-1. ローリングアップデートの流れ

6-4-2. おまけ:ロールバック

もし新バージョンに問題があったら、一瞬で元に戻せます。

# 直前のバージョンに戻す
kubectl rollout undo deployment/nginx-deployment

# 確認
kubectl describe deployment nginx-deployment | grep Image

期待される出力:

    Image:        nginx:1.25

🍽️ 「新メニュー不評だった!元に戻して!」→ 店長が即座にシフト表を元に戻す。


6-5. 後片付け

# Deployment を削除(Pod も一緒に消える)
kubectl delete deployment nginx-deployment

# 確認
kubectl get pods

期待される出力:

No resources found in default namespace.

7. つまずきポイント(体験談)

7-1. YAMLのインデントずれ

症状:

error: error validating "nginx-deployment.yaml": error validating data: ...

原因と対策: YAMLはインデント(スペース)が構文の一部です。
タブ文字は使えません。スペース2つで統一してください。

❌ NG ✅ OK
タブ文字でインデント スペース2つでインデント
インデントがバラバラ 階層ごとにスペース2つずつ増やす

7-2. 自動復旧が速すぎて見逃す

症状: kubectl delete podkubectl get pods したら、もう新しいPodが Running になっている。

対策: --watch フラグを先に付けてから別ターミナルで削除すると、復旧の過程が見えます。

# ターミナル1:監視
kubectl get pods --watch

# ターミナル2:削除
kubectl delete pod <Pod名>

7-3. Pod名の手打ちミス

症状:

Error from server (NotFound): pods "nginx-deployment-xxxxx" not found

対策: Pod名はランダム文字列を含むので、kubectl get pods で名前を確認してコピペするのが一番確実です。

# まず名前を確認 → 表示された名前をコピペして削除
kubectl get pods
kubectl delete pod <コピペしたPod名>

🔰 Memo: 慣れてきたらラベル指定で一括操作もできます:kubectl delete pod -l app=nginx


8. まとめ

8-1. この記事でやったこと

# 内容 状態
1 Pod単体の限界を体験した(壊れたら終わり)
2 Deploymentで自動復旧(Self-healing)を体験した
3 kubectl scale でスケーリングを体験した
4 ローリングアップデート&ロールバックを体験した

8-2. 3層構造の対比(まとめ表)

観点 Pod単体 Deployment
作成方法 kubectl run kubectl apply -f
障害時 消えたまま 自動復旧
スケール できない kubectl scale
バージョン更新 作り直し ローリングアップデート
ロールバック できない kubectl rollout undo
実務での使用 ほぼ使わない こちらが基本

8-3. Docker Compose → k8s 対応表

Docker Compose Kubernetes 備考
services.web Deployment 管理レベルが違う
docker-compose up kubectl apply -f 宣言的に適用
docker-compose up --scale web=3 kubectl scale --replicas=3 k8sは自動維持する
(該当なし) ローリングアップデート Docker Composeにはない
(該当なし) Self-healing Docker Composeにはない

9. 次回予告

第3回:Service / Ingress — ネットワーキングの設計思想

今回、Podは動くようになりました。
でも「外からアクセスする方法」がまだありません。

🍽️ レストランは開店したけど、看板も入口もない状態。
お客さんがたどり着けない!

次回は:

  • PodにはIPアドレスがあるのに、なぜ直接アクセスしないのか?
  • Service の4つの種類(ClusterIP / NodePort / LoadBalancer / ExternalName)
  • Ingressで「1つの入口から複数のサービスに振り分ける」方法

(つづく)

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?