適切なワークロードリソースの選択

KubernetesBeginner
オンラインで実践に進む

はじめに

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 スタイルのマニフェストを作成する前に、適切なリソースを選択する助けとなります。