Kubernetes CronJob Controller
The Kubernetes CronJob Controller schedules and manages periodic tasks in Kubernetes clusters, ensuring reliable execution of scheduled workloads.
Kubernetes CronJob Controller is the control loop that creates Job objects on a recurring schedule expressed in standard cron syntax, delegating all actual Pod management and completion tracking to the Jobs it creates rather than performing any of that work itself. It sits one layer above the Job controller in the same way a Deployment sits above a ReplicaSet, adding time-based triggering without duplicating the completion logic that already exists at the Job level.
Schedule Expression
Standard Cron Syntax
spec.schedule accepts the familiar five-field cron format, minute, hour, day of month, month, day of week, evaluated against the cluster's configured time zone (or UTC by default in the absence of an explicit spec.timeZone).
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob-controller-example
spec:
schedule: "0 2 * * *"
timeZone: "America/New_York"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: worker
image: registry.example.com/nightly-worker:1.0.0
Job Creation at Scheduled Times
One Job Per Scheduled Occurrence
At each point the schedule fires, the controller creates a new Job object from spec.jobTemplate, with a name derived from the CronJob's name and the scheduled time, and that Job then proceeds through its own independent completion lifecycle exactly as any standalone Job would.
kubectl get jobs -l cronjob=cronjob-controller-example
Concurrency Policy
Handling Overlapping Runs
spec.concurrencyPolicy determines what happens if a scheduled time arrives while a previous Job created by the same CronJob is still running: Allow (the default) lets both run simultaneously, Forbid skips the new occurrence entirely if a prior one is still active, and Replace cancels the still-running Job and starts the new one in its place.
spec:
concurrencyPolicy: Forbid
Missed Schedule Handling
startingDeadlineSeconds
If the CronJob controller itself is unavailable (during an upgrade or outage) and misses one or more scheduled firing times, spec.startingDeadlineSeconds bounds how far in the past a missed schedule can still be honored once the controller resumes; missed occurrences older than this deadline are simply skipped rather than run late.
spec:
startingDeadlineSeconds: 200
Too Many Missed Schedules
If the controller detects more missed schedules than a fixed internal threshold since it last checked, it logs the situation and skips straight to the most recent schedule, avoiding a burst of many backlogged Job creations all firing in rapid succession.
History Retention
successfulJobsHistoryLimit and failedJobsHistoryLimit
These fields bound how many completed Job objects, successful and failed respectively, the controller retains after they finish, deleting the oldest beyond that count to prevent unbounded accumulation of historical Job objects in the namespace.
spec:
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
Suspending Without Deleting
The suspend Field
Setting spec.suspend: true halts the creation of any new scheduled Jobs without deleting the CronJob object or its configuration, and any Jobs already running continue to completion unaffected, providing a reversible way to pause recurring work.
kubectl patch cronjob cronjob-controller-example -p '{"spec":{"suspend":true}}'
CronJob Controller Diagram
Because each firing produces a fully independent Job object with its own completion tracking, failure handling, and Pod lifecycle, the CronJob controller's own responsibility remains narrowly scoped to timing and history bookkeeping, leaving the substantially more complex work of running Pods to completion entirely to the Job controller it delegates to.