Safeguard
Security Guides•

Does your cluster image list miss CronJobs and batch images?

A list of running pods misses CronJob images between runs. Here is how to find scheduled and batch images so your container scanning coverage is complete.

Safeguard Security Team
6 min read

Yes, it can. A list built from running pods shows only what is running at that moment. A Kubernetes CronJob creates pods only when its schedule fires, so its image may be absent from the list for hours or days. To cover those images, read the CronJob and Job definitions, not just pods.

What the documentation says

The Kubernetes documentation describes a CronJob as meant for regular scheduled actions such as backups and report generation, like one line of a crontab file, running a Job periodically on a given schedule. The control plane creates the Jobs, and indirectly the pods, when the schedule fires. The container image is declared inside the job template in the CronJob's spec.

The documentation also describes history limits: the successful and failed jobs history limit fields say how many completed and failed Jobs to keep. That matters for a different reason. A pod listing may show finished pods of recent runs for a while, but only as many as the limits keep, and only until they are cleaned up. So a pod listing is a poor basis for coverage even for recent runs.

The Kubernetes task page on listing running container images shows the standard approach for pods: query pods in all namespaces and format the output to the image fields of containers and init containers. It is a good start, but it reports what exists in pods now.

Where images hide in a cluster

Workload typePresent in a pod list?Where the image is defined
Deployment, StatefulSet, DaemonSetYes, while runningPod template
CronJobOnly while a job runsJob template inside the CronJob
JobUntil cleaned upPod template inside the Job
Init containersWhile the pod runsInit container list in the pod spec
SidecarsWhile the pod runsContainer list in the pod spec
Controllers and operators that launch podsWhile they runOften built by the operator, not by a manifest
Paused or scaled to zero workloadsNoThe workload spec

The last two rows are easy to forget. An operator can create pods from images named in its own custom resources, and a deployment scaled to zero still has an image that will run when it scales up.

Step by step: find every image

  1. List images from running pods across all namespaces, including init containers.
  2. List CronJobs across all namespaces and extract the images from each job template.
  3. List Jobs and extract their images.
  4. List the controller workloads, Deployments, StatefulSets and DaemonSets, and extract their template images. This catches those scaled to zero.
  5. Review operators and custom resources that define images in their own fields. Search for image references in custom resource definitions your cluster uses.
  6. Search deployment repositories and Helm charts for image references, since not everything deployed is present now.
  7. Merge all lists, key by digest where you can, and mark where each was seen.

For step 1 and 2 you can use the same jsonpath approach as the documentation, adjusting the path for each resource type.

A worked example

A team lists images from running pods and finds 40. They then add the other sources.

SourceAdditional distinct images
CronJob templates5
Job templates2
Workloads scaled to zero3
Operator custom resources4
Helm charts not currently deployed6

The total grows to 60. Of the 20 new images, several run with high privilege, including a backup job that has access to the database. None of them had been scanned. This is the pattern the exercise usually finds: the forgotten images are often the ones with broad access, because they were set up once and left alone.

These counts are an illustration, not a statistic.

Keep it current

A one-time listing goes stale. Choose a way to refresh.

  • Run the listing on a schedule and compare it with the previous result.
  • Add a CI check that fails when a new image appears that is not in the scanned set.
  • Use an admission policy that requires images to come from approved registries, which at least bounds the list.
  • Review the list quarterly with service owners.

Questions to ask a scanner vendor

  • Does your cluster integration read CronJobs and Jobs, or only pods?
  • How do you treat workloads scaled to zero?
  • Can you discover images that operators create?
  • How quickly do you notice a new image?

Common mistakes

  • Building coverage reports from pod lists alone.
  • Assuming scheduled jobs use the same images as the main service.
  • Leaving old CronJobs in the cluster after the work they did has ended.
  • Ignoring init containers and sidecars.

Try it yourself

Click through it at your own pace, or open it full screen.

See how an inventory groups items and shows what each contains. Imagine the same view for images, with a column for where each was found.

Where Safeguard fits

Safeguard offers asset discovery and SBOM and dependency scanning, which can help you keep an inventory current. You can try a free scan at gold.safeguard.sh/scan.

Quick check

Is a pod list good enough for scan coverage?

No. It misses scheduled jobs between runs, workloads scaled to zero and images that are defined but not running. Add the workload definitions.

Where is a CronJob's image defined?

Inside the job template in the CronJob spec. The Kubernetes documentation shows the container and its image under that template.

Do init containers need scanning?

Yes. They run in the pod with its permissions, and the standard listing method includes them.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.