Ritolabo
  1. Home
  2. Kubernetes
  3. Kubernetes の Deployment で Pod を管理する

Kubernetes の Deployment で Pod を管理する

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

Pod を単体で作ると、その Pod を消したときに代わりは作られない。Pod の数を見張って保つ担当がいないため。

Deployment は、Pod をいくつ、どんな中身で動かすかを定義するリソース。Deployment を作ると、Pod が消えても数が足りなくなった分が作り直される。

この記事では、Deployment をローカルのクラスタに作り、Pod を消す・数を変える・image を変える操作をして、そのときの動きを確認する。

この記事でやること:

  • Deployment の YAML の確認
  • Deployment・ReplicaSet・Pod の関係の確認
  • Pod を消したときの動き
  • replicas を書き換えたときの動き
  • image を書き換えたときの動き(ローリングアップデート)
  • Deployment の削除

contents

  1. 環境
  2. Deployment の YAML
  3. Deployment を作る
    1. Deployment・ReplicaSet・Pod の関係
  4. Pod を消すと作り直される
  5. replicas を変える
  6. image を変える:ローリングアップデート
    1. ReplicaSet が2つになる
    2. 単体の Pod との違い
  7. Deployment を消す
  8. 用語メモ
  9. 参考 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
templatePod のひな形。この下の 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 を作って管理する
ReplicaSetPod の数を 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新しいほうを増やす31
2古いほうを減らす21
3新しいほうを増やす22
4古いほうを減らす12
5新しいほうを増やす13
6古いほうを減らす03
  • 新しいほうを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


[Prev] kubectl で Kubernetes のクラスタを操作する

Author

rito

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級