Container Lifecycle
Managing container images is often an overlooked part of application development and operations. However, understanding the container image lifecycle in OpenShift can lead to significant benefits. Efficient image management can:
-
Speed up cold starts on new or rebooted nodes by reducing image pull times.
-
Prevent storage exhaustion by pruning unused or outdated images.
-
Simplify operations in secure or disconnected environments where external registries may be unavailable.
This page explores how images are brought into OpenShift, how they are managed on the cluster, and how the platform automatically prunes old images to maintain performance and stability.
To supplement the standard image lifecycle, we will introduce four supporting technologies: kubernetes-image-puller
, mirror registry
, image-pruner
, and the included internal image registry
.
Importing Images
The simplest way to use an image in OpenShift is to reference it directly in a workload manifest. This can be done with any workload type, such as a Deployment
, DaemonSet
, or StatefulSet
.
In this case, the image is typically hosted on an external registry like Quay or Docker Hub, or on a registry hosted on-premise within the organization. There is no need to import the image beforehand — OpenShift will attempt to pull it when the pod is scheduled.
But what specifically happens after the manifest is applied?
-
OpenShift schedules the pod onto a node.
-
The container runtime checks if the image is already present on the node.
-
If not present, the runtime attempts to pull the image from the specified registry.
-
If the registry requires authentication, the runtime uses credentials stored in the cluster (typically via a
Secret
linked to aServiceAccount
). -
Once pulled, the image may be cached locally on the node for future use.
Image pulling behavior is controlled by the
Choosing the right policy can help balance reliability, performance, and security depending on your use case. |
It’s important to note that image caching is node-specific. If a pod is rescheduled to a different node — for example, due to a node reboot or scale event — the image must be pulled again on that new node. This can introduce additional latency if the image is large or the registry is slow or unreachable.
To reduce this impact, the kubernetes-image-puller
project can be used to proactively pre-fetch commonly used or frequently updated images across all nodes in a cluster.
ImagePuller
---
apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
labels:
operators.coreos.com/kubernetes-imagepuller-operator.openshift-operators: ""
name: kubernetes-imagepuller-operator
namespace: openshift-operators
spec:
channel: stable
installPlanApproval: Automatic
name: kubernetes-imagepuller-operator
source: community-operators
sourceNamespace: openshift-marketplace
startingCSV: kubernetes-imagepuller-operator.v1.1.0
---
kind: KubernetesImagePuller
apiVersion: che.eclipse.org/v1alpha1
metadata:
name: image-puller
namespace: openshift-operators
spec:
daemonsetName: k8s-image-puller
images: 'ubi9=registry.redhat.io/ubi9:latest'
The example image-puller resource uses the "latest" tag. Avoid using the latest tag wherever possible, because it does not necessarily provide a consistent image. |
Disconnected Installs
In some environments — like high-security data centers or government systems — clusters aren’t allowed to reach out to the internet. That means they can’t pull images directly from external registries.
So how do you run workloads in a setup like that?
The answer is to mirror the images you need into a local registry that the cluster can access. This process usually happens ahead of time, in a connected environment. Once the images are downloaded, they’re pushed into a registry that lives inside your network.
Here’s the general approach:
-
Pull the images you need while connected.
-
Push them into a registry that’s reachable by the disconnected cluster.
-
Update the cluster configuration so that it uses the internal registry instead of reaching out to the public internet.
OpenShift provides tools like oc mirror
and oc adm release mirror
to help automate this process, especially for cluster upgrade images and curated image sets.
In disconnected clusters, that local registry becomes critical. If it’s misconfigured or goes down, pods won’t start, and cluster upgrades can break. Make sure it’s reliable and backed up. |
And if you want to go one step further, cluster administrators can use a combination of ImageContentSourcePolicy
(ICSP), ImageDigestMirrorSet
, and ImageTagMirrorSet
objects. These let you rewrite image references at the cluster level — so even core OpenShift components pull from your mirrored registries instead of the internet.
Images on the Cluster
Once an image is pulled, OpenShift doesn’t just forget about it. The platform tracks images using its internal registry, metadata, and built-in Kubernetes resources. This gives OpenShift powerful visibility and automation around how images are stored, updated, and referenced across the cluster.
In this section, we’ll explore how OpenShift manages images that have already been brought into the cluster, including how it stores them, associates them with workloads, and keeps them up to date.
ImageStreams
In Kubernetes, you typically reference container images by their full registry URL and tag. But in OpenShift, you have the option to use something more flexible: an ImageStream
. You have already created one in the "Application Deployment" module!
An ImageStream is a resource that acts like a pointer to one or more related images. It lets you manage versions, automate updates, and even trigger builds or deployments when a new image is available.
You can think of an ImageStream as a named alias for a group of images — similar to how a Git branch points to different commits over time.
In OpenShift you can use standard image references or ImageStreams. So why use ImageStreams?
-
They decouple your application from the raw image URL.
-
They enable automatic redeployments or builds when a new image is pushed.
-
They give you visibility into image history, metadata, and source.
A basic ImageStream might look like this:
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
name: retail-cart
namespace: default
spec:
lookupPolicy:
local: false
status:
dockerImageRepository: image-registry.openshift-image-registry.svc:5000/default/retail-cart
publicDockerImageRepository: default-route-openshift-image-registry.apps.ms01.k8socp.com/default/retail-cart
tags:
- items:
- created: "2025-04-09T15:43:06Z"
dockerImageReference: image-registry.openshift-image-registry.svc:5000/default/retail-cart@sha256:f14cc636d6f62738da50597f32829920b32495a1f714bea431281bba6f4b37bf
generation: 1
image: sha256:f14cc636d6f62738da50597f32829920b32495a1f714bea431281bba6f4b37bf
tag: latest
In this example, the ImageStream is called retail-cart
, and its latest
tag points to an external image. Once this is set up, you can reference it in workloads like this image: image-registry.openshift-image-registry.svc:5000/my-project/my-app@sha256:….
where the sha256
comes from the ImageStream’s tag status.
Behind the scenes, OpenShift handles tracking and pulling the actual image so that your workload always uses the correct version.
ImageStream Facts
|
Image Pruning
Over time, clusters accumulate a lot of images — from builds, deployments, and testing. Without cleanup, this can take up valuable storage in the internal registry and slow down operations.
OpenShift includes a built-in pruning mechanism to help manage this. Pruning removes old, unused, or orphaned images from the internal registry, keeping your storage lean and healthy.
You don’t need to manually delete images one by one. The platform provides a way to safely automate cleanup while keeping important images intact.
How Pruning Works
Pruning works by checking for images that:
-
Are no longer referenced by any ImageStream or workload.
-
Are older than a configured threshold.
-
Have more revisions than the retention policy allows.
When you run a prune operation, OpenShift analyzes the registry and removes image data that’s no longer needed.
Here’s an example command:
oc adm prune images --keep-tag-revisions=3 --keep-younger-than=60m
This tells OpenShift to:
-
Keep the most recent 3 revisions of each tag.
-
Preserve any images that were pushed in the last 60 minutes.
-
Delete anything older that isn’t referenced.
Pruning only affects images stored in the internal registry. If you’d like to know how images are cleared from nodes directly, look at garbage collection. |
You can also run pruning in dry-run mode to preview what would be deleted:
oc adm prune images --keep-tag-revisions=3 --keep-younger-than=60m --confirm=false
This is especially useful in production clusters where caution is critical.
OpenShift includes an ImagePruner
resource that allows you to schedule pruning as part of cluster operations.
This resource lets cluster administrators define pruning policies and run schedules directly within the cluster — no need for external cron jobs or scripts.
It’s a good idea to monitor registry usage and prune regularly — especially in environments where image builds and CI/CD activity happen often.
Knowledge Check
-
What happens when a workload references an external image that isn’t cached on the node?
-
How are images tracked in OpenShift once they’re imported?
-
What is an ImageStream, and why might you use one instead of a direct image reference?
-
In a disconnected environment, what steps are required to run workloads that depend on public images?
-
What does the
oc adm prune images
command do? -
How does OpenShift decide which images to prune from the internal registry?
-
What role does the
ImagePruner
resource play in managing image lifecycle automation? -
What are the uses and differences between
ImageContentSourcePolicy
,ImageDigestMirrorSet
, andImageTagMirrorSet
?