はじめに
Kubernetesで単独のPodとDeploymentを作成し、管理方法の違いを確認します。
本記事では、以下の操作を行います。
- 単独Podの作成と削除
- Podの状態・イベントの確認
- DeploymentによるPodの管理
- Pod削除後の自動補充
- Pod数の変更(水平スケール)
- コンテナイメージのローリング更新と切り戻し
操作にはkubectl runやkubectl create deploymentなど、コマンドで直接リソースを作成・変更する命令的な方法を使用します。
1. 前提条件
前の記事で作成した、kindのtrainingクラスタを使用します。
操作前に、接続先を確認してください。
kubectl config current-context
想定するコンテキストは以下です。
kind-training
必要に応じて、コンテキストを切り替えます。
kubectl config use-context kind-training
本記事ではdefault名前空間を使用します。コマンドで名前空間を省略できるよう、現在のコンテキストに設定します。
kubectl config set-context --current --namespace=default
同じ名前のPod soloやDeployment webが存在しない状態で作業してください。
出力例のPod名、IPアドレス、配置先ノード、経過時間などは、実行環境によって異なります。
2. 単独のPodを作成する
Nginxを実行するPodを1つ作成します。
kubectl run solo --image=nginx:1.27
起動状態を確認します。
kubectl get pod solo -o wide
出力例:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
solo 1/1 Running 0 9s 10.244.1.2 training-worker2 <none> <none>
表示内容の見方
| 項目 | 意味 |
|---|---|
NAME |
Pod名 |
READY |
準備完了のコンテナ数/対象のコンテナ数 |
STATUS |
Podの状態 |
RESTARTS |
コンテナの再起動回数 |
IP |
Podに割り当てられたIPアドレス |
NODE |
Podが配置されたノード |
作成直後はPendingやContainerCreatingになることがあります。準備が完了すると、今回の例ではREADYが1/1、STATUSがRunningになります。
単独Podの特徴
このコマンドで作成するPodには、DeploymentやReplicaSetによる管理がありません。そのため、Pod自体を削除しても、新しいPodは自動作成されません。
一方、Pod内のコンテナが終了した場合は、既定のrestartPolicy: Alwaysに基づいて、kubeletがコンテナを再起動します。
「コンテナの再起動」と「削除したPodの再作成」は異なる動作です。
参考:Kubernetes公式ドキュメント:kubectl run
3. Podの詳細とイベントを確認する
kubectl describe pod solo
末尾の情報だけを確認したい場合は、以下のように表示できます。
kubectl describe pod solo | tail -n 20
ただし、末尾20行だけでは、コンテナの状態やConditionsなどが省略されることがあります。問題の調査時には、全体の出力も確認してください。
イベントの確認
Eventsには、Podの配置やコンテナ起動に関する情報が表示されます。
出力例(抜粋):
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 26s default-scheduler Successfully assigned default/solo to training-worker2
Normal Pulling 26s kubelet Pulling image "nginx:1.27"
Normal Pulled 19s kubelet Successfully pulled image "nginx:1.27"
Normal Created 19s kubelet Created container solo
Normal Started 19s kubelet Started container solo
| イベント | 意味 |
|---|---|
Scheduled |
配置先ノードが決定した |
Pulling |
コンテナイメージを取得している |
Pulled |
コンテナイメージを取得した |
Created |
コンテナを作成した |
Started |
コンテナを起動した |
状態・配置・リソースに関する項目
| 項目 | 意味 |
|---|---|
PodScheduled: True |
Podの配置先ノードが決まっている |
Volumes |
Podで利用するボリュームの一覧 |
Node-Selectors: <none> |
nodeSelectorによる配置先の絞り込みがない |
QoS Class: BestEffort |
CPU・メモリのRequestsとLimitsを設定していない場合のQoSクラス |
今回のPodでは、CPU・メモリの要求量(Requests)や上限(Limits)を指定していません。名前空間の設定などによって値が補われなければ、BestEffortになります。
参考:Kubernetes公式ドキュメント:Pod Quality of Service Classes
Kubernetes APIへのアクセス用ボリューム
通常、Podにはkube-api-access-xxxxxという名前のボリュームが自動で追加されます。
表示例:
Volumes:
kube-api-access-xn2qj:
Type: Projected
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
| 項目 | 意味 |
|---|---|
Projected |
複数の情報源を1つのボリュームにまとめる形式 |
TokenExpirationSeconds |
ServiceAccountトークンに要求する有効期間。Pod自体の寿命ではない |
ConfigMapName: kube-root-ca.crt |
APIサーバーの証明書検証に使うCA情報の取得元 |
ConfigMapOptional: <nil> |
optionalの明示指定がないことを表す。取得元の欠落を許可する指定ではない |
DownwardAPI: true |
名前空間など、Pod自身の情報をファイルとして渡す |
参考:Kubernetes公式ドキュメント:Projected Volumes
Tolerations
Tolerationsは、ノードに設定されたtaintをPodがどのように許容するかを指定します。
taintは、Podの配置や退避に影響するノード側の設定です。以下は、ノードが準備未完了・到達不能になった場合に関係する設定です。
node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
対応するtaintが付いても、Podがそのノードに残ることを300秒間許容します。
| 項目 | 意味 |
|---|---|
not-ready |
ノードが準備未完了の状態 |
unreachable |
ノードに到達できない状態 |
NoExecute |
許容しないPodの退避にも作用するtaintの効果 |
op=Exists |
taintの値によらず、対応するキーを許容 |
for 300s |
そのtaintを300秒間許容 |
この設定は、ノード障害時にPodが動作し続けることを保証するものではありません。
参考:Kubernetes公式ドキュメント:Taints and Tolerations
4. 単独Podを削除する
作成したPodを削除します。
kubectl delete pod solo
削除後の状態を確認します。
kubectl get pods
soloが表示されなくなり、その後も自動で再作成されないことを確認します。
ほかのPodが存在しない場合は、次のように表示されます。
No resources found in default namespace.
5. Deploymentを作成する
次に、NginxのPodを3つ管理するDeploymentを作成します。
kubectl create deployment web --image=nginx:1.27 --replicas=3
作成したリソースを確認します。
kubectl get deployments.apps,rs,pods
出力例:
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/web 3/3 3 3 27s
NAME DESIRED CURRENT READY AGE
replicaset.apps/web-c7d75d445 3 3 3 27s
NAME READY STATUS RESTARTS AGE
pod/web-c7d75d445-98mj6 1/1 Running 0 27s
pod/web-c7d75d445-kv47s 1/1 Running 0 27s
pod/web-c7d75d445-lqcrb 1/1 Running 0 27s
rsはReplicaSetの省略名です。
Deployment・ReplicaSet・Podの関係
Deployment:Podテンプレートの更新やReplicaSetの世代を管理
└─ ReplicaSet:指定されたPod数を維持
├─ Pod
├─ Pod
└─ Pod
Deploymentを作成すると、ReplicaSetを介してPodが管理されます。Podが不足した場合は、ReplicaSetが新しいPodを作成します。
Deploymentの表示項目
| 項目 | 意味 |
|---|---|
READY: 3/3 |
希望する3個に対し、準備完了のPodが3個 |
UP-TO-DATE: 3 |
現在のPodテンプレートに対応するPodが3個 |
AVAILABLE: 3 |
利用可能と判定されたPodが3個 |
ReplicaSetの表示項目
| 項目 | 意味 |
|---|---|
DESIRED |
希望するPod数 |
CURRENT |
現在管理しているPod数 |
READY |
準備完了のPod数 |
参考:Kubernetes公式ドキュメント:Deployments
6. ラベルとPod名を確認する
Deployment webに対応するPodを、ラベルで絞り込んで表示します。
kubectl get pods -l app=web --show-labels
出力例:
NAME READY STATUS RESTARTS AGE LABELS
web-c7d75d445-98mj6 1/1 Running 0 41s app=web,pod-template-hash=c7d75d445
web-c7d75d445-kv47s 1/1 Running 0 41s app=web,pod-template-hash=c7d75d445
web-c7d75d445-lqcrb 1/1 Running 0 41s app=web,pod-template-hash=c7d75d445
オプションとラベルの意味
| 項目 | 意味 |
|---|---|
-l app=web |
app=webラベルを持つPodだけを表示 |
--show-labels |
ラベル一覧を表示 |
app=web |
今回の作成コマンドによって付与されたアプリ識別用のラベル |
pod-template-hash |
Podテンプレートから生成され、ReplicaSetを区別するために使われる値 |
今回作成されるPod名の構成
web-c7d75d445-98mj6
│ │ └─ 個々のPodを区別する接尾辞
│ └─ Podテンプレート由来のハッシュ
└─ Deployment名
Podテンプレートを変更すると、通常は異なるハッシュを持つReplicaSetが作成されます。
7. Podを削除して自動補充を確認する
Deploymentで管理しているPodを1つ削除します。
kubectl delete pod "$(kubectl get pods -l app=web \
-o jsonpath='{.items[0].metadata.name}')"
その後、Podの状態を継続的に表示します。
kubectl get pods -l app=web -w
確認を終了する場合は、Ctrl+Cを押します。Ctrl+Cで終了するのは監視コマンドであり、Podは削除されません。
削除コマンドの解説
| 項目 | 意味 |
|---|---|
-l app=web |
対象のPodをラベルで絞り込む |
-o jsonpath=... |
結果から指定した項目を取り出す |
.items[0] |
一覧の最初の要素 |
.metadata.name |
リソースの名前 |
$(...) |
内側のコマンドの出力を、外側のコマンドの引数として使用 |
-w |
最初の一覧を表示した後、変更を継続的に表示 |
確認するポイント
Podを削除すると、ReplicaSetが不足を検知して、新しいPodを作成します。
削除したPodが復活するのではなく、別名・別UIDのPodが補充されます。
新しいPodの準備が完了し、再び3つのPodがRunningかつREADY: 1/1になることを確認してください。
補充が速い場合は、監視開始時点ですでに新しいPodが表示されることもあります。
8. Pod数を変更する(水平スケール)
Pod数を5つに増やす
kubectl scale deployment web --replicas=5
kubectl rollout status deployment/web
kubectl get pods -l app=web
Podが5つになり、それぞれ準備完了になることを確認します。
Pod数を2つに減らす
kubectl scale deployment web --replicas=2
kubectl rollout status deployment/web
kubectl get pods -l app=web
不要になったPodが削除され、最終的に2つになることを確認します。
--replicasは希望するPod数を指定するオプションです。変更直後は作成中・終了中のPodが表示されるため、反映には少し時間がかかります。
ここで変更しているのはPod数です。kindのワーカーノード数は変わりません。
9. コンテナイメージをローリング更新する
Deployment webのコンテナイメージを、nginx:1.27からnginx:1.29へ変更します。
今回の作成コマンドではコンテナ名がnginxになるため、その名前を指定します。
kubectl set image deployment/web nginx=nginx:1.29
更新の進行状況を確認します。
kubectl rollout status deployment/web
更新後のPodと、Deploymentに設定されたイメージを確認します。
kubectl get pods -l app=web
kubectl get deployment web \
-o jsonpath='{.spec.template.spec.containers[*].image}{"\n"}'
イメージの想定出力:
nginx:1.29
コマンドの解説
| 項目 | 意味 |
|---|---|
set image |
Podテンプレート内のコンテナイメージを変更 |
deployment/web |
操作対象のリソース種類と名前 |
nginx=nginx:1.29 |
コンテナ名nginxのイメージを変更 |
rollout status |
更新の進行状況を表示し、完了まで待機 |
すべてのコンテナを対象にする場合は、次のようにも指定できます。
kubectl set image deployment/web '*=nginx:1.29'
*を引用符で囲むのは、シェルによる展開を防ぐためです。複数のコンテナを持つPodでは、意図したコンテナ名を指定してください。
参考:Kubernetes公式ドキュメント:kubectl set image
ローリング更新と無停止の関係
今回のDeploymentでは、既定のRollingUpdate方式により、新しいPodを作成しながら古いPodを順次置き換えます。
ローリング更新は無停止を目指す方式ですが、必ず無停止になるわけではありません。実際の通信を継続するには、Serviceによる振り分け、適切なreadiness probe、終了処理、リソースの余裕などが必要です。
本記事では、Podの置き換えと更新完了を確認します。通信が途切れないことの検証は行っていません。
10. 直前のイメージへ切り戻す
直前のPodテンプレートへ戻します。
kubectl rollout undo deployment/web
切り戻しの完了を待ちます。
kubectl rollout status deployment/web
イメージとPod数を確認します。
kubectl get deployment web \
-o jsonpath='{.spec.template.spec.containers[*].image}{"\n"}'
kubectl get deployment web
kubectl get pods -l app=web
本記事の手順どおりに実行した場合、イメージは以下に戻ります。
nginx:1.27
切り戻しで戻るもの
rollout undoで戻るのは、DeploymentのPodテンプレートです。
直前のスケール操作まで取り消すわけではないため、希望するPod数は2個のままです。また、アプリケーションが外部データベースなどに書き込んだデータも元には戻りません。
参考:Kubernetes公式ドキュメント:Deploymentのロールバック
11. 単独PodとDeploymentの違い
| 操作・機能 | 単独Pod | Deploymentで管理するPod |
|---|---|---|
| Pod削除後の自動補充 | されない | ReplicaSetが新しいPodを作成 |
| Pod数の維持 | 管理するコントローラーがない | 指定したPod数を維持 |
| Pod数の変更 | Podを個別に作成・削除 |
kubectl scaleで変更 |
| イメージ更新 | Deploymentによる更新管理はない | ローリング更新が可能 |
| Podテンプレートの切り戻し | Deploymentの履歴管理はない |
kubectl rollout undoで可能 |
コンテナの再起動は、どちらの場合もPodのrestartPolicyに従います。Deploymentを使うことで、それに加えてPod数の維持や更新の管理が行えるようになります。