Free lesson · CKAD Prep Program · Module 2: Application design and build
Run Batch Work with Jobs and CronJobs
Deployments babysit forever processes; Jobs run work that must finish. This lesson covers the controllers for finite work, one-shot and scheduled, with the knobs that control retries and concurrency.
11 min reading
Objectives
- Choose Job over Deployment for run-to-completion work and say why
- Set completions, parallelism and backoffLimit to match the workload
- Write a CronJob schedule that actually means what you intend
- Read job history and pod logs to prove the batch finished
Why this matters
Migrations, report generation, queue draining, nightly cleanup: production is full of work that should run, finish, and stop. Running it as a Deployment wastes a restart loop and hides the completion signal. The exam checks the distinction constantly, plus the failure knobs, because batch jobs that retry forever are how clusters melt at night.
Concepts
A Job creates pods until the completion count is met. completions says how many successful pods finish the work; parallelism says how many run at once; backoffLimit caps retries before the whole Job is marked failed. restartPolicy: Never or OnFailure is required (the default Always belongs to long-running pods and is rejected). activeDeadlineSeconds bounds total run time so a stuck batch cannot burn quota all weekend.
A CronJob wraps a Job template in a schedule. The schedule is standard cron plus an optional timezone; concurrencyPolicy decides what happens when a run overruns its slot (Allow, Forbid, Replace). successfulJobsHistoryLimit plus failedJobsHistoryLimit keep history readable instead of infinite. Suspend pauses everything without deleting the definition, which is the safe way to stop a noisy schedule during an incident.
Worked example
Nightly report, one at a time, keep three successes for inspection:
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-report
spec:
schedule: "30 2 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
backoffLimit: 2
activeDeadlineSeconds: 600
template:
spec:
restartPolicy: OnFailure
containers:
- name: report
image: busybox
command: ["sh", "-c", "echo report-$(date +%F)"]Check with kubectl get jobs after the minute passes, then kubectl logs job/<name> for the output. Forbid plus a ten-minute deadline means a stuck run neither piles up nor burns the night.
Exam notes
restartPolicy: Always on a Job template is rejected by the API: memorize Never or OnFailure. Cron schedules run in the controller's timezone unless set, so always state yours. And history limits prune Jobs but never running pods: a Wedged run still needs deleting by hand.
Quick check
A 4-question self-check. Your answers stay on your device, are never stored or sent. Only a passing score (for example 3 of 4) is saved, and only to unlock lesson progress: at least 3 correct is required before a lesson counts as complete. It never counts toward any certification assessment.
Lesson feedback
No published feedback yet.
Log in and complete the lesson to leave feedback.
Exercise
Write a CronJob that runs every 15 minutes, allows at most 2 concurrent runs worth of behavior (pick and justify the policy), retries twice, and keeps five successful histories. Then describe how you confirm the third scheduled run completed.
Pass criteria
Schedule reads every-15-minutes; policy chosen with a one-line justification; backoffLimit 2 and history 5 present; confirmation names jobs list plus pod logs.