ブログ一覧

図でわかるKubernetes入門:Pod・Deployment・Serviceの違いとつながり

· 約14分で読めます

Kubernetesの用語を、本の一覧APIを動かす一つの例でつなげます。8つの図と配置の見取り図で、クラスタとNode、Podの作成と復旧、Serviceへの通信、ヘルスチェック、設定・ストレージ、スケールと更新を順に解説します。

1. Kubernetesとは?「APIを3個動かしたい」を維持する仕組み

コンテナイメージは、アプリと実行に必要なファイルをまとめたものです。コンテナは、そのイメージから起動した実行環境。1台で起動するだけならコンテナランタイムを使えますが、複数のマシンで動かすと、配置・障害時の補充・接続先・更新も管理する必要が出てきます。Kubernetes(略称K8s)は、その管理を担います。

本の一覧を返す架空のAPIを考えます。宣言するのは「books-apiのv1を3 Pod動かす」という望ましい状態です。コントローラーは現在の状態を観察し、足りないPodを作るなどして差を埋めます。この繰り返しを調整ループ、reconciliationと呼びます。

図1:望ましい状態へ近づける調整ループの1周。観察と調整を繰り返す。

宣言:3 Pod必要 → 観察:現在は2 Pod → 調整:不足分を作成 → 再び観察:3 Podか確認

作成には時間がかかり、配置できる容量や権限がなければ望ましい状態に届きません。3個と書くだけで即座に3個が正常稼働するわけではなく、Kubernetesは目標へ近づける動作を続けます。以降は一般的なDeploymentと、セレクターを持つClusterIP Serviceを使う例です。

2. Cluster・Node・Pod・Container:どこで何が動くのか

クラスタ(Cluster)は、管理を行うコントロールプレーンと、アプリを動かすNodeから構成されます。Nodeは仮想マシンまたは物理マシンです。Podは1つのNode上に配置され、1個以上のコンテナが同じネットワーク環境を共有し、必要に応じてボリュームも共有します。API本体と補助プロキシのように密接に連携する構成もあります。

配置の見取り図:2 Nodeへの配置は説明用の例。自動的な均等配置を保証する図ではない
Cluster
├─ Control plane(クラスタを管理)
└─ Worker Nodes(アプリを実行)
   ├─ Node A
   │  ├─ Pod A [API container]
   │  └─ Pod B [API container]
   └─ Node B
      └─ Pod C [API container]

3個のAPIを動かすなら、通常は1つのPodにAPIコンテナを3個入れるのではなく、APIを入れたPodを3個に複製します。Podは配置と複製の単位だからです。同じPodのコンテナは別々のNodeに分散できません。Node障害へ備えて分散したい場合は、topology spread constraintsなどで配置条件も設計します。

コントロールプレーンの部品役割APIの例での仕事
API serverKubernetes APIの窓口kubectlなどから宣言を受け付ける
etcdAPIオブジェクトなどのクラスタ状態を保存Deploymentの設定などを保存する。アプリの本データ用DBとは別
scheduler未配置Podの配置先Nodeを選ぶ要求リソースや配置条件を満たすNodeを探す
controller manager調整ループを実行ReplicaSetなどのコントローラーが実際の状態を目標へ近づける

Node側ではkubeletがPodの実行状態を管理し、containerdなどのコンテナランタイムを通じてコンテナを起動します。宣言を受け付ける人、置き場所を決める人、実際に動かす人が分担していると考えると、構成を追いやすくなります。

3. Deployment・ReplicaSet・Pod:誰が数を保ち、誰が置き換えるのか

Podだけを作っても、削除後の補充を管理する仕組みは付きません。ステートレスなAPIならDeploymentを使い、Podのひな型、必要な個数、更新方法を宣言します。DeploymentはReplicaSetを管理し、ReplicaSetが対象Podの数を維持します。

図2:矢印は管理関係。DeploymentやReplicaSetは通信の中継点ではない。

Deployment:ひな型と更新 → ReplicaSet:このひな型の個数を維持 → Pod A・B・C:コンテナを実行

