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

PodPulse - Kubernetes pod crash watcher

A Kestra blueprint that watches Kubernetes pods, detects crash loops and excessive restarts, and alerts on Slack without spamming.

Categories
Infrastructure

How it works

  1. list_pods (io.kestra.plugin.scripts.shell.Commands) runs kubectl get pods in the target namespace and saves the full pod list as JSON. It authenticates with a client certificate and key passed as Kestra secrets, the same pattern the Kubernetes gallery blueprints use.
  2. find_trouble (io.kestra.plugin.scripts.python.Script) reads the pod list and the remembered state from the KV store, then checks every pod. Crashlooping: any container stuck waiting with reason CrashLoopBackOff. Flapping: any container whose restart count reached the restart_threshold input. Pods that finished successfully are skipped because a completed Job is not a problem. Anything already alerted on is dropped.
  3. maybe_alert (io.kestra.plugin.core.flow.If) runs only when there is something new to report, and send_alert posts the troubled pods to Slack with the reason plus kubectl describe and kubectl logs commands to inspect each one.
  4. save_state (io.kestra.plugin.core.kv.Set) writes back the new list of troubled pod names as one JSON value. Recovered pods drop out on their own, so a future crash alerts again.

What you get

  • A daily pod health check for any namespace, no agent to install inside the cluster.
  • Slack alerts only for new trouble: crash loops and pods restarting too often, each with the exact kubectl commands to dig in.
  • No alert spam: the KV-backed memory remembers who was already reported, and forgets pods that recovered.
  • Quiet runs when everything is healthy.

Who it's for

Anyone running workloads on Kubernetes who wants to know about crash-looping pods without watching kubectl get pods all day. Works on any cluster you can reach with a client certificate: minikube, kind, managed clusters.

Why orchestrate this with Kestra

A shell script on a cron server can list pods, but then you need somewhere to keep the "already alerted" state, somewhere to hold the secrets, and a place to see the run history when an alert looks wrong. Kestra gives you all three: the KV store is the memory, secrets stay out of the YAML, and every run keeps its logs and outputs where you can inspect them.

Prerequisites

  • A Kubernetes cluster reachable from where Kestra runs, with a client certificate and key for authentication.
  • Kestra with the Docker task runner available (used for the kubectl and Python steps).
  • A Slack Incoming Webhook URL.

Secrets

Secret What it is
CLIENT_CRT base64-encoded client certificate for the cluster
CLIENT_KEY base64-encoded client key for the cluster
MASTERURL base64-encoded Kubernetes API server URL, reachable from inside the Kestra container
SLACK_WEBHOOK base64-encoded Slack Incoming Webhook URL

In Kestra OSS, secrets come from environment variables prefixed with SECRET_ and must be base64-encoded.

Quick start

  1. Start Kestra with the four secrets above as SECRET_ environment variables.
  2. Import this flow and run it with the namespace you want to watch.
  3. Make a pod crash (for example a Deployment with an image that exits immediately) and run again: the Slack alert lists the pod, the reason, and the kubectl commands to inspect it.
  4. Run once more without changing anything: no second alert. Fix the pod and run again: quiet, and the state is cleared.

How to extend

  • Watch image pull problems too by also flagging containers waiting with ImagePullBackOff.
  • Lower the schedule to every hour for faster detection by changing the cron trigger.
  • Deploy one copy of the flow per namespace you want to watch, changing only the namespace input.
  • Route alerts to PagerDuty or Opsgenie by swapping the Slack task for another notification task.

Inputs

Input Type Default What it does
namespace STRING default the namespace whose pods to watch
restart_threshold INT 5 a pod with at least this many container restarts counts as troubled
slack_webhook STRING (required) Incoming webhook URL of the Slack channel for the alerts

Links

Pitfalls

  • Pod names change when a Deployment rolls out, so the remembered state is per pod name. A redeployed pod that crash-loops again counts as new trouble and alerts again, which is usually what you want.
  • The restart_threshold counts cumulative restarts since the pod started, not restarts per hour. A long-lived pod that restarted 5 times over a month will flag once, then stay quiet thanks to the dedup.
  • Make sure the MASTERURL is reachable from inside the Kestra container. localhost inside the container is not your host: use host.docker.internal when Kestra runs in Docker on the same machine as the cluster.
See How

New to Kestra?

Use blueprints to kickstart your first workflows.