✦ For everyone, free.

Practical knowledge for real and everyday life

Home

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

CronJob: schedule Job (2am run) Job (3am run)

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.