図3:Podを1個削除した後の補充例。配置可能なNodeと取得可能なイメージがある前提。
  1. APIのPod: Pod Bが削除され、必要な3個に足りなくなる
  2. コントロールプレーン: ReplicaSetのコントローラーが代わりのPod Dを作る
  3. コントロールプレーン: schedulerがPod Dの配置先Nodeを選ぶ
  4. Node上のkubelet: ランタイムを通じてイメージを取得し、コンテナを起動する
  5. APIのPod: Pod Dのアプリが初期化を終え、Readyになる

代わりのPod Dは、削除されたPod Bとは別のオブジェクトで、IPも同じとは限りません。対して、Pod内のコンテナが異常終了した場合は、kubeletがrestartPolicyに従って同じPod内で再起動することがあります。コンテナの再起動とPodの置き換えを区別しましょう。障害検知から補充までは時間がかかるため、処理中の要求やメモリ内のデータまで自動復元されるわけではありません。

4. Service・Label・Ingress:利用者の通信はどこへ届くのか

PodのIPを呼び出し側に直接設定すると、置き換わるたびに接続先が変わります。Serviceは、入れ替わるPod群に対して安定した接続先を提供します。この例のClusterIP Serviceにはクラスタ内の仮想IPが割り当てられ、クラスタDNSがあれば同じNamespaceのアプリはbooks-apiという名前で接続できます。

LabelはPodなどに付ける名札です。Podにapp=books-apiを付け、Serviceのselectorにもapp=books-apiを指定します。通常のセレクター付きServiceでは、対象Podのアドレスと準備状態がEndpointSliceへ反映され、通信経路の実装が転送先を更新します。ServiceがDeployment名を見て対象を選ぶわけではありません。

図4:外部HTTP通信の論理的な経路例。Serviceは接続先の抽象化で、独立したプロキシPodとは限らない。

利用者のHTTP要求 → Ingress対応のLB/プロキシ → Service books-apiを宛先に選ぶ → 対象のReadyなPod A/C/Dのいずれか → Pod内のAPIコンテナ

Ingressは、ホスト名やパスからServiceへ振り分けるHTTP(S)のルールです。ルールを反映するIngress controllerとロードバランサー等の実体が必要です。図は論理的な対応であり、実装によってはServiceの仮想IPを経由せず、プロキシがPodへ直接転送します。実際の経路は採用した実装で確認します。Gateway APIも入口を構成する選択肢です。

接続の仕組み主な用途必要なもの
ClusterIP Serviceクラスタ内部の安定した接続先クラスタ内のネットワークとService転送の実装
LoadBalancer Service外部ロードバランサー経由で公開クラウドなどの対応するロードバランサー実装
IngressHTTP(S)のホスト・パスでServiceを選ぶルールを実現するcontrollerと通信を処理する実体

5. RunningとReady:起動したPodへすぐ通信してよいか

Runningはアプリが要求を処理できる保証ではありません。設定やキャッシュを読み込む途中でもコンテナは動いています。そこでprobe(ヘルスチェック)を使い、起動できたか、要求を受けてよいか、再起動が必要かを分けて判断します。

probe確かめること失敗時の主な動作
startupProbe起動処理が完了したか設定した失敗条件に達すると対象コンテナを再起動。成功までは他の2種を実行しない
readinessProbeこのコンテナが要求を受けてよいかPodをNotReadyにする。通常のService転送対象から外れるが、この失敗だけでは再起動しない
livenessProbe再起動が必要な状態か設定した失敗条件に達すると対象コンテナを再起動する
図5:起動から通信参加までの例。全コンテナの準備と必要な条件を満たし、経路へ反映されてから通信が届く。
  1. APIコンテナ: プロセスは起動したが、初期化はまだ途中
  2. kubeletの検査: startupProbeが成功し、readiness等の検査を開始
  3. kubeletの検査: readinessProbeが成功し、Podの準備条件を満たす
  4. Serviceの転送先: ReadyなPodとして通信経路に反映される
  5. kubeletの検査: 後でreadinessが失敗したら対象から外す。失敗だけで再起動しない

livenessに共有DBへの問い合わせを入れると、DBの一時的な遅延で全コンテナが再起動し、起動時の接続集中で悪化することがあります。再起動で直るプロセス自身の異常と、依存先の障害を分けます。readinessにも共有依存先を入れるなら、全Podを同時に外す影響を評価します。検査と転送先の更新には遅れがあり、切り替えは瞬時ではありません。

