Kubernetesを触りはじめると、DeploymentとPodは早い段階で出てきますが、その間にいるReplicaSetの役割が抜けて、「DeploymentがPodを動かしている」と大まかに捉えてしまいがちです。この理解だと、Podが勝手に復活する仕組みや、無停止でバージョンを入れ替える挙動を説明できません。
この記事は、『Kubernetesの概要・全体像まとめ』で押さえた全体像のうち、「あるべき状態を宣言する」部分を具体的なリソースで見ていきます。誰が誰を管理しているかという三層関係を確定させ、その上で自己修復・ローリングアップデート・ロールバックの挙動を整理します。
- Deployment・ReplicaSet・Podの管理関係
- Podが落ちたときに復活する自己修復の仕組み
- replicas・ローリングアップデート・ロールバックの挙動
Kubernetesのデプロイを支える3つのリソース
Kubernetesでアプリケーションをデプロイするときは、Deployment・ReplicaSet・Podという3つのリソースの役割を押さえると全体像がつかみやすくなります。これらは上から順に相手を管理する三層の関係になっています。
flowchart TB D["Deployment(あるべき状態を宣言)"] RS["ReplicaSet(Pod数を維持)"] P1["Pod"] P2["Pod"] P3["Pod"] D -->|"管理"| RS RS -->|"維持"| P1 RS -->|"維持"| P2 RS -->|"維持"| P3
- Deployment
- 「どのコンテナを何個、どのバージョンで動かすか」というあるべき状態を宣言する
- ReplicaSet
- Deploymentの指定にもとづき、指定された数のPodが常に動いている状態を維持する
- Pod
- 実際にコンテナが動く最小単位
利用者が直接書くのは基本的にDeploymentだけで、ReplicaSetはDeploymentが裏で自動的に作ります。ReplicaSetを手で作ることは通常ありません。
DeploymentがReplicaSetを管理する
Deploymentは、アプリケーションのあるべき状態を宣言するリソースです。コンテナイメージ・バージョン・Pod数などを指定します。
Deploymentの重要な役割は、バージョンの世代管理です。後述するローリングアップデートやロールバックは、Deploymentが新旧のReplicaSetを切り替えることで実現されます。「Podをどう入れ替えるか」を受け持つのがDeploymentだと捉えるとよいです。
ReplicaSetがPod数を維持する
ReplicaSetは、指定された数のPodが常に動いている状態を維持するリソースです。「Podを3個」と指定されていれば、現在3個動いているかを監視し続け、足りなければ作り、多ければ減らします。
Podを実際に数え、増減させて数を合わせているのはReplicaSetです。Deploymentはあるべき状態を宣言し、ReplicaSetがその数を維持する、という分担になっています。
Podが落ちたときの自己修復
Podが何らかの理由で落ちると、ReplicaSetが「指定は3個なのに今は2個」という差を検知し、新しいPodを1個作って3個に戻します。これが自己修復の実体です。
ここで大事なのは、復活するのは同じPodではなく新しいPodだという点です。落ちたPodがそのまま生き返るのではなく、あるべき数を満たすために別のPodが作られます。新しいPodはIPアドレスも変わります。
そのため、Podを直接指定して通信する設計は成り立ちません。安定した宛先をどう用意するかは『KubernetesのService・Ingressの関係とPodへの通信経路』で扱います。
replicasで台数を宣言する
replicasは、Podを何個動かすかを指定する値です。Deploymentにreplicas: 3と書けば、ReplicaSetがPodを3個に保ちます。
この値を増やせば、ReplicaSetが新しいPodを追加してスケールアウトします。減らせば余分なPodを止めます。負荷に応じてこの値を自動で増減させる仕組み(オートスケール)もありますが、それはGKEなどのマネージド環境の話として『GKE概要まとめ』で扱います。
replicasを2以上にする狙いは、負荷分散だけではありません。1個のPodやNodeが落ちても他のPodが処理を続けられるようにする、可用性の確保でもあります。1個だけだと、それが落ちた瞬間にサービスが止まります。
ローリングアップデートの挙動
新しいバージョンをデプロイするとき、Kubernetesは全Podを一度に入れ替えるのではなく、少しずつ入れ替えます。これがローリングアップデートです。
Deploymentのコンテナイメージを新しいバージョンに変えると、次のように進みます。
sequenceDiagram participant D as Deployment participant Old as 旧ReplicaSet participant New as 新ReplicaSet D->>New: 新バージョンのPodを1個作る New-->>D: 新Podが起動して準備完了 D->>Old: 旧Podを1個止める Note over D,Old: 上記を繰り返し、少しずつ入れ替える D->>Old: 旧Podがすべて止まる
Deploymentは新しいReplicaSetを作り、新Podを増やしながら旧Podを減らしていきます。この間、新旧のPodが一時的に混在します。常に一定数のPodが動き続けるため、サービスを止めずに更新できます。
裏を返すと、更新中は新旧のバージョンが同時に動く前提になります。データベースのスキーマ変更のように、新旧が同居すると壊れる変更は、この前提を踏まえて段階的に進める必要があります。
ロールバックで前のバージョンに戻す
新しいバージョンに問題があったとき、Deploymentは前のバージョンに戻すロールバックができます。
これが可能なのは、Deploymentが世代ごとにReplicaSetを保持しているためです。新バージョンで作られた新ReplicaSetを縮小し、旧バージョンの旧ReplicaSetを再び拡大することで、前の状態に戻します。手作業で旧バージョンを再デプロイし直すのではなく、宣言した世代を切り替えるだけで戻せる、という点が利点です。
まとめ
Kubernetesのデプロイでは、Deployment・ReplicaSet・Podが役割を分担し、宣言した状態を維持しながらアプリケーションを動かします。要点は以下です。
- DeploymentがReplicaSetを管理し、ReplicaSetがPodの数を維持する。利用者が直接書くのはDeployment
- Podが落ちると、ReplicaSetがあるべき数との差を埋め、新しいPodを作り直す。これが自己修復
- 復活するのは同じPodではなく新しいPodで、IPも変わる。だからPodを直接名指しにしない
- replicasはPod数の宣言で、負荷分散と可用性の両方を担う
- ローリングアップデートは新旧Podを少しずつ入れ替えて無停止更新する。更新中は新旧が同居する
- ロールバックは、Deploymentが保持する旧ReplicaSetに切り替えて前の状態に戻す