Home › CKAD › Topics › Practice tasks › Jobs & CronJobs
CKAD · Application Design and Build

Create a CronJob with History Limits and a Deadline

Create a CronJob named backup-job in namespace default with the following specifications: Schedule: Run every 30 minutes (*/30 * * * *) Image: busybox:latest Container command: echo "Backup…

Check live lab access → All CKAD tasks

Live lab access

This task description is public. Live practice requires full access unless this is the selected free weekly task. AI Lab Coach is available in single-task labs, including the free weekly task. See this week's free task.

Create an account to continue →

Read this week's free task →

On a phone? Read the task and create your account here, then sign in on a desktop or laptop for the terminal lab. Nothing starts until you choose Start.

The task

Task

Create a CronJob named backup-job in namespace default with the following specifications:

Tip: Use kubectl explain cronjob.spec to find the correct field names.

Original Prepium guide · Written for Kubernetes v1.35 and checked against the official documentation on 6 October 2026. Use a disposable practice cluster.

CronJobs are three objects deep: put each field at the right level

A CronJob does not run containers. It creates a Job on a schedule, and the Job creates Pods. Each layer owns different settings, and most CronJob mistakes on the exam are a correct field placed one level too high or too low. kubectl's default strict validation rejects a field that does not exist at that level, but some names, such as activeDeadlineSeconds, exist at two levels and mean different things.

CronJob .spec            schedule, timeZone, concurrencyPolicy, startingDeadlineSeconds,
  |                      successfulJobsHistoryLimit, failedJobsHistoryLimit, suspend
  '-- jobTemplate.spec   activeDeadlineSeconds, backoffLimit
        '-- template.spec  containers, restartPolicy (Never or OnFailure)

1. Read the schedule before you write it

The schedule has five fields: minute, hour, day of month, month, day of week (0 is Sunday). 15 2 * * 1-5 means 02:15 on weekdays. A step after an asterisk repeats through the whole range, so */20 in the minute field fires at :00, :20 and :40. Macros such as @hourly and @daily also work. Without .spec.timeZone, the schedule follows the kube-controller-manager's local time zone; putting TZ= or CRON_TZ= inside the schedule string is rejected by validation.

2. A manifest with every layer visible

apiVersion: batch/v1
kind: CronJob
metadata:
  name: ledger-report
  namespace: prepium-tutorial
spec:
  schedule: "15 2 * * 1-5"
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 600
  failedJobsHistoryLimit: 4
  jobTemplate:
    spec:
      activeDeadlineSeconds: 120
      backoffLimit: 2
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: report
            image: busybox:1.36
            command: ["sh", "-c", "date; echo ledger totals ready"]

What each choice does:

3. Test it now instead of waiting until 02:15

kubectl create namespace prepium-tutorial
kubectl apply -f ledger-report.yaml
kubectl create job ledger-manual --from=cronjob/ledger-report -n prepium-tutorial
kubectl -n prepium-tutorial wait --for=condition=Complete job/ledger-manual --timeout=90s
kubectl -n prepium-tutorial logs job/ledger-manual

--from=cronjob/ copies the CronJob's job template into a one-off Job, so it proves the Pod spec, command and image without touching the schedule. You can also generate a starting manifest with kubectl create cronjob NAME --image=... --schedule="..." --restart=OnFailure --dry-run=client -o yaml -- COMMAND and add the remaining fields by hand.

4. Confirm the stored values

kubectl -n prepium-tutorial get cronjob ledger-report -o yaml
kubectl explain cronjob.spec.jobTemplate.spec.activeDeadlineSeconds

Read back the YAML and check that defaults were filled in where you left fields out. kubectl explain with the full path settles any doubt about which level a field belongs to.

Common mistakes

Example checkEvidence
Schedule is what you meant.spec.schedule, read field by field
Job-level limits in the right place.spec.jobTemplate.spec.activeDeadlineSeconds set
History retentionBoth history limits present in the stored object
Pod spec worksA Job created --from=cronjob/ completes and logs the expected line

Cleanup: kubectl delete namespace prepium-tutorial. References: CronJob, Jobs, kubectl create job. Next, try choosing the right workload controller.

Exam
CKAD
Domain
Application Design and Build
Grading
Programmatic · partial credit

What this tests

Define pods and multi-container patterns, build container images, and run jobs and cronjobs. On the CKAD exam, Application Design and Build tasks are graded purely on what you build in the cluster - not multiple choice - so the only way to get faster is to do them on a real cluster against a clock.

Practice it for real

The public description lets you study the task before signing up. Full access includes this live lab; the selected Task of the Week is free with an account. You solve the task in a real terminal, hit validate, and a programmatic checker scores exactly what you got right and wrong (with partial credit). You can open the solution while practising, then retry and use the failed checks to improve your score.

Related CKAD tasks