はじめに
CKAD のタスクでは、マニフェストを作成する前に、適切な Kubernetes ワークロードリソースを選択することが求められます。Pod は実行可能な最小単位であり、Deployment は長時間稼働するアプリケーションのレプリカを維持し、Job はタスクを完了まで実行し、CronJob はスケジュールされた Job テンプレートを保持します。
この実験では、定義を暗記するのではなく、実際の動作を観察することでこれらのリソースを比較します。スタンドアロンの Pod は削除後に再作成されないこと、Deployment は Pod を再作成すること、Job は完了して成功を記録すること、そして CronJob は定期的なタスクのためのスケジュール情報を保持することを学びます。
ワークロード比較用名前空間の準備
このステップでは、ワークロードリソースを比較するためのクリーンな名前空間を準備します。
/home/labex/project から開始します。このディレクトリ内で、ワークロードの動作を比較するための小さなマニフェストを作成します。
mkdir -p /home/labex/project
cd /home/labex/project
Kubernetes API サーバーにアクセスできるか確認します。VM が起動した直後でノードの準備ができていない場合は、数秒待ってから再度コマンドを実行してください。
kubectl get nodes --request-timeout=5s
期待される出力例:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
ワークロードは Pod を作成するため、クラスターのネットワーキング Pod が Ready になるまで待ちます。
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
期待される出力:
pod/calico-node-... condition met
ckad-prep-workloads という名前空間を作成します。
kubectl create namespace ckad-prep-workloads
この名前空間を現在のコンテキストの名前空間として設定します。
kubectl config set-context --current --namespace=ckad-prep-workloads
現在の名前空間を確認します。
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
期待される出力:
ckad-prep-workloads
Pod と Deployment の比較
このステップでは、スタンドアロンの Pod と Deployment を比較します。両方の Pod を削除し、Kubernetes が次にどのような動作をするかを観察します。
スタンドアロンの Pod は、非常に小さなタスクや調査のために、直接管理されるランタイムユニットが必要な場合に便利です。Deployment は、ReplicaSet を所有し、要求された数の Pod を維持するため、長時間稼働するアプリケーションに適しています。
スタンドアロンの Pod マニフェストを作成します。コンテナは sleep するため、Pod は観察に十分な時間稼働し続けます。terminationGracePeriodSeconds: 0 フィールドを設定することで、後で Pod を削除する際に実験を素早く進められます。
cat > standalone-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: standalone-task
labels:
app: standalone-task
workload.labex.io/intent: direct-pod
spec:
terminationGracePeriodSeconds: 0
containers:
- name: sleeper
image: busybox:1.36
command: ["/bin/sh", "-c", "sleep 3600"]
EOF
Deployment マニフェストを作成します。この Deployment は、1 つの managed-worker Pod を維持するように Kubernetes に指示し、Pod テンプレートには同じく素早い終了設定を使用します。
cat > managed-deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: managed-worker
labels:
workload.labex.io/intent: long-running
spec:
replicas: 1
selector:
matchLabels:
app: managed-worker
template:
metadata:
labels:
app: managed-worker
spec:
terminationGracePeriodSeconds: 0
containers:
- name: sleeper
image: busybox:1.36
command: ["/bin/sh", "-c", "sleep 3600"]
EOF
両方のマニフェストを適用します。
kubectl apply -f standalone-pod.yaml
kubectl apply -f managed-deployment.yaml
期待される出力:
pod/standalone-task created
deployment.apps/managed-worker created
両方のワークロードが準備完了になるまで待ちます。
kubectl wait --for=condition=Ready pod/standalone-task --timeout=120s
kubectl wait --for=condition=Available deployment/managed-worker --timeout=120s
期待される出力:
pod/standalone-task condition met
deployment.apps/managed-worker condition met
現在の Deployment の Pod 名を取得し、スタンドアロンの Pod と Deployment が管理する Pod の両方を削除します。
managed_pod="$(kubectl get pods -l app=managed-worker -o 'jsonpath={.items[0].metadata.name}')"
kubectl delete pod standalone-task "$managed_pod"
期待される出力例:
pod "standalone-task" deleted
pod "managed-worker-..." deleted
Deployment が再び利用可能になるまで待ちます。
kubectl wait --for=condition=Available deployment/managed-worker --timeout=120s
期待される出力:
deployment.apps/managed-worker condition met
Pod を一覧表示します。スタンドアロンの Pod は消滅し、新しい managed-worker Pod が存在しているはずです。
kubectl get pods
期待される出力には managed-worker Pod が含まれますが、standalone-task は含まれません。
NAME READY STATUS RESTARTS AGE
managed-worker-... 1/1 Running 0 ...
完了を目的とした Job の選択
このステップでは、永続的に実行するのではなく、正常に終了すべきタスクのために Job を選択します。
Deployment は「このアプリケーションを稼働させ続ける」という望ましい状態に適しています。Job は「このタスクが完了するまで実行する」という望ましい状態に適しています。そのため、マイグレーション、バッチ処理、一度限りのメンテナンスコマンドなどは通常 Job として実行されます。
schema-migration という名前の Job を作成します。
kubectl create job schema-migration --image=busybox:1.36 -- /bin/sh -c 'echo migration-start; echo migration-complete'
期待される出力:
job.batch/schema-migration created
Job が Complete 条件に達するまで待ちます。
kubectl wait --for=condition=Complete job/schema-migration --timeout=120s
期待される出力:
job.batch/schema-migration condition met
Job の概要を確認します。COMPLETIONS が 1/1 と表示されていれば、タスクが一度正常に完了したことを意味します。
kubectl get job schema-migration
期待される出力例:
NAME STATUS COMPLETIONS DURATION AGE
schema-migration Complete 1/1 ... ...
Job のログを読み取ります。
kubectl logs job/schema-migration
期待される出力:
migration-start
migration-complete
定期的なタスクのための CronJob の選択
このステップでは、スケジュールに従って実行すべきタスクのために CronJob を選択します。
CronJob はスケジュールされた Job テンプレートです。一度だけ完了するのではなく、後でタスクを繰り返す必要がある場合に適した選択肢です。このガイド付き実験では、決定論的な動作を維持するために、CronJob を一時停止(suspend)状態で作成します。これにより、時計の境界を待つことなく、スケジュールとテンプレートを確認できます。
cleanup-cronjob.yaml を作成します。
cat > cleanup-cronjob.yaml <<'EOF'
apiVersion: batch/v1
kind: CronJob
metadata:
name: cleanup-schedule
labels:
workload.labex.io/intent: recurring-task
spec:
schedule: "*/5 * * * *"
suspend: true
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: cleanup
image: busybox:1.36
command:
- /bin/sh
- -c
- 'echo cleanup-ready'
EOF
マニフェストを適用します。
kubectl apply -f cleanup-cronjob.yaml
期待される出力:
cronjob.batch/cleanup-schedule created
CronJob の概要を確認します。この実験ではスケジュールされた Job を待たずにリソースの選択を学ぶため、SUSPEND は True になっています。
kubectl get cronjob cleanup-schedule
期待される出力例:
NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE
cleanup-schedule */5 * * * * <none> True 0 <none> ...
オブジェクトから直接スケジュールとテンプレートのイメージを読み取ります。
kubectl get cronjob cleanup-schedule -o 'jsonpath={.spec.schedule}{" "}{.spec.suspend}{" "}{.spec.jobTemplate.spec.template.spec.containers[0].image}{"\n"}'
期待される出力:
*/5 * * * * true busybox:1.36
この実験で作成したワークロードリソースを一覧表示します。この表示により、リソースタイプと意図された動作が結びつきます。長時間稼働するレプリカには Deployment、完了を目的とするタスクには Job、定期的な実行には CronJob を使用します。
kubectl get deployment,job,cronjob
期待される出力例:
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/managed-worker 1/1 1 1 ...
NAME STATUS COMPLETIONS DURATION AGE
job.batch/schema-migration Complete 1/1 ... ...
NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/cleanup-schedule */5 * * * * <none> True 0 <none> ...
まとめ
Kubernetes のワークロードリソースをその動作に基づいて比較しました。スタンドアロンの Pod は削除後に再作成されず、Deployment はレプリカを維持するために Pod を再作成し、Job はタスクを正常に完了させ、CronJob は定期的な Job テンプレートを保持しました。これらの観察結果は、CKAD スタイルのマニフェストを作成する前に、適切なリソースを選択する助けとなります。


