Effectively monitor your scheduled jobs in Kubernetes
Kubernetes CronJobs allow running pods on a defined schedule, just like classic Unix cron. In modern cloud-native environments, they are used for maintenance tasks, backups, synchronization, and batch processing. Their monitoring is critical because in an active cluster with hundreds of pods, CronJob failures easily go unnoticed.
Kubernetes complexity introduces many potential failure points: container image not found, insufficient resources to schedule the pod, CrashLoopBackOff on the container, exceeded timeout, or simply a CronJob accidentally suspended. These problems are often silent because Kubernetes has no native alerting for CronJobs.
MoniTao perfectly complements the Kubernetes ecosystem by adding an external heartbeat monitoring layer. By integrating a simple curl call into your containers, you are instantly alerted if a CronJob doesn't execute correctly, regardless of the underlying cause.
Understanding K8s CronJob architecture is essential for configuring effective monitoring.
Kubernetes CronJobs present unique challenges compared to traditional crons.
Several approaches allow integrating heartbeat monitoring into your Kubernetes CronJobs.
Here's an example Kubernetes CronJob manifest with integrated heartbeat monitoring:
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-daily
spec:
schedule: "0 2 * * *" # 2:00 AM daily
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: backup
image: my-backup-image:latest
command:
- /bin/sh
- -c
- |
/scripts/backup.sh && \
curl -fsS "https://api.monitao.com/ping/YOUR_TOKEN"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
The && ensures curl is only executed if backup succeeds. With restartPolicy: OnFailure, K8s will automatically retry if the container fails, but MoniTao will alert you of the delay.
Configure your MoniTao alerts to cover different Kubernetes failure scenarios.
Check several things: suspend isn't true, the schedule is valid, the CronJob hasn't reached failedJobsHistoryLimit. Use kubectl describe cronjob to see history.
Create a manual Job from the CronJob: kubectl create job test-run --from=cronjob/my-cronjob. This immediately runs the Job with the same configuration.
The cluster doesn't have enough resources to schedule the pod. Check with kubectl describe pod pod-name to see events. Reduce requests or add nodes.
Since K8s 1.27+, use spec.timeZone: "Europe/Paris". For earlier versions, the schedule uses the kube-controller-manager timezone (often UTC).
Set concurrencyPolicy: Forbid in the spec. This prevents creating a new Job if the previous one is still running. Caution: this can mask performance problems.
List the Job's pods with kubectl get pods -l job-name=my-job, then kubectl logs pod-name. For terminated pods, add --previous if the container restarted.
Kubernetes CronJobs are powerful but their native monitoring remains limited. In an active cluster, silent failures can go unnoticed for days, affecting your backups, synchronizations, and batch processing.
By combining Kubernetes best practices with MoniTao heartbeat monitoring, you gain complete visibility into your scheduled jobs. Start with your critical CronJobs and gradually extend coverage across your entire cluster.
Start free, no credit card required.