Skip to content

Monitor Kubernetes CronJobs without Prometheus

Kubernetes stores Job and pod status, but a CronJob that never creates a Job produces no application failure to alert on. A dead-man check catches the absence of the expected run, plus explicit failures and stuck executions.

Put backupctl in the workload image and wrap the CronJob’s command:

apiVersion: batch/v1
kind: CronJob
metadata:
name: nightly-export
spec:
schedule: "0 2 * * *"
timeZone: "UTC"
concurrencyPolicy: Forbid
startingDeadlineSeconds: 900
jobTemplate:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: export
image: registry.example.com/nightly-export:latest
env:
- name: BACKPULSE_URL
value: https://backpulse.aniicrite.dev
- name: BACKPULSE_PING_KEY
valueFrom:
secretKeyRef:
name: backpulse-nightly-export
key: ping-key
command:
- backupctl
- run
- "--"
- /app/export

Store the ping key as a Secret, never inline in the manifest:

Terminal window
kubectl create secret generic backpulse-nightly-export \
--from-literal=ping-key='<check-key>'

Match the backpulse cron expression and timezone to the Kubernetes schedule. Set grace to cover normal controller and image-pull jitter. Pick the failure threshold on purpose:

  • 1: page on the first missed or failed production run.
  • 2 or higher: forgive one transient failure for frequent, retryable jobs.

The wrapper sends /start, then /success or /fail with duration and exit status. backpulse distinguishes a schedule that produced no Job, a Job that failed, a Job that never finished, a late run, and overlapping starts.

This is scheduled-work monitoring, not cluster observability. Keep your metrics and logs for node pressure, sizing, and debugging. The dead-man check answers one narrower question: did this specific recurring job run successfully when it was supposed to?