Not every workload runs continuously — Kubernetes Jobs and CronJobs handle finite, batch, or scheduled tasks, distinct from the always-running Deployment pattern. This guide covers both.
Jobs vs Deployments: The Key Difference
A Deployment (see Kubernetes Pods, Deployments & Services Explained) manages pods meant to run continuously, restarting them if they fail or complete; a Job runs a pod to completion — success means the task is genuinely done, not something to restart indefinitely.
Basic Job Example
apiVersion: batch/v1
kind: Job
metadata:
name: data-migration
spec:
template:
spec:
containers:
- name: migration
image: myapp:latest
command: ["python", "migrate.py"]
restartPolicy: Never
backoffLimit: 3
Runs the specified command to completion — backoffLimit controls how many retry attempts occur if the job fails before giving up entirely.
Running Jobs in Parallel
spec:
parallelism: 5
completions: 20
Useful for batch processing that can be split into independent parallel work items — runs up to 5 pods simultaneously, continuing until 20 total successful completions are reached.
Setting a Job Timeout
spec:
activeDeadlineSeconds: 600
Prevents a hung/stuck job from running indefinitely — if the job hasn't completed within the deadline, Kubernetes terminates it, treating it as failed.
CronJobs for Scheduled Recurring Tasks
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-backup
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: myapp:latest
command: ["./backup.sh"]
restartPolicy: OnFailure
Standard cron syntax for scheduling — creates a new Job according to the schedule, similar in concept to traditional cron but managed natively within Kubernetes.
Handling Overlapping CronJob Runs
spec:
concurrencyPolicy: Forbid
Forbid prevents a new job run from starting if the previous scheduled run hasn't completed yet — important for tasks that shouldn't genuinely run concurrently (like a backup job that could conflict with itself if overlapping).
Setting Job History Limits
spec:
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
Controls how many completed job records Kubernetes retains — without limits, job history can accumulate indefinitely, cluttering your cluster's resource listings.
Monitoring Job/CronJob Status
kubectl get jobs
kubectl get cronjobs
kubectl describe job data-migration
Getting Alerted on Job Failures
See How to Monitor a Kubernetes Cluster with Prometheus and Grafana — export job success/failure metrics and alert on unexpected failures, similar in principle to How to Set Up Automated Backup Verification and Alerting applied to Kubernetes-native scheduled tasks.
Common Errors
CronJob never seems to run at the scheduled time — verify the cluster's timezone assumptions match your expectations (Kubernetes CronJob schedules are typically evaluated in UTC by default unless explicitly configured otherwise), and check for any suspended state on the CronJob resource.
Continue Reading
- Kubernetes Pods, Deployments & Services Explained
- How to Monitor a Kubernetes Cluster with Prometheus and Grafana
- How to Deploy a Database in Kubernetes with StatefulSets
Browse more articles in Kubernetes & Container Orchestration.