DevOps Peach

Docker & Kubernetes · Kubernetes Workloads · Lesson 5 of 5

Jobs, CronJobs and Operators

A Job runs pods to completion; a CronJob creates Jobs on a cron schedule (UTC by default); an Operator is a custom controller for complex apps.

Practice interactively →

Job

A Job makes sure pods run and finish successfully: it retries until completions is reached, runs at most parallelism pods at once, and fails after backoffLimit errors. restartPolicy may only be Never or OnFailure (not Always). Finished pods stay so you can read their logs until you delete the Job (or set ttlSecondsAfterFinished).

CronJob

apiVersion: batch/v1           # batch/v1beta1 was removed in 1.25
kind: CronJob
metadata: { name: backup }
spec:
  schedule: "0 2 * * *"
  timeZone: "Asia/Ho_Chi_Minh" # without it, the kube-controller-manager time zone is used (usually UTC)
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      completions: 4
      parallelism: 2
      backoffLimit: 3
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - { name: backup, image: busybox:1.36, command: ["date"] }
flowchart LR
  CJ["CronJob backup<br/>0 2 * * *"] -- "every day" --> J["Job backup-29001234"]
  J --> P1["pod (run 1)"]
  J --> P2["pod (run 2)"]

Operators

When no workload fits (for example running a database cluster: backups, failover), you define a CRD (Custom Resource Definition) and write your own controller that watches it — an Operator, usually written in Go, needing a ServiceAccount and RBAC to manage workloads.

Command Meaning
kubectl create cronjob backup --image=busybox:1.36 --schedule="0 2 * * *" -- date Create a CronJob
kubectl create job manual-backup --from=cronjob/backup Run a Job from the CronJob right now
kubectl get jobs,cronjobs List Jobs and CronJobs

More Job controls

Field Effect
activeDeadlineSeconds Fail the Job if it runs longer than this
ttlSecondsAfterFinished Delete the finished Job and its pods automatically
completionMode: Indexed Give each pod an index (JOB_COMPLETION_INDEX) to split work into parts
podFailurePolicy Fail fast on some exit codes, ignore others such as node disruptions
suspend: true Create the Job without starting it yet

Indexed Jobs suit "process shard 0 to 9" style batch work without an external queue.

CronJob behaviour to know

Debugging batch work

kubectl get jobs shows completions such as 3/4; kubectl describe job lists pod failures and the backoff reason. kubectl logs job/manual-backup reads the logs of one of its pods. Failed pods are kept up to backoffLimit, which helps debugging but can clutter a namespace without a TTL.

Operators in practice

You rarely write an operator yourself at first; you install one. Popular examples: cert-manager (TLS certificates as Certificate resources), CloudNativePG or the Zalando operator for PostgreSQL clusters, Prometheus Operator (ServiceMonitor, PrometheusRule), and Strimzi for Kafka. Each adds CRDs and a controller that encodes the operations knowledge of experts: provisioning, backups, failover, and upgrades. OperatorHub.io lists many of them, and frameworks such as Kubebuilder and Operator SDK help when you do write one.

Practice interactively →