0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【KCNA】KubernetesでPodとDeploymentの違いを確認する|自動復旧・スケール・ローリング更新(Part3)

0
Posted at

はじめに

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数の維持や更新の管理が行えるようになります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?