一覧CL-11-1 · Kubernetesの状態管理

DeploymentによるPodの管理

APIに保存された宣言、Podの所有関係、実際の個数を対応させ、手動削除が台数変更にならない理由を説明します。

説明

Kubernetesでは、アプリを動かす最小の配置単位をPodと呼びます。Deploymentに必要なPod数を宣言すると、ReplicaSetが実際のPod数との差を埋めます。宣言の受付と、Podが利用可能になる時点は別です。

独立したlesson名前空間に、Alpineで待機するPodを2個作ります。所有関係を確認してからPodを1個削除し、別のPodが補充される様子を調べます。最後に宣言を3個へ変え、同じ定義を再適用します。

APIに保存された宣言、Podの所有関係、実際の個数を対応させ、手動削除が台数変更にならない理由を説明します。

1Podを2個保つ定義

replicasは必要なPod数です。selectorは管理対象のラベル、templateは新しく作るPodの定義です。

python3 -c定義ファイルの台数・ラベル・イメージを表示する 'import json; d=json.load(open("deployment.json")); print("replicas=",d["spec"]["replicas"]); print("selector=",d["spec"]["selector"]); print("image=",d["spec"]["template"]["spec"]["containers"][0]["image"])'

replicas=2とapp=webのラベルが対応しています。イメージから起動するプロセスはsleepで、終了せず待機します。

2定義をAPIへ登録する

applyでDeploymentを保存します。createdは受付の結果であり、Podの準備完了を意味しません。

kubectl apply -f deployment.jsonファイルの宣言をAPIへ反映する

Deployment/webが作成されました。controllerがこの宣言を読み、ReplicaSetとPodを作ります。

3準備完了した個数を確認する

observe.pyはPodのReady条件と再起動回数をAPIから取得します。2個ともReadyになるまで待ちます。

python3 observe.py wait 2 2 0Pod数2・Ready数2になるまで確認する

Podは2個、Readyも2個、再起動は0回です。要求した個数と利用可能な個数が一致しました。

4所有関係をたどる

各PodのownerReferencesと、そのReplicaSetのownerReferencesを照合します。名前だけで同じアプリだと推測せず、所有者のUIDを使います。

python3 observe.py ownersUIDでPodからReplicaSetとDeploymentをたどる

各PodはReplicaSet、そのReplicaSetはDeployment/webに所有されています。Deploymentが直接Podを数えるだけの構造ではありません。

5変更前の識別子を保存する

後で新しいPodと比較するため、現在のPodのUIDを含むJSONを保存します。

kubectl get pods -l app=web -o json現在のPodをJSONで取得する > before.json python3 -c保存したPod数を確認する 'import json; print("saved_pods="+str(len(json.load(open("before.json"))["items"])))'

2個のPodの記録を保存しました。UIDは同名の資源が再作成されても別の値になります。

6Podを1個削除して補充を待つ

現在の先頭のPodを削除します。Deploymentのreplicasは2のままです。

kubectl delete podPodを1個削除する "$(kubectl get pods -l app=web -o jsonpath='{.items[0].metadata.name}')" --wait=true > /dev/null python3 observe.py wait 2 2 0必要な2個の準備完了を待つ python3 observe.py replacement変更前後のUID集合を比較する

2個へ戻り、replaced=1になります。削除したPodが復活したのではなく、新しいUIDのPodが作られています。

7必要な個数を3へ変える

継続して3個動かすには、Podを手動で増やすのではなく宣言のreplicasを変更します。

python3 -c宣言のreplicasを3へ変更する 'import json; p="deployment.json"; d=json.load(open(p)); d["spec"]["replicas"]=3; open(p,"w").write(json.dumps(d))' kubectl apply -f deployment.json変更した宣言を反映する python3 observe.py wait 3 3 03個の準備完了を確認する

宣言と実際のReady数が3になりました。controllerが埋める差の基準を変更したためです。

8同じ定義をもう一度適用する

何も編集せずapplyを繰り返します。

kubectl apply -f deployment.json同じ定義を再適用する python3 observe.py wait 3 3 0個数が増えていないことを確認する

unchangedで、個数も3のままです。同じ宣言を再適用するたびにPodが3個追加される操作ではありません。

まとめ

Podの削除後はReplicaSetが不足分を補充します。

継続する台数はDeploymentのreplicasで指定します。

APIへの受付とPodのReadyを別々に確認します。

操作履歴と解説を振り返れます。

Kubernetes 1.37.0 / kind 0.33.0 / Linux arm64

1
python3 -c 'import json; d=json.load(open("deployment.json")); print("replicas=",d["spec"]["replicas"]); print("selector=",d["spec"]["selector"]); print("image=",d["spec"]["template"]["spec"]["containers"][0]["image"])'
replicas= 2
selector= {'matchLabels': {'app': 'web'}}
image= alpine:3.22
2
kubectl apply -f deployment.json
deployment.apps/web created
3
python3 observe.py wait 2 2 0
pods=2 ready=2 restarts=0
4
python3 observe.py owners
Pod -> ReplicaSet -> Deployment/web
Pod -> ReplicaSet -> Deployment/web
5
kubectl get pods -l app=web -o json > before.json python3 -c 'import json; print("saved_pods="+str(len(json.load(open("before.json"))["items"])))'
saved_pods=2
6
kubectl delete pod "$(kubectl get pods -l app=web -o jsonpath='{.items[0].metadata.name}')" --wait=true > /dev/null python3 observe.py wait 2 2 0 python3 observe.py replacement
pods=2 ready=2 restarts=0
old=2 current=2 replaced=1
7
python3 -c 'import json; p="deployment.json"; d=json.load(open(p)); d["spec"]["replicas"]=3; open(p,"w").write(json.dumps(d))' kubectl apply -f deployment.json python3 observe.py wait 3 3 0
deployment.apps/web configured
pods=3 ready=3 restarts=0
8
kubectl apply -f deployment.json python3 observe.py wait 3 3 0
deployment.apps/web unchanged
pods=3 ready=3 restarts=0

演習完了