Kubernetes の Deployment で Pod を管理する
- 公開日
- カテゴリ:Kubernetes
- タグ:Kubernetes,学習メモ

Pod を単体で作ると、その Pod を消したときに代わりは作られない。Pod の数を見張って保つ担当がいないため。
Deployment は、Pod をいくつ、どんな中身で動かすかを定義するリソース。Deployment を作ると、Pod が消えても数が足りなくなった分が作り直される。
この記事では、Deployment をローカルのクラスタに作り、Pod を消す・数を変える・image を変える操作をして、そのときの動きを確認する。
この記事でやること:
- Deployment の YAML の確認
- Deployment・ReplicaSet・Pod の関係の確認
- Pod を消したときの動き
replicasを書き換えたときの動きimageを書き換えたときの動き(ローリングアップデート)- Deployment の削除
contents
- 環境
- Deployment の YAML
- Deployment を作る
- Pod を消すと作り直される
- replicas を変える
- image を変える:ローリングアップデート
- Deployment を消す
- 用語メモ
- 参考 URL
環境
kind で作ったクラスタ(Control Plane 1台 + Worker 2台)を使う。(作り方は「Kubernetes の Pod とは?コンテナを動かす最小単位を整理する」を参照)
- 環境: macOS(Apple Silicon)、Docker Desktop 29.8.0、kind v0.33.0、Kubernetes v1.37.0、kubectl v1.36.1
Deployment の YAML
nginx の Pod を3つ動かす Deployment を用意する。
# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
| 場所 | 意味 |
|---|---|
replicas | 動かしておきたい Pod の数。省略すると 1 |
template | Pod のひな形。この下の spec は、Pod の YAML に書く spec と同じ形 |
template.metadata.labels | 作る Pod に付ける label(キー: 値 の形の札) |
selector | どの label が付いた Pod を管理の対象にするかの指定 |
selectorはtemplate.metadata.labelsと一致している必要がある。一致していないと API に拒否されるtemplateの中に Pod の名前は書かない。名前は Pod が作られるときに自動で付く
Pod の YAML と並べると、Pod の定義が template の中に入り、その外側に数(replicas)と対象(selector)が付いた形になっている。
Pod の YAML Deployment の YAML
───────────── ─────────────────────
kind: Pod kind: Deployment
metadata: metadata:
name: nginx name: nginx-deployment
spec: spec:
containers: ... replicas: 3
selector: ...
template:
metadata:
labels: ...
spec:
containers: ...
Deployment を作る
$ kubectl apply -f nginx-deployment.yaml
# => deployment.apps/nginx-deployment created
作ったのは Deployment 1つだが、クラスタには3種類のリソースができる。
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 6s
$ kubectl get replicasets
NAME DESIRED CURRENT READY AGE
nginx-deployment-54fd4d6d4c 3 3 3 11s
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-54fd4d6d4c-5kdcd 1/1 Running 0 103s 10.244.2.2 k8s-study-worker2 <none> <none>
nginx-deployment-54fd4d6d4c-8ldzg 1/1 Running 0 103s 10.244.1.2 k8s-study-worker <none> <none>
nginx-deployment-54fd4d6d4c-zgdhg 1/1 Running 0 103s 10.244.1.3 k8s-study-worker <none> <none>
kubectl get deploymentsのREADYは「利用可能な数 / 欲しい数」- ReplicaSet の名前は
Deployment の名前-ハッシュ、Pod の名前はReplicaSet の名前-ランダムな文字列 - Pod は3つ、Worker は2台なので、
k8s-study-workerには Pod が2つ置かれている。1つの Node には複数の Pod を置ける - 同じ Node にある2つの Pod も、IP は別々(
10.244.1.2と10.244.1.3)。どちらの nginx もポート 80 で待ち受けているが、IP が違うので衝突しない
Deployment・ReplicaSet・Pod の関係
| リソース | 担当 |
|---|---|
| Deployment | 自分で定義するもの。ReplicaSet を作って管理する |
| ReplicaSet | Pod の数を replicas の数に保つ。足りなければ template から作り、多ければ消す |
| Pod | コンテナを動かす |
- Pod の数を保っているのは ReplicaSet で、Deployment はその ReplicaSet を管理する
- 公式ドキュメントでは、Deployment が所有する ReplicaSet を直接管理しないこと、ReplicaSet を直接使う代わりに Deployment を使うことが勧められている
- どの Node に Pod を置くかは Deployment の YAML には書かない。クラスタにある Node の中から kube-scheduler が選ぶ
(クラスタのコンポーネントを含めた全体の流れは「Kubernetes のアーキテクチャを整理する:Control Plane と Node の構成要素」を参照)
Pod を消すと作り直される
Pod を1つ、名前を指定して消す。
$ kubectl delete pod nginx-deployment-54fd4d6d4c-zgdhg
# => pod "nginx-deployment-54fd4d6d4c-zgdhg" deleted from default namespace
このときの Pod の変化は、kubectl get pods -w で追える。-w(watch)を付けると、変化があるたびに行が追加される。次の出力は、別のターミナルで Pod(...-xfkgk)を1つ消したときのもの。
$ kubectl get pods -w
NAME READY STATUS RESTARTS AGE
nginx-deployment-76df5b8bb8-5ts2q 1/1 Running 0 5s
nginx-deployment-76df5b8bb8-8qqjs 1/1 Running 0 5s
nginx-deployment-76df5b8bb8-xfkgk 1/1 Running 0 5s
nginx-deployment-76df5b8bb8-xfkgk 1/1 Terminating 0 20s
nginx-deployment-76df5b8bb8-6n2ch 0/1 Pending 0 0s
nginx-deployment-76df5b8bb8-xfkgk 1/1 Terminating 0 20s
nginx-deployment-76df5b8bb8-6n2ch 0/1 Pending 0 0s
nginx-deployment-76df5b8bb8-6n2ch 0/1 ContainerCreating 0 0s
nginx-deployment-76df5b8bb8-xfkgk 0/1 Completed 0 20s
nginx-deployment-76df5b8bb8-xfkgk 0/1 Completed 0 20s
nginx-deployment-76df5b8bb8-xfkgk 0/1 Completed 0 20s
nginx-deployment-76df5b8bb8-6n2ch 0/1 ContainerCreating 0 0s
nginx-deployment-76df5b8bb8-6n2ch 1/1 Running 0 0s
(この出力は Deployment を作り直したあとに取ったもので、ReplicaSet の名前が前の節と異なる)
- 消した Pod(
...-xfkgk)がTerminatingになった直後に、名前の違う新しい Pod(...-6n2ch)がPendingで現れている - 新しい Pod は
Pending→ContainerCreating→Runningと進む - 残りの2つの Pod(
...-5ts2q、...-8qqjs)には変化がない
消した Pod が復活するのではなく、別の Pod が新しく作られる。ReplicaSet が「欲しい数は 3、今は 2」という差を検知し、足りない1つを template から作っている。
replicas を変える
nginx-deployment.yaml の replicas を書き換えて、apply し直す。
replicas: 5 # 3 から変更
$ kubectl apply -f nginx-deployment.yaml
# => deployment.apps/nginx-deployment configured
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-54fd4d6d4c-2hrls 1/1 Running 0 4s
nginx-deployment-54fd4d6d4c-h5jbf 1/1 Running 0 4s
nginx-deployment-54fd4d6d4c-r99zl 1/1 Running 0 4s
nginx-deployment-54fd4d6d4c-rxp8m 1/1 Running 0 4s
nginx-deployment-54fd4d6d4c-wqmgh 1/1 Running 0 4s
replicas を 3 に戻して apply すると、Pod は3つに減る。
replicas: 3 # 5 から変更
$ kubectl apply -f nginx-deployment.yaml
# => deployment.apps/nginx-deployment configured
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-54fd4d6d4c-2hrls 1/1 Running 0 51s
nginx-deployment-54fd4d6d4c-r99zl 1/1 Running 0 51s
nginx-deployment-54fd4d6d4c-rxp8m 1/1 Running 0 51s
- 5つのうち2つ(
...-h5jbf、...-wqmgh)が消され、残りの3つはそのまま動いている(AGEが続いている) - ReplicaSet は同じもの(Pod の名前に含まれるハッシュ
54fd4d6d4cが変わっていない)
Pod を消したときも、replicas を変えたときも、「欲しい数」と「今の数」の差を埋めるという動きは同じ。前者は今の数が変わり、後者は欲しい数が変わっている。
image を変える:ローリングアップデート
nginx-deployment.yaml の image を書き換えて、apply し直す。
image: nginx:1.16.1 # 1.14.2 から変更
$ kubectl apply -f nginx-deployment.yaml
# => deployment.apps/nginx-deployment configured
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-54fd4d6d4c-2hrls 1/1 Running 0 104s
nginx-deployment-54fd4d6d4c-r99zl 0/1 Completed 0 104s
nginx-deployment-54fd4d6d4c-rxp8m 1/1 Running 0 104s
nginx-deployment-76df5b8bb8-mkgdr 1/1 Running 0 1s
nginx-deployment-76df5b8bb8-smwm4 0/1 ContainerCreating 0 0s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-76df5b8bb8-mkgdr 1/1 Running 0 2s
nginx-deployment-76df5b8bb8-smwm4 1/1 Running 0 1s
nginx-deployment-76df5b8bb8-w8znq 1/1 Running 0 1s
1回目の kubectl get pods は、入れ替えの途中の状態。
| Pod | 状態 |
|---|---|
古い Pod(54fd4d6d4c) | 2つが Running、1つは終了したところ(Completed) |
新しい Pod(76df5b8bb8) | 1つが Running、1つはコンテナの作成中(ContainerCreating) |
2回目では、3つとも新しい Pod に入れ替わっている。
- Pod の名前がすべて変わり、
AGEは入れ替わった時点からの時間、RESTARTSは0 - Pod の名前に含まれるハッシュ(ReplicaSet の部分)も
54fd4d6d4cから76df5b8bb8に変わった
ReplicaSet が2つになる
$ kubectl get replicasets
NAME DESIRED CURRENT READY AGE
nginx-deployment-54fd4d6d4c 0 0 0 46s
nginx-deployment-76df5b8bb8 3 3 3 3s
templateが変わると、Deployment は新しい ReplicaSet を作る- 新しい ReplicaSet の数を増やしながら、古い ReplicaSet の数を減らしていく
- 入れ替えが終わると、新しいほうが 3、古いほうが 0 になる
一度にすべての Pod を止めず、少しずつ入れ替えるこの更新の方法をローリングアップデートと呼ぶ。
- 既定では、入れ替えの間も「欲しい数」の 75% 以上の Pod が利用可能な状態に保たれ、Pod の総数は「欲しい数」の 125% までに抑えられる
replicas: 3の場合は、利用可能な Pod が 3 以上、Pod の総数が 4 以下- 終了処理中の Pod はこの数に含まれない。そのため、入れ替えの途中では想定より多くの Pod が見えることがある(上の1回目の出力でも5行並んでいる)
- 入れ替えが起きるのは
templateを変えたときだけ。replicasの変更では起きない
入れ替えの経過は、Deployment の Events: に残る。
$ kubectl describe deployment nginx-deployment
(Events: より上は省略)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 65s deployment-controller Scaled up replica set nginx-deployment-54fd4d6d4c from 0 to 3
Normal ScalingReplicaSet 22s deployment-controller Scaled up replica set nginx-deployment-76df5b8bb8 from 0 to 1
Normal ScalingReplicaSet 21s deployment-controller Scaled down replica set nginx-deployment-54fd4d6d4c from 3 to 2
Normal ScalingReplicaSet 21s deployment-controller Scaled up replica set nginx-deployment-76df5b8bb8 from 1 to 2
Normal ScalingReplicaSet 21s deployment-controller Scaled down replica set nginx-deployment-54fd4d6d4c from 2 to 1
Normal ScalingReplicaSet 21s deployment-controller Scaled up replica set nginx-deployment-76df5b8bb8 from 2 to 3
Normal ScalingReplicaSet 20s deployment-controller Scaled down replica set nginx-deployment-54fd4d6d4c from 1 to 0
1行目は Deployment を作ったときの記録で、2行目からが入れ替え。ReplicaSet の数は次のように変わっている。
| 順 | 操作 | 古い ReplicaSet(1.14.2) | 新しい ReplicaSet(1.16.1) |
|---|---|---|---|
| 1 | 新しいほうを増やす | 3 | 1 |
| 2 | 古いほうを減らす | 2 | 1 |
| 3 | 新しいほうを増やす | 2 | 2 |
| 4 | 古いほうを減らす | 1 | 2 |
| 5 | 新しいほうを増やす | 1 | 3 |
| 6 | 古いほうを減らす | 0 | 3 |
- 新しいほうを1つ増やしてから、古いほうを1つ減らす、という操作が交互に繰り返されている
- 2つの ReplicaSet の数の合計は、3 と 4 の間を行き来している
数が 0 になった古い ReplicaSet は、消されずに残る。Deployment の各リビジョン(template の版)の設定は ReplicaSet に保存されていて、前のリビジョンに戻すときに使われる。既定では古い ReplicaSet が 10 個まで保持される。
単体の Pod との違い
単体の Pod の image を書き換えて apply した場合は、Pod はそのままで、中のコンテナだけが起動し直される(「kubectl で Kubernetes のクラスタを操作する」で確認した動き)。Deployment の場合は、Pod ごと新しいものに入れ替わる。
| 単体の Pod の image を変更 | Deployment の image を変更 | |
|---|---|---|
| 起きること | Pod はそのまま。中のコンテナだけ起動し直す | Pod ごと新しいものに入れ替わる |
| Pod の名前 | 変わらない | 変わる |
AGE | 作ったときから続く | 入れ替わった時点から |
RESTARTS | 増える | 0 |
Deployment を消す
Pod を消しても作り直されるので、片付けるときは Deployment を消す。
$ kubectl delete -f nginx-deployment.yaml
# => deployment.apps "nginx-deployment" deleted from default namespace
$ kubectl get deployments
# => No resources found in default namespace.
$ kubectl get replicasets
# => No resources found in default namespace.
$ kubectl get pods
# => No resources found in default namespace.
Deployment を消すと、その下の ReplicaSet と Pod もまとめて消える。Kubernetes は既定で、消したオブジェクトに従属するオブジェクトも削除する。
用語メモ
| 用語 | 読み方 | 意味 |
|---|---|---|
| Deployment | デプロイメント | Pod をいくつ、どんな中身で動かすかを定義するリソース。ReplicaSet を作って管理する |
| ReplicaSet | レプリカセット | Pod の数を、指定された数に保つリソース |
| replicas | レプリカズ | 動かしておきたい Pod の数 |
| label | ラベル | リソースに付ける キー: 値 の形の札 |
| selector | セレクター | どの label が付いたリソースを対象にするかの指定 |
| rolling update | ローリングアップデート | Pod を少しずつ新しいものに入れ替える更新の方法 |
まとめ
- Deployment は、Pod の数(
replicas)と Pod のひな形(template)を定義するリソース - Deployment を作ると ReplicaSet と Pod ができる。Pod の数を保つのは ReplicaSet で、Deployment はその ReplicaSet を管理する
- Pod を消すと、名前の違う新しい Pod が作られ、数が
replicasに戻る replicasを書き換えて apply すると、同じ ReplicaSet のまま Pod が増減するtemplate(imageなど)を書き換えて apply すると、新しい ReplicaSet が作られ、Pod が少しずつ新しいものに入れ替わる- 片付けるときは Deployment を消す。ReplicaSet と Pod もまとめて消える
参考 URL
- [official] Deployment | Kubernetes
- [official] ReplicaSet | Kubernetes
- [official] ラベル(Labels)とセレクター(Selectors) | Kubernetes
- [official] ガベージコレクション | Kubernetes

