Kubernetes CronJobs use standard cron syntax, but production behavior also depends on CronJob controller settings.
The .spec.schedule field uses standard five-field cron syntax: minute, hour, day of month, month, and day of week. For example, schedule: "0 0 * * *" runs every day at midnight according to the CronJob timezone configuration.
apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-report
spec:
schedule: "0 0 * * *"
timeZone: "Etc/UTC"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: report
image: example/report:latestconcurrencyPolicy controls what happens when a previous Job is still running. Allow is the default and permits overlap. Forbid skips the new run. Replace stops the currently running Job and starts a new one.
Pod restart behavior comes from the Job template, commonly restartPolicy: OnFailure or Never. Missed runs are affected by controller downtime, startingDeadlineSeconds, and the CronJob controller’s catch-up limits, so jobs should be idempotent.
Kubernetes supports .spec.timeZone in modern clusters. Without it, schedules are interpreted relative to the kube-controller-manager timezone. CRON_TZ and TZ inside the schedule string are not the supported Kubernetes approach.