Kubernetes cookbook · Intermediate

Run scheduled jobs reliably with CronJobs

Nightly jobs sometimes run twice, overlap, or silently stop running.

Create a free account to save this page, take notes and track your progress. Sign in

Approach

Forbid overlapping runs, set a time zone and a starting deadline, keep history for debugging, bound retries and run time, and make the job idempotent.

Solution

apiVersion: batch/v1
kind: CronJob
metadata: {name: nightly-report}
spec:
  schedule: "0 2 * * *"
  timeZone: Europe/Berlin
  concurrencyPolicy: Forbid
  startingDeadlineSeconds: 600
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 5
  jobTemplate:
    spec:
      backoffLimit: 2
      activeDeadlineSeconds: 3600
      ttlSecondsAfterFinished: 86400
      template:
        spec:
          restartPolicy: Never
          containers:
            - name: report
              image: ghcr.io/acme/report:2.1.0
              args: ["--date", "yesterday"]

Pitfalls

  • Jobs that aren't idempotent: retries and rare double runs corrupt data.
  • No alert when a CronJob stops succeeding (monitor last successful run time).

Variations

  • Use a lock (database advisory lock) if even rare concurrent runs are unacceptable.
  • Workflow engines (Argo Workflows) for multi-step pipelines.

Further reading: CronJob

Reference: https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/

More Kubernetes recipes

Was this page helpful?