Lab 11 - Jobs and CronJobs

Lab 11 - Jobs and CronJobs

Goal: run work that finishes, in parallel, on a schedule - and see how a failing Job gives up. Chapter: Jobs and CronJobs

# 1 - a one-off Job
cd ~
kubectl create job hello --image busybox:1.36 -- sh -c 'echo "hello from $(hostname)"; sleep 5'
kubectl get job,pods -l job-name=hello
kubectl wait --for=condition=complete job/hello --timeout=60s
kubectl logs job/hello

COMPLETIONS 1/1 and the Pod in Completed. The Pod is kept so you can read its log.

# 2 - completions and parallelism
cat > batch.yaml <<'YAML'
apiVersion: batch/v1
kind: Job
metadata:
  name: batch
spec:
  completions: 6
  parallelism: 2
  ttlSecondsAfterFinished: 300
  template:
    spec:
      restartPolicy: Never
      containers:
        - name: work
          image: busybox:1.36
          command: ["sh", "-c", "echo working on $(hostname); sleep 8"]
YAML
kubectl apply -f batch.yaml
kubectl get pods -l job-name=batch -w      # Ctrl-C after 6 Completed

Never more than two Pods at a time, six successes in total.

# 3 - a Job that always fails
kubectl create job broken --image busybox:1.36 --dry-run=client -o yaml \
  -- sh -c 'echo failing; exit 1' > broken.yaml
sed -i 's/^spec:/spec:\n  backoffLimit: 2/' broken.yaml
kubectl apply -f broken.yaml
kubectl get pods -l job-name=broken -w     # Ctrl-C after ~1 minute
kubectl describe job broken | tail -5

Each retry waits longer (10 s, 20 s, 40 s …). After backoffLimit retries the Job is Failed with reason BackoffLimitExceeded.

CronJob

# 4 - every minute
kubectl create cronjob tick --image busybox:1.36 --schedule '*/1 * * * *' \
  -- sh -c 'date; echo tick'
kubectl get cronjob tick
kubectl get jobs -w                        # a new Job each minute; Ctrl-C after 2
kubectl logs job/$(kubectl get jobs -o name | grep tick | tail -1 | cut -d/ -f2)
# 5 - run it now, then pause it
kubectl create job tick-manual --from=cronjob/tick
kubectl patch cronjob tick -p '{"spec":{"suspend":true}}'
kubectl get cronjob tick                   # SUSPEND True

Discovery

Infodiscover

Task A. Create a CronJob backup that runs at 02:30 every night in Prague time, never overlaps with itself and keeps only one successful Job.

kubectl create cronjob backup --image busybox:1.36 --schedule '30 2 * * *' \
  --dry-run=client -o yaml -- sh -c 'echo backup' > backup.yaml
# edit backup.yaml, under spec: add
#   timeZone: "Europe/Prague"
#   concurrencyPolicy: Forbid
#   successfulJobsHistoryLimit: 1
kubectl apply -f backup.yaml
kubectl get cronjob backup -o yaml | grep -E 'timeZone|concurrency|successful'

Task B. Make a Job that is killed if it runs longer than 10 seconds (sleep 60 inside). What is the failure reason?

kubectl create job slow --image busybox:1.36 --dry-run=client -o yaml -- sleep 60 > slow.yaml
sed -i 's/^spec:/spec:\n  activeDeadlineSeconds: 10/' slow.yaml
kubectl apply -f slow.yaml
sleep 15; kubectl describe job slow | grep -i -A2 reason

DeadlineExceeded.

Clean up

kubectl delete job hello tick-manual slow --ignore-not-found
kubectl delete -f batch.yaml -f broken.yaml --ignore-not-found
kubectl delete cronjob tick backup --ignore-not-found