# Job

> Jobs reserve node capacity from start until completion or failure, retrying up to 6 times under the default backoffLimit. ZopNight derives status from the counters (succeeded at or above completions is completed, failures with nothing active is failed), records parallelism and any owning CronJob, and flags failed Jobs once they are over 1 hour old.

Source: https://zop.dev/integrations/kubernetes/job
Updated: 2026-08-19

---

A Job runs pods until a task completes, then stops. Its cost model is the healthiest in Kubernetes, with capacity reserved only from start to finish. That holds right up until a Job cannot finish, at which point retries hold pods and node capacity with nothing to show for it.

## A meter that should stop by itself

Unlike a Deployment, a Job's compute reservation is supposed to be temporary: `parallelism` pods (default 1) run until `completions` successes (default 1) are recorded. Discovery captures both knobs plus the live counters (`succeeded`, `failed`, `active`) and the containers' requests and limits, so a Job's worst-case footprint is computable from its spec.

## Status from three counters

Status is derived from arithmetic on the counters: nothing active with successes at or above the completion target is `completed`; nothing active with failures on the board is `failed`; anything else is `running`. Completed Jobs are effectively free, because the pods are gone. Failed ones are the signal worth acting on.

## The 1-hour grace for retries

The Failed Job rule (RC-1735 / RC-1835 / RC-1935, medium severity) does not fire on the first failure it sees. A Job retries under its `backoffLimit`, 6 attempts by default, and a failure observed mid-retry may yet succeed, so the rule waits until a failed state has persisted on a Job at least 1 hour old, and abstains entirely when the creation timestamp is unavailable. What it catches is the durable kind of failure: broken images, missing credentials, and misconfigured pipelines that will never complete no matter how many pods they burn.

## Hand-run versus CronJob-owned

When a CronJob spawned the Job, discovery records the owner's name in an `ownerCronJob` field. That distinction matters during cleanup: failed children of a CronJob point at a schedule that needs fixing at the source, while orphan hand-run Jobs are one-off experiments that accumulate quietly; clusters that never set `ttlSecondsAfterFinished` keep every one of them forever.

```bash
kubectl get jobs -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,SUCCEEDED:.status.succeeded,FAILED:.status.failed,ACTIVE:.status.active,OWNER:.metadata.ownerReferences[0].name
```
