Commands icon
Docker icon
Script icon
If icon
SlackIncomingWebhook icon
Set icon
Schedule icon

Crony

Check the CronJobs in a namespace on a schedule and ping Slack when one misses its run or fails. Skips suspended jobs and never repeats an alert.

Categories
CoreInfrastructure

Kubernetes CronJobs fail silently. A backup job that never ran or a cleanup job that kept failing can go unnoticed for days because nothing pages when a schedule is missed. This blueprint watches the CronJobs in a namespace every day and pings Slack when one misses its run or fails, and stays quiet when everything is healthy.

How it works

  1. list_cronjobs (io.kestra.plugin.scripts.shell.Commands) runs kubectl get cronjobs in the namespace through a bitnami/kubectl container and saves the JSON.
  2. list_jobs (io.kestra.plugin.scripts.shell.Commands) runs kubectl get jobs the same way, so the flow can see which runs failed.
  3. find_trouble (io.kestra.plugin.scripts.python.Script) reads the single JSON list of CronJobs we already alerted on from the KV store (empty on the first run), then goes through every CronJob and checks two things. Missed: the last schedule time is older than twice the expected interval, or it never ran at all. Failed: any Job owned by the CronJob failed. Suspended CronJobs are skipped because pausing one is a choice, not a problem. Anything already alerted on is dropped.
  4. maybe_alert (io.kestra.plugin.core.flow.If) runs only when there is something new to report, and send_alert posts the troubled CronJobs to Slack with the reason and a kubectl command to inspect each one.
  5. save_state (io.kestra.plugin.core.kv.Set) writes back the new list of troubled names. Recovered names drop out on their own, so a future failure alerts again.

What you get

  • A daily check that every CronJob in the namespace actually ran on schedule.
  • One Slack alert listing the missed and failed CronJobs, with reasons and inspect commands.
  • A quiet run when everything is healthy, and no repeated alerts for the same problem.

Who it's for

  • Teams running scheduled jobs on Kubernetes (backups, cleanups, reports) with no watcher on the schedules themselves.
  • On-call engineers who want to know about a missed backup before the restore is needed.
  • Anyone who has discovered a CronJob was silently suspended or failing for weeks.

Why orchestrate this with Kestra

Kubernetes will retry a failed Job and eventually give up, but it never tells anyone the schedule itself is broken. Kestra keeps the whole check in one visible flow: the schedule, the kubectl reads, the missed and failed detection, the duplicate-alert guard, and the Slack call are all one auditable execution history. The KV-backed memory means the alert logic survives restarts without an external database.

Prerequisites

  • A Kubernetes cluster Kestra can reach with kubectl.
  • A Kestra instance with Docker, because the kubectl and Python steps run in containers.

Secrets

  • CLIENT_CRT: client certificate for the Kubernetes API.
  • CLIENT_KEY: client key for the Kubernetes API.
  • MASTERURL: Kubernetes API server URL.
  • SLACK_WEBHOOK: Slack incoming webhook for the alerts. In Kestra OSS, secrets are supplied as environment variables prefixed SECRET_, base64-encoded, and read back with {{ secret('NAME') }}, for example SECRET_SLACK_WEBHOOK=$(echo -n 'https://hooks.slack.com/services/<placeholder>' | base64).

Quick start

  1. Save the cluster details as CLIENT_CRT, CLIENT_KEY and MASTERURL secrets, and the webhook as SLACK_WEBHOOK (base64-encoded, see above).
  2. Import the flow and hit Execute. Type the namespace when it asks; it defaults to default.
  3. Check the execution: if any CronJob missed its run or failed, the Slack alert lists them.
  4. The daily schedule takes care of the rest.

How to extend

  • Deploy one copy of the flow per namespace you want to watch, changing only the namespace input.
  • Add a label_selector input and pass -l to the kubectl commands to watch a subset.
  • Tune the missed-run sensitivity by changing the 2 * interval factor in the Python step.

Inputs

  • namespace: the namespace whose CronJobs to watch (defaults to default).
  • slack_webhook: Incoming webhook URL of the Slack channel for the alerts.

Links

Pitfalls

  • The missed-run check guesses the expected interval from common cron shapes; exotic schedules fall back to a 30-day interval, so a rarely-run job may alert as missed later than you expect.
  • The flow only sees Jobs Kubernetes still keeps; if successfulJobsHistoryLimit is very low, old successes age out of the check.
See How

New to Kestra?

Use blueprints to kickstart your first workflows.