はじめに

Pod はコンテナを実行しますが、Kubernetes においてアプリケーションを実行する際、Pod 単体で運用することは一般的ではありません。Deployment はアプリケーションの「望ましい状態(desired state)」を記述し、ReplicaSet を作成します。そして、その ReplicaSet が Pod を作成・維持するという仕組みになっています。

この実験では、最初の Deployment を作成し、利用可能になるまで待機し、作成された Deployment、ReplicaSet、Pod を調査します。さらに、Pod を削除した際に Deployment がどのように Pod を復旧させるかを観察します。これは、スケーリング、ローリングアップデート、ロールバック、アプリケーションの公開といった、後の CKAD トピックの基礎となります。

Deployment 用名前空間の準備

このステップでは、Deployment の練習用にクリーンな名前空間を準備し、コマンドのデフォルト名前空間として設定します。

まずは /home/labex/project から始めます。この実験でマニフェストファイルを記述する必要はありませんが、同じワークスペースを使用することで一貫性を保ちます。

mkdir -p /home/labex/project
cd /home/labex/project

Kubernetes API サーバーに接続できるか確認します。VM が起動した直後でこのコマンドが失敗する場合は、数秒待ってからノードが Ready になるまで再実行してください。

kubectl get nodes --request-timeout=5s

期待される出力例:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Pod が Ready 状態になるには、クラスターのネットワークプラグインが必要です。アプリケーションのワークロードを作成する前に、Calico ノードの Pod が準備完了するのを待ちます。

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

期待される出力:

pod/calico-node-... condition met

ckad-prep-deployments という名前空間を作成します。

kubectl create namespace ckad-prep-deployments

作成が確認できるはずです。

namespace/ckad-prep-deployments created

この名前空間を現在のコンテキストの名前空間として設定します。

kubectl config set-context --current --namespace=ckad-prep-deployments

現在の名前空間を確認します。

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

期待される出力:

ckad-prep-deployments

Deployment の作成

このステップでは、2 つのレプリカを持つ web-demo という名前の Deployment を作成します。

kubectl create deployment コマンドは、Kubernetes に対して Deployment オブジェクトの作成を指示します。--image オプションは Pod テンプレート内のコンテナイメージを設定し、--replicas=2 は Deployment に対して一致する Pod を 2 つ維持するように指示します。

kubectl create deployment web-demo --image=registry.k8s.io/pause:3.10.1 --replicas=2

期待される出力:

deployment.apps/web-demo created

Deployment のロールアウトが完了するまで待ちます。新しい Deployment の場合、ロールアウトの完了とは、Kubernetes が ReplicaSet を作成し、要求された Pod が利用可能になったことを意味します。

kubectl rollout status deployment/web-demo --timeout=90s

Pod が利用可能になるまでの間、短い待機メッセージが表示される場合があります。最終的に以下のように表示されます。

deployment "web-demo" successfully rolled out

Deployment の概要を確認します。

kubectl get deployment web-demo

期待される出力例:

NAME       READY   UP-TO-DATE   AVAILABLE   AGE
web-demo   2/2     2            2           ...

ReplicaSet と Pod の調査

このステップでは、Deployment 配下に作成されたオブジェクトを調査します。

Deployment は直接コンテナを実行するわけではありません。Deployment が ReplicaSet を作成し、その ReplicaSet が Pod を作成します。Deployment のセレクターと Pod テンプレートのラベルが、これらのオブジェクトを紐付けています。

まず、Deployment のセレクターラベルとテンプレートラベルを確認します。JSONPath を使用して特定のフィールドのみを出力し、結果を見やすくします。

kubectl get deployment web-demo -o 'jsonpath={.spec.selector.matchLabels.app}{" "}{.spec.template.metadata.labels.app}{"\n"}'

期待される出力:

web-demo web-demo

最初の値は Deployment のセレクターラベル、2 番目の値はテンプレートから作成された Pod に付与されたラベルです。これらが一致しているため、Deployment はその Pod を管理できます。

Deployment によって作成された ReplicaSet を一覧表示します。

kubectl get replicasets -l app=web-demo

期待される出力例:

NAME                  DESIRED   CURRENT   READY   AGE
web-demo-...          2         2         2       ...

次に、同じラベルで選択される Pod を一覧表示します。

kubectl get pods -l app=web-demo --show-labels

2 つの実行中の Pod が表示されるはずです。

NAME                        READY   STATUS    RESTARTS   AGE   LABELS
web-demo-...                1/1     Running   0          ...   app=web-demo,pod-template-hash=...
web-demo-...                1/1     Running   0          ...   app=web-demo,pod-template-hash=...

最後に、各 Pod のオーナーの種類(Kind)を表示します。各 Pod は Deployment ではなく、ReplicaSet によって所有されています。

kubectl get pods -l app=web-demo -o 'custom-columns=NAME:.metadata.name,OWNER:.metadata.ownerReferences[0].kind,PHASE:.status.phase'

期待される出力:

NAME                        OWNER        PHASE
web-demo-...                ReplicaSet   Running
web-demo-...                ReplicaSet   Running

望ましい状態の復旧の観察

このステップでは、現在の Pod を削除し、Deployment がどのように望ましい状態を復旧させるかを観察します。

これが単一の Pod と Deployment の決定的な違いです。単独の Pod を削除すると、その Pod は消滅します。しかし、Deployment によって管理されている Pod を削除すると、Deployment は「現在の状態」が「望ましい状態」と一致しなくなったことを検知し、代替の Pod を作成します。

app=web-demo ラベルを持つ Pod を削除します。--wait=false オプションを指定すると、削除リクエストを送信した直後にコマンドが終了するため、古い Pod が完全に消えるのを待たずに復旧の様子を観察できます。

kubectl delete pods -l app=web-demo --wait=false

期待される出力例:

pod "web-demo-..." deleted from ckad-prep-deployments namespace
pod "web-demo-..." deleted from ckad-prep-deployments namespace

Deployment が再び利用可能になるまで待ちます。

kubectl wait --for=condition=Available deployment/web-demo --timeout=90s

期待される出力:

deployment.apps/web-demo condition met

Pod を再度一覧表示します。

kubectl get pods -l app=web-demo

2 つの実行中の Pod が表示されます。ReplicaSet によって新しい Pod が作成されたため、名前が変わっている可能性があります。

NAME                        READY   STATUS    RESTARTS   AGE
web-demo-...                1/1     Running   0          ...
web-demo-...                1/1     Running   0          ...

Deployment の概要をもう一度確認します。

kubectl get deployment web-demo

期待される出力例:

NAME       READY   UP-TO-DATE   AVAILABLE   AGE
web-demo   2/2     2            2           ...

まとめ

Deployment を作成し、ロールアウトを待ち、セレクターと Pod テンプレートのラベルを調査し、作成された ReplicaSet と Pod を確認しました。さらに、Pod を削除した後に Deployment が望ましい状態を復旧させる様子を観察しました。これらの概念は、レプリカ数の変更、アプリケーションの更新、ローリングアップデートの管理など、次の Deployment 関連の実験に進むための重要な基礎となります。