All answers so far are unaware of namespaces, and are dependent on custom labeling in the Job.
The latter can be fixed as kube-state-metrics version 1.6.0 introduced a new metric kube_job_owner which solves the problem matching Jobs and CronJobs.
NOTE: In kube-state-metrics 1.4.0 the job label was renamed to job_name to avoid a label collision with Prometheus.
clamp_max(
max by (namespace, owner_name, job_name) (
max by (namespace, owner_name, job_name) (
kube_job_status_start_time
*
on (job_name) group_left(owner_name) max by (namespace, owner_name, job_name) (kube_job_owner{owner_kind="CronJob"})
)
==
on (namespace, owner_name) group_left max by (namespace, owner_name) (
kube_job_status_start_time
*
on (job_name) group_left(owner_name) max by (namespace, owner_name, job_name) (kube_job_owner{owner_kind="CronJob"})
)
),
1
)
*
on (namespace, job_name) group_left kube_job_status_failed
The output can be further improved by renaming the owner_name
label to cronjob by surrounding the expression with
max without (owner_name) (
label_replace(
<expression from above>
,
"cronjob", "$1", "owner_name", "(.+)"
)
)
(the label_replace() function adds a new cronjob label, while max() drops the owner_name label)