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 type | Present in a pod list? | Where the image is defined |
|---|---|---|
| Deployment, StatefulSet, DaemonSet | Yes, while running | Pod template |
| CronJob | Only while a job runs | Job template inside the CronJob |
| Job | Until cleaned up | Pod template inside the Job |
| Init containers | While the pod runs | Init container list in the pod spec |
| Sidecars | While the pod runs | Container list in the pod spec |
| Controllers and operators that launch pods | While they run | Often built by the operator, not by a manifest |
| Paused or scaled to zero workloads | No | The 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
- List images from running pods across all namespaces, including init containers.
- List CronJobs across all namespaces and extract the images from each job template.
- List Jobs and extract their images.
- List the controller workloads, Deployments, StatefulSets and DaemonSets, and extract their template images. This catches those scaled to zero.
- Review operators and custom resources that define images in their own fields. Search for image references in custom resource definitions your cluster uses.
- Search deployment repositories and Helm charts for image references, since not everything deployed is present now.
- 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.
| Source | Additional distinct images |
|---|---|
| CronJob templates | 5 |
| Job templates | 2 |
| Workloads scaled to zero | 3 |
| Operator custom resources | 4 |
| Helm charts not currently deployed | 6 |
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.