What is a CronJob in Kubernetes?
Kubernetes emphasizes web apps and databases, but handling short-lived jobs is essential. CronJob is the main time-based, automated work manager. One line in a Unix crontab file schedules CronJobs.
You can also read Setting up a Kubernetes cluster locally with minikube
The Core Purpose of CronJobs
CronJobs schedule database housekeeping, log rotation, data synchronization between systems, report production, and nightly backups. Instead of a single Job’s instantaneous execution, a CronJob schedules many Jobs to activate at predefined intervals.
This example CronJob manifest prints the current time and a hello message every minute:
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "* * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox:1.28
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
Writing a CronJob spec
To work properly within the cluster, a CronJob manifest needs a few essential fields. The CronJob type and the batch/v1 API version are used. The work template and the timetable are the most important components of the specification.
The .spec.schedule field is required. The value of that field follows the Cron syntax:
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12)
# │ │ │ │ ┌───────────── day of the week (0 - 6) (Sunday to Saturday)
# │ │ │ │ │ OR sun, mon, tue, wed, thu, fri, sat
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
For example, a schedule of 0 3 * * 1 translates to running the task weekly every Monday at 3 AM. Kubernetes also supports step values using the / operator; for instance, */2 in the hours field means “every two hours”. Additionally, several macros are supported for convenience:
@hourly:0 * * * *@daily:0 0 * * *@weekly:0 0 * * 0@monthly:0 0 1 * *@yearly:0 0 1 1 *
Time Zones
Since Kubernetes v1.27, you can explicitly set a time zone for a CronJob using the .spec.timeZone field (e.g., "Etc/UTC" or "America/New_York"). If no time zone is specified, the kube-controller-manager interprets the schedule relative to its own local time zone.
The Job Template
The .spec.jobTemplate is a required field that defines the Job object to be created at each scheduled interval. It has the exact same schema as a standard Job, meaning it must include a Pod template with a restartPolicy of either OnFailure or Never.
You can also read What is Kubernetes Cloud Controller Manager?
Advanced Operational Parameters
CronJobs provide advanced controls that go beyond simple scheduling to regulate the handling of overlapping or delayed jobs.
Concurrency Policies
The optional .spec.concurrencyPolicy property controls what occurs if a new job is scheduled while an existing one is already in progress. Three potential values exist:
Allow(default): The CronJob allows concurrently running Jobs.Forbid: The CronJob does not allow concurrent runs; if it is time for a new Job run and the previous Job run hasn’t finished yet, the CronJob skips the new Job run. Also note that when the previous Job run finishes,.spec.startingDeadlineSecondsis still taken into account and may result in a new Job run.Replace: If it is time for a new Job run and the previous Job run hasn’t finished yet, the CronJob replaces the currently running Job run with a new Job run
Starting Deadline
The .spec.startingDeadlineSeconds parameter establishes a window of time within which a job can begin in the event that its scheduled time is missed because of controller or cluster outages. This particular execution is skipped if the controller is unable to generate the job before this deadline.
History Limits and Suspension
CronJobs have historical restrictions to keep outdated Job and Pod resources from clogging the cluster.
The .spec.successfulJobsHistoryLimit and .spec.failedJobsHistoryLimit fields specify how many completed and failed Jobs should be kept. Both fields are optional.
.spec.successfulJobsHistoryLimit: This field specifies the number of successful finished jobs to keep. The default value is3. Setting this field to0will not keep any successful jobs..spec.failedJobsHistoryLimit: This field specifies the number of failed finished jobs to keep. The default value is1. Setting this field to0will not keep any failed jobs.
You can also suspend a CronJob by setting .spec.suspend: true. This halts all future scheduled executions until the field is set back to false.
You can also read What is a Kubernetes ReplicaSet & Working with ReplicaSets
Operational Logic and Limitations
The fact that CronJob scheduling is approximative must be understood. Sometimes the controller creates two or no jobs for a schedule. These Jobs’ tasks must be idempotent, meaning they can be repeated without causing unexpected results.
The “100 Missed Schedules” Rule
The controller will cease the creation of new jobs and record an error if a CronJob fails to execute more than 100 expected executions, such as if the controller was unavailable for an extended period without a startingDeadlineSeconds. Upon controller recovery, the cluster receives fewer “catch-up” Jobs.
Step-by-Step Execution Guide
- Creation: Save your manifest and apply it using
kubectl apply -f <filename>.yaml. - Verification: Check the status of your CronJob with
kubectl get cronjobs. This will show you the schedule and theLAST SCHEDULEtime. - Monitoring: Use
kubectl get jobsto see the individual Jobs spawned by the CronJob. - Debugging: Identify the Pod associated with a specific Job run and view its logs using
kubectl logs <pod-name>. - Deletion: Removing a CronJob with
kubectl delete cronjob <name>will also perform a cascading deletion of all Jobs and Pods it created.
Security Best Practices
The NSA and CISA recommend that CronJobs be handled as sensitive resources. Because CronJobs automate execution, an attacker with the ability to create them may set up malicious scripts to execute frequently. To make sure that only permitted tasks are being automated, administrators should use cluster audit logging to track the creation and update of CronJobs. For unmanaged Jobs, it is also advised to use the TTL method (.spec.ttlSecondsAfterFinished) to prevent them from lingering and putting burden on the API server.
You can also read What is Kube-Proxy in Kubernetes and it’s Lifecycle