6. YAMLを読む:Deploymentのひな型とServiceの名札を結ぶ

ここまでの関係をYAMLで表すと次のようになります。既存のbooks Namespaceを想定した概念説明用の例です。イメージURLはダミーで、実行確認した構成ではありません。実際に試すには取得可能なイメージと、8080番で本の一覧および/readyzを返すアプリが必要です。リソース値は仮定で、推奨値ではありません。

apps/v1 Deploymentとv1 Serviceの例:startup・livenessや本番運用に必要な周辺設定は省略
apiVersion: apps/v1
kind: Deployment
metadata:
  name: books-api
  namespace: books
spec:
  replicas: 3
  selector:
    matchLabels:
      app: books-api
  template:
    metadata:
      labels:
        app: books-api
    spec:
      containers:
        - name: api
          image: registry.example.invalid/books-api:v1
          ports:
            - name: http
              containerPort: 8080
          readinessProbe:
            httpGet:
              path: /readyz
              port: http
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "256Mi"
---
apiVersion: v1
kind: Service
metadata:
  name: books-api
  namespace: books
spec:
  type: ClusterIP
  selector:
    app: books-api
  ports:
    - port: 80
      targetPort: http

7. Namespace・ConfigMap・Secret:所属と設定を分ける

Namespaceは、クラスタ内で名前やリソースを区切る単位です。booksのServiceと、別Namespaceにある同名Serviceは別物です。ただしNodeやPersistentVolumeのようにNamespaceへ属さないリソースもあります。Namespaceを分けただけで通信や権限がすべて分離されるわけではなく、RBACや実装に対応したNetworkPolicy等も必要です。

概念本の一覧APIでの例読むときの注意
NamespacebooksにAPIとServiceを所属させる配置先Nodeやネットワーク隔離を単独では決めない
ConfigMapログのレベルや公開用の設定値機密情報を入れない。環境別設定をイメージから分離する
SecretDBパスワードやAPIキーBase64は暗号化ではない。保存時暗号化と最小権限を別途設定する

ConfigMapやSecretを環境変数で渡した場合、オブジェクトを更新しても実行中コンテナの環境変数は変わりません。新しい値を取り込むためにコンテナを再起動する必要があります。通常のボリュームマウントでは更新が後から反映されますが、subPathには自動反映されず、アプリ側にもファイルを読み直す仕組みが必要です。SecretをPodへマウントできる権限も、機密値を読む権限として扱います。

8. Volume・PVC・PV:Podが消えても残したいデータ

コンテナの書き込み領域やPodの一時ボリュームを、永続データの保存先と考えてはいけません。例えばemptyDirは同じPod内のコンテナ再起動では残りますが、Podが削除されると失われます。Podの寿命と分けて保存したいときに、PersistentVolumeClaim(PVC)とPersistentVolume(PV)を使います。

図6:永続ストレージの参照・対応関係。通信の順序ではなく、Podが保存先を使うためのつながり。

Pod:保存先をマウント → PVC:容量・アクセス方式を要求 → PV:要求に対応付いたストレージ資源 → 実体:ディスクや共有ファイルストレージ

StorageClassは、動的にストレージを作るときの種類や作成方法を表します。PVCがあっても、アクセス方式・ゾーン・実装によっては複数Nodeから同時利用できません。PVC削除後に実体が残るかはreclaimPolicy等に依存します。永続化はバックアップとは別で、削除や破損に備える復元の設計も必要です。今回のAPIは本のデータを外部DBに保存する前提なら、各API PodにPVCを付ける必要はありません。

9. requests・limits・HPA:Podを増やすこととNodeを増やすこと

requestsは配置判断に使う要求量、limitsは実行時の制約です。LinuxコンテナではCPUのlimitがスロットリング、メモリ不足がOOM終了につながることがあります。同じ「上限」でも挙動は違います。例の100mはCPU 1コアの10分の1、128Miは128メビバイトです。指定量がすべてアプリ専用に物理確保される、という意味ではありません。

図7:HPAが3 Podから5 Podへ増やす仮定の例。Nodeの余力が足りる場合は増設段階を飛ばせる。

メトリクスに基づきHPAが判断 → Deploymentの希望数を3→5へ変更 → ReplicaSetが追加Podを作成 → 配置余力がなければPending/別途Node増設 → 起動・Ready・経路反映後に処理へ参加

Horizontal Pod Autoscaler(HPA)は、CPUなどのメトリクスを基に対象の希望Pod数を調整します。CPU使用率を使う設定では、分母はCPU requestsです。必要なメトリクス供給も別途必要です。HPAで管理する場合は、先ほどのYAMLのような固定のreplicasを継続して適用しないよう、管理をHPAへ移します。replicas: 3を再適用すると、HPAが増やした希望数を3へ戻してしまいます。一方、Nodeの増設は別の仕組みで、HPAだけではマシンは増えません。台数の判断から処理参加までに、収集・配置・イメージ取得・初期化の待ちがあります。予測できる集中には事前増設や通常時の余力も検討します。

Podを増やすと、DB接続や外部APIへの呼び出しも増え得ます。例えば仮定として1 Podの接続プール上限が10なら、3 Podで最大30、5 Podで最大50接続です。Kubernetesが外部DBの上限まで自動調整してくれるとは限りません。アプリ全体の予算からPod数と並列数を決めます。

10. ローリング更新:新しいPodを用意してから古いPodを終了する

DeploymentのPodひな型をv1からv2へ変更すると、ローリング更新では新しいReplicaSetを使い、旧Podと新Podの個数を段階的に調整します。次の図は、desired replicasが3、maxSurgeが1、maxUnavailableが0の例です。新Podが利用可能になるまで旧Podを減らさないため、一時的に追加の容量が必要です。

図8:3個を維持する更新の1段階。終了待ちPodを含めると、同時に存在するPodが4個を超えることもある。
  1. Deployment: 新しいひな型のReplicaSetを用意する
  2. 新Pod v2: 追加のv2を1個起動し、利用可能になるのを待つ
  3. Deployment: 利用可能な個数を見ながら旧ReplicaSetを1個減らす
  4. 旧Pod v1: 転送先からの除外を進めつつ、猶予内で処理中の要求を終える
  5. Deployment: 同じ調整を繰り返し、目標の3個をv2へ置き換える

ローリング更新だけで無停止になるわけではありません。正しいreadiness、残るPodの処理能力、終了時のgraceful shutdownが必要です。経路から外れるまでの遅れと処理中の要求を考慮し、アプリが終了シグナルを受け、猶予内で後片付けできるようにします。固定秒数待つだけで安全とせず、実際の転送停止と終了時間を測ります。DBスキーマも旧版・新版の両方が動く形で移行します。

用語をつなげて読む:つまずいたらどの段階を見るか

見えている状態まず見るものこの段階で分かること
PodがPendingPodのイベント、requests、配置条件、Nodeの余力Pod作成後、まだ配置・起動へ進めていない可能性
RunningだがReadyではないprobeの結果、初期化ログ、コンテナの状態プロセス起動と通信受付の準備を分けて調べる
ReadyなのにServiceから届かないselectorとlabels、EndpointSlice、portとtargetPort、通信制御対象の選択、ポート、通信経路のどこで切れているか
コンテナの再起動が続く終了理由、前回ログ、OOM、probeの失敗アプリ異常と実行制約、再起動判断を切り分ける
デプロイ中だけエラー旧Podへの転送、終了ログ、残存容量、DB接続通信の切り替え・終了処理・容量を同じ時刻で比較する

確認問題です。Podを3個にしたいのはDeployment、入れ替わっても同じ名前で接続したいのはService、初期化中のPodへ要求を送らないための検査はreadinessProbeです。この3つの役割を図2・4・5で言い直せれば、基本のつながりをつかめています。次は下のTipで、ヘルスチェック、リソース、スケールの遅れ、機密設定、終了処理の設計を掘り下げられます。

参考資料:Kubernetes公式ドキュメント

2026年10月26日に確認した公式の概念ドキュメントです。図は本の一覧APIを使った独自の説明用モデルで、実環境の観測結果ではありません。機能の利用可否や実際の通信・ストレージの挙動は、利用するKubernetesのバージョンと実装で確認してください。

この記事で深掘りしたTips