iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Jobs & CronJobs

A Job runs Pods until N succeed. CronJob runs a Job on a schedule. Together they cover database migrations, backups, batch processing, periodic cleanup — anything that isn’t long-lived service traffic.

Job + CronJob + parallelism patterns

EXAMPLE
# 1) One-shot Job — run a DB migration
apiVersion: batch/v1
kind: Job
metadata: { name: migrate-2026-06 }
spec:
    backoffLimit:           4                # retry the Pod up to 4 times on failure
    activeDeadlineSeconds:  900              # 15-minute hard cap
    ttlSecondsAfterFinished: 86400           # clean up 1 day after completion
    template:
        spec:
            restartPolicy: Never
            containers:
                - name: migrate
                  image: myapp:1.4.2
                  command: ["./manage.py", "migrate"]
                  envFrom:
                      - secretRef: { name: db-credentials }

# 2) Parallel Job — process a queue of work in parallel
apiVersion: batch/v1
kind: Job
metadata: { name: thumbnail-batch }
spec:
    completions: 1000          # 1000 successful pods = done
    parallelism: 20            # 20 pods at a time
    backoffLimit: 50
    template:
        spec:
            restartPolicy: OnFailure
            containers:
                - name: worker
                  image: thumbnailer:1.0
                  args: ["--queue", "redis://queue:6379/0"]

# 3) Indexed Job — each pod knows its index 0..N-1 (great for sharding)
apiVersion: batch/v1
kind: Job
metadata: { name: shard-export }
spec:
    completionMode: Indexed
    completions: 8
    parallelism: 8
    template:
        spec:
            restartPolicy: Never
            containers:
                - name: export
                  image: exporter:2.0
                  env:
                      - name: SHARD
                        valueFrom:
                            fieldRef: { fieldPath: metadata.annotations['batch.kubernetes.io/job-completion-index'] }

# 4) CronJob — nightly backup
apiVersion: batch/v1
kind: CronJob
metadata: { name: backup-nightly }
spec:
    schedule: "0 2 * * *"               # 02:00 UTC daily
    timeZone: Australia/Sydney          # since K8s 1.27
    concurrencyPolicy: Forbid           # don't pile up if a run is slow
    startingDeadlineSeconds: 600
    successfulJobsHistoryLimit: 3
    failedJobsHistoryLimit:     1
    jobTemplate:
        spec:
            backoffLimit: 2
            template:
                spec:
                    restartPolicy: OnFailure
                    containers:
                        - name: dump
                          image: backup:1.0
                          envFrom:
                              - secretRef: { name: backup-creds }

# 5) Useful kubectl
kubectl get jobs
kubectl logs job/migrate-2026-06
kubectl describe job/migrate-2026-06
kubectl delete job/migrate-2026-06       # cancel a running job

Why it matters

Use backoffLimit + activeDeadlineSeconds on every Job — an infinite retry loop on a broken image will burn through your namespace quota and trigger pager. ttlSecondsAfterFinished stops zombie Job objects from accumulating.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
# Run-to-completion: Job.
# Scheduled: CronJob (schedule: "*/5 * * * *").
Try it Yourself »

Discussion

Loading…