1. Introduction
OpenShift can deploy applications in two major ways:
- Using a normal container image directly, such as:
registry.access.redhat.com/ubi9/httpd-24:latest
docker.io/library/httpd:2.4
quay.io/some-org/some-image:tag
- Using an OpenShift ImageStream, such as:
httpd:latest
httpd:2.4-ubi9
my-httpd:latest
Code language: CSS (css)
Both approaches ultimately run containers in Pods, but they behave very differently in terms of tracking, automation, promotion, rollback, image lookup, image triggers, disconnected environments, and enterprise governance.
OpenShift ImageStreams are an OpenShift-native abstraction over container images. They do not store the image layers themselves; instead, they store image metadata, tags, digests, and references. Red Hatโs current OpenShift image documentation says ImageStreams provide an abstraction for referencing container images, can manage image versions, and can automate builds and deployments.
Your cluster is:
Server Version: 4.21.14
Kubernetes Version: v1.34.6
Code language: CSS (css)
OpenShift 4.21 officially uses Kubernetes 1.34 with CRI-O runtime.
2. What Is a Normal Image Deployment in OpenShift?
A normal image deployment means the Kubernetes Deployment directly references an external or internal container image pull spec.
Example:
containers:
- name: httpd
image: registry.access.redhat.com/ubi9/httpd-24:latest
In this model, OpenShift behaves much like Kubernetes. The Deployment points directly to the registry image.
Example command:
oc create deployment httpd-direct \
--image=registry.access.redhat.com/ubi9/httpd-24:latest
This is simple and familiar, but OpenShift does not automatically give you the full ImageStream-based lifecycle unless you explicitly add ImageStreams or image triggers.
OpenShiftโs own CLI tutorial says the simplest way to deploy an application is to run a provided container image. In its example, oc new-app deploys an image and creates resources such as a Deployment and Service.
Important nuance: oc new-app is OpenShift-aware. Even when you provide an external image, oc new-app can create an ImageStreamTag to track that image. Red Hatโs tutorial output shows: โAn image stream tag will be created โฆ that will track this image.โ
So if you want a true no-ImageStream test, use oc create deployment, oc apply -f deployment.yaml, or kubectl create deployment, not oc new-app.
3. What Is an ImageStream Deployment?
An ImageStream deployment means the Deployment refers to an OpenShift ImageStreamTag, not directly to the external registry.
Example:
containers:
- name: httpd
image: httpd:latest
Code language: CSS (css)
But for Kubernetes Deployments to resolve httpd:latest as an OpenShift ImageStreamTag, you must enable image lookup using:
oc set image-lookup
Code language: JavaScript (javascript)
Red Hatโs current docs say Kubernetes resources can use ImageStreams when the ImageStream is in the same project and referenced by a single-segment value such as ruby:2.5. They also say oc set image-lookup can enable ImageStream resolution either on a specific resource or on the ImageStream itself.
4. High-Level Comparison
| Feature | Normal Image Deployment | ImageStream Deployment |
|---|---|---|
| Image reference | Full registry path | ImageStreamTag such as httpd:latest |
| Example | registry.access.redhat.com/ubi9/httpd-24:latest | httpd:latest |
| OpenShift abstraction | No | Yes |
| Tracks external image metadata | No, not by itself | Yes |
| Can trigger builds/deployments on tag changes | Not automatically | Yes, with ImageStream triggers |
| Can promote tags like dev โ test โ prod | Manual registry/tag work | Easy with oc tag |
| Can rollback ImageStreamTag | Manual image digest change | Easier using ImageStream tag history |
| Works like vanilla Kubernetes | Yes | OpenShift-specific |
| Best for portability | Better | Less portable outside OpenShift |
| Best for OpenShift CI/CD | Basic | Strong |
| Useful in disconnected environments | Possible but manual | Very useful with mirroring and samples |
| Fine-grained image access through OpenShift objects | Limited | Stronger |
| Stores image layers | Registry stores layers | ImageStream stores metadata, not layers |
OpenShift ImageStreams can point to images in the integrated registry, external registries such as registry.redhat.io or quay.io, or other ImageStreams in the cluster. Red Hat also documents that when a build or deployment references an ImageStreamTag, OpenShift queries the repository through that tag and uses the exact associated image ID.
5. Why ImageStreams Exist
ImageStreams solve practical enterprise problems:
- Developers want to use short names like
httpd:latest. - Platform teams want to control which external images are allowed.
- CI/CD pipelines want image-change triggers.
- Security teams want better visibility into image references.
- Release teams want promotion flows such as
dev,qa,stage, andprod. - Disconnected clusters need a clean way to mirror and manage image references.
Red Hat lists several ImageStream benefits: tagging, rollback, triggering builds and deployments, periodic re-import, fine-grained image access control, team sharing, and keeping applications on a known-good image when the source image changes.
6. Lab Setup
6.1 Confirm versions
oc version
Your current output:
Client Version: 4.18.7
Kustomize Version: v5.4.2
Server Version: 4.21.14
Kubernetes Version: v1.34.6
Code language: CSS (css)
Recommended for this tutorial:
oc version
Expected ideal state:
Client Version: 4.21.x
Server Version: 4.21.x
Kubernetes Version: v1.34.x
Code language: CSS (css)
Red Hat recommends using the oc binary corresponding to the OpenShift server version if you want latest features and full command compatibility.
6.2 Create a project
Do not test workloads in default, openshift, kube-system, or other privileged system projects. Red Hat warns that default projects are reserved for core components, and functionality such as admission plugins, SCCs, quotas, and image reference resolution does not work normally in highly privileged projects.
Create a clean project:
oc new-project httpd-image-demo
Code language: JavaScript (javascript)
Check current project:
oc project
Expected:
Using project "httpd-image-demo"
Code language: JavaScript (javascript)
7. Check Existing HTTPD ImageStreams in OpenShift
Many OpenShift clusters include sample ImageStreams in the openshift namespace through the Cluster Samples Operator.
Check HTTPD sample ImageStream:
oc get is -n openshift | grep -i httpd
Code language: JavaScript (javascript)
Or:
oc get imagestream httpd -n openshift
Code language: JavaScript (javascript)
Check available tags:
oc describe is httpd -n openshift
You may see tags such as:
2.4-ubi8
2.4-ubi9
latest
Code language: CSS (css)
The exact tags depend on your cluster, release, sample operator configuration, architecture, and network access.
The Cluster Samples Operator creates and manages sample ImageStreams and templates, including HTTPD, and its configuration can be Managed, Unmanaged, or Removed.
Check Samples Operator:
oc get configs.samples.operator.openshift.io cluster -o yaml
Code language: CSS (css)
Short status:
oc get configs.samples.operator.openshift.io cluster \
-o jsonpath='{.spec.managementState}{"\n"}'
Code language: PHP (php)
Expected:
Managed
If it says Removed, sample ImageStreams might not exist.
8. Method 1 โ Deploy HTTPD Using a Normal Image, Without ImageStream
This is the Kubernetes-style deployment.
8.1 Create Deployment directly from image
Use a Red Hat UBI HTTPD image:
oc create deployment httpd-direct \
--image=registry.access.redhat.com/ubi9/httpd-24:latest
Check Deployment:
oc get deploy httpd-direct
Code language: JavaScript (javascript)
Check Pod:
oc get pods -l app=httpd-direct
Code language: JavaScript (javascript)
Describe Pod:
oc describe pod -l app=httpd-direct
Check exact image in Deployment:
oc get deploy httpd-direct \
-o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
Code language: PHP (php)
Expected:
registry.access.redhat.com/ubi9/httpd-24:latest
This proves the Deployment is using the external registry image directly.
8.2 Expose HTTPD internally
The UBI HTTPD image usually listens on port 8080.
Create a Service:
oc expose deployment httpd-direct --port=8080
Check Service:
oc get svc httpd-direct
Code language: JavaScript (javascript)
Create a Route:
oc expose svc httpd-direct
Check Route:
oc get route httpd-direct
Code language: JavaScript (javascript)
Get URL:
oc get route httpd-direct \
-o jsonpath='http://{.spec.host}{"\n"}'
Code language: PHP (php)
Test:
curl -I "$(oc get route httpd-direct -o jsonpath='http://{.spec.host}')"
Code language: JavaScript (javascript)
Expected:
HTTP/1.1 200 OK
Code language: HTTP (http)
8.3 Observe normal-image behavior
Check image field:
oc get deploy httpd-direct -o yaml | grep -A3 "image:"
Code language: JavaScript (javascript)
Expected:
image: registry.access.redhat.com/ubi9/httpd-24:latest
Code language: HTTP (http)
Check if any ImageStream was created:
oc get is
Code language: JavaScript (javascript)
Expected:
No resources found in httpd-image-demo namespace.
Code language: PHP (php)
That is the key point: this is a direct image deployment, not an ImageStream-based deployment.
9. Method 2 โ Deploy HTTPD Using oc new-app
This is a useful OpenShift shortcut, but understand the behavior carefully.
Run:
oc new-app registry.access.redhat.com/ubi9/httpd-24:latest \
--name=httpd-newapp
Code language: JavaScript (javascript)
Check resources:
oc get all -l app=httpd-newapp
Code language: JavaScript (javascript)
Check ImageStreams:
oc get is
Code language: JavaScript (javascript)
You may see:
NAME IMAGE REPOSITORY TAGS UPDATED
httpd-newapp ... latest ...
This happens because oc new-app is designed to generate OpenShift application objects and can create an ImageStreamTag to track the supplied image. Red Hatโs CLI tutorial shows this exact behavior: when deploying a container image through oc new-app, an ImageStreamTag is created to track that image.
So:
oc new-app external-image
Code language: JavaScript (javascript)
does not always mean โwithout ImageStream.โ
For a pure direct-image test, prefer:
oc create deployment
or declarative YAML.
10. Method 3 โ Create Your Own HTTPD ImageStream
Now let us create an ImageStream manually and deploy from it.
10.1 Create/import ImageStream from external HTTPD image
oc import-image my-httpd:latest \
--from=registry.access.redhat.com/ubi9/httpd-24:latest \
--confirm
Code language: JavaScript (javascript)
Check ImageStream:
oc get is my-httpd
Code language: JavaScript (javascript)
Check ImageStreamTag:
oc get istag my-httpd:latest
Code language: JavaScript (javascript)
Describe it:
oc describe is my-httpd
Red Hat documents oc import-image <imagestreamtag> --from=<image> --confirm as the command for importing an image into an ImageStream.
10.2 View the external image reference behind the ImageStream
oc get istag my-httpd:latest -o yaml
Code language: JavaScript (javascript)
Useful JSONPath commands:
oc get istag my-httpd:latest \
-o jsonpath='{.image.dockerImageReference}{"\n"}'
Code language: PHP (php)
oc get istag my-httpd:latest \
-o jsonpath='{.image.metadata.name}{"\n"}'
Code language: PHP (php)
oc get istag my-httpd:latest \
-o jsonpath='{.image.dockerImageMetadata.Architecture}{"\n"}'
Code language: PHP (php)
This shows that the ImageStreamTag tracks image metadata and digest information.
11. Deploy HTTPD from ImageStream
There are two ways.
11.1 Option A โ Enable ImageStream lookup on the ImageStream
Enable lookup:
oc set image-lookup my-httpd
Code language: JavaScript (javascript)
Check:
oc set image-lookup imagestream --list
Code language: JavaScript (javascript)
Expected:
NAME LOCAL
my-httpd true
Code language: JavaScript (javascript)
Red Hat says enabling image lookup on the ImageStream sets ImageStream.spec.lookupPolicy.local to true, and then the behavior applies to all tags in that ImageStream.
Now create a Deployment using the short ImageStreamTag reference:
oc create deployment httpd-is \
--image=my-httpd:latest
Check what image the Deployment has:
oc get deploy httpd-is \
-o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
Code language: PHP (php)
You might see either:
my-httpd:latest
Code language: CSS (css)
or a resolved pull spec, depending on when admission resolution happened and how the object was admitted.
Check Pod:
oc get pods -l app=httpd-is
Code language: JavaScript (javascript)
Describe Pod:
oc describe pod -l app=httpd-is | grep -i "Image:"
Code language: JavaScript (javascript)
Expose:
oc expose deployment httpd-is --port=8080
oc expose svc httpd-is
Test:
curl -I "$(oc get route httpd-is -o jsonpath='http://{.spec.host}')"
Code language: JavaScript (javascript)
11.2 Option B โ Enable ImageStream lookup only on the Deployment
Create Deployment:
oc create deployment httpd-is-specific \
--image=my-httpd:latest
Enable image lookup only for this Deployment:
oc set image-lookup deploy/httpd-is-specific
Code language: JavaScript (javascript)
Red Hat says you can enable image stream resolution on a specific resource; for a Deployment this sets the alpha.image.policy.openshift.io/resolve-names annotation.
Check annotation:
oc get deploy httpd-is-specific -o yaml | grep -A5 "annotations:"
Code language: JavaScript (javascript)
Expose:
oc expose deployment httpd-is-specific --port=8080
oc expose svc httpd-is-specific
Test:
curl -I "$(oc get route httpd-is-specific -o jsonpath='http://{.spec.host}')"
Code language: JavaScript (javascript)
12. ImageStreamTag Reference Types
OpenShift supports several image reference styles.
| Reference Type | Example | Meaning |
|---|---|---|
| Direct external image | registry.access.redhat.com/ubi9/httpd-24:latest | Pull directly from external registry |
| ImageStreamTag | my-httpd:latest | Mutable tag in an ImageStream |
| ImageStreamImage | my-httpd@sha256:<digest> | Immutable image digest inside ImageStream |
| DockerImage source | quay.io/org/app:tag | External registry pull spec |
Red Hat documents that ImageStreamTag uses <image_stream_name>:<tag>, ImageStreamImage uses <image_stream_name>@<image_id>, and external DockerImage references use the normal registry pull specification.
13. Refreshing ImageStreams
Refreshing is one of the biggest reasons ImageStreams exist.
There are two refresh styles:
- Manual refresh
- Scheduled refresh
13.1 Manual refresh
Run:
oc import-image my-httpd:latest \
--from=registry.access.redhat.com/ubi9/httpd-24:latest
Code language: JavaScript (javascript)
Or with confirm if creating/updating:
oc import-image my-httpd:latest \
--from=registry.access.redhat.com/ubi9/httpd-24:latest \
--confirm
Code language: JavaScript (javascript)
Check updated tag:
oc describe is my-httpd
Check import events:
oc get events --sort-by=.lastTimestamp | tail -20
Code language: JavaScript (javascript)
13.2 Scheduled refresh using oc tag --scheduled
Create a scheduled tracking tag:
oc tag registry.access.redhat.com/ubi9/httpd-24:latest \
my-httpd:scheduled \
--scheduled=true
Code language: JavaScript (javascript)
Check:
oc describe is my-httpd
Red Hat documents --scheduled=true for periodic refresh/re-import, and the period is configured globally at the system level. In current docs, the example says the default cluster-wide period is 15 minutes.
Remove scheduled behavior:
oc tag registry.access.redhat.com/ubi9/httpd-24:latest \
my-httpd:scheduled
Or delete the tag:
oc tag -d my-httpd:scheduled
Code language: CSS (css)
14. Permanent Tags vs Tracking Tags
OpenShift has two important ImageStream tag behaviors.
14.1 Permanent tag
A permanent tag points to a specific image at a point in time.
oc tag my-httpd:latest my-httpd:stable
Code language: CSS (css)
Red Hat says the default oc tag behavior creates a permanent tag pinned to an image ID. If the source later changes, the destination does not automatically change.
Use this for production-safe promotion:
oc tag my-httpd:latest my-httpd:prod
Code language: CSS (css)
14.2 Tracking tag
A tracking tag follows another tag.
oc tag --alias=true my-httpd:latest my-httpd:tracking
Code language: JavaScript (javascript)
Red Hat documents --alias=true as a tracking tag, where the destination tag metadata updates when the source tag changes. It also notes that this tracking behavior works correctly within a single ImageStream.
Check:
oc describe is my-httpd
15. Trigger Deployments When ImageStream Changes
ImageStreams become powerful when a Deployment reacts to ImageStreamTag changes.
15.1 Create Deployment from ImageStream
oc create deployment httpd-triggered \
--image=my-httpd:latest
Enable image lookup:
oc set image-lookup deploy/httpd-triggered
Code language: JavaScript (javascript)
Now add an image trigger:
oc set triggers deploy/httpd-triggered \
--from-image=my-httpd:latest \
-c httpd
Code language: JavaScript (javascript)
But your container name might not be httpd. Check it first:
oc get deploy httpd-triggered \
-o jsonpath='{.spec.template.spec.containers[*].name}{"\n"}'
Code language: PHP (php)
If the container is named my-httpd, use:
oc set triggers deploy/httpd-triggered \
--from-image=my-httpd:latest \
-c my-httpd
Code language: JavaScript (javascript)
Red Hatโs latest ImageStream trigger docs say Kubernetes resources do not have built-in trigger fields like OpenShift BuildConfigs and DeploymentConfigs, so OpenShift uses the image.openshift.io/triggers annotation. They also document oc set triggers deploy/example --from-image=example:latest -c web for Deployment image-change triggers.
Check triggers:
oc set triggers deploy/httpd-triggered
Code language: JavaScript (javascript)
Check annotation:
oc get deploy httpd-triggered -o yaml | grep -A20 "image.openshift.io/triggers"
Code language: JavaScript (javascript)
15.2 Trigger a rollout by changing the ImageStreamTag
Import another HTTPD image tag into the same ImageStreamTag.
Example:
oc import-image my-httpd:latest \
--from=registry.access.redhat.com/ubi9/httpd-24:latest \
--confirm
Code language: JavaScript (javascript)
Watch rollout:
oc rollout status deploy/httpd-triggered
Check new ReplicaSet:
oc get rs -l app=httpd-triggered
Code language: JavaScript (javascript)
Check Deployment image:
oc get deploy httpd-triggered \
-o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
Code language: PHP (php)
16. Normal Image Update vs ImageStream Update
16.1 Normal image update
With a direct image Deployment:
oc set image deployment/httpd-direct \
httpd=registry.access.redhat.com/ubi9/httpd-24:latest
Code language: JavaScript (javascript)
But check the container name first:
oc get deploy httpd-direct \
-o jsonpath='{.spec.template.spec.containers[*].name}{"\n"}'
Code language: PHP (php)
Then:
oc set image deployment/httpd-direct \
<container-name>=registry.access.redhat.com/ubi9/httpd-24:latest
Code language: HTML, XML (xml)
Rollout:
oc rollout status deployment/httpd-direct
This is manual.
16.2 ImageStream update
With ImageStream:
oc import-image my-httpd:latest \
--from=registry.access.redhat.com/ubi9/httpd-24:latest \
--confirm
Code language: JavaScript (javascript)
If triggers are configured, OpenShift can update the Deployment automatically.
Red Hatโs ImageStream documentation explains that when a new image is added to a stream or a tag is modified, watching resources receive notifications and can react by starting a new build or deployment.
17. Rollback and Promotion
17.1 Promotion using ImageStreams
Create environment-style tags:
oc tag my-httpd:latest my-httpd:dev
oc tag my-httpd:dev my-httpd:test
oc tag my-httpd:test my-httpd:prod
Code language: CSS (css)
Deploy production from:
oc create deployment httpd-prod --image=my-httpd:prod
oc set image-lookup deploy/httpd-prod
Code language: JavaScript (javascript)
Expose:
oc expose deployment httpd-prod --port=8080
oc expose svc httpd-prod
Now your production Deployment refers to the prod ImageStreamTag.
17.2 Roll back prod to older known-good tag
If you have a known-good tag:
oc tag my-httpd:stable my-httpd:prod
Code language: CSS (css)
Then trigger deployment:
oc rollout status deploy/httpd-prod
Or force rollout if needed:
oc rollout restart deploy/httpd-prod
ImageStreams help because you can promote and repoint tags without changing every application YAML.
18. ImageStream with External Image and Local Reference Policy
You can tag an external image and tell OpenShift to use local pull-through behavior:
oc tag registry.access.redhat.com/ubi9/httpd-24:latest \
my-httpd:local \
--reference-policy=local
Red Hat documents --reference-policy=local as a way to instruct OpenShift to fetch the tagged image from the integrated registry, using pull-through behavior.
Check:
oc get istag my-httpd:local -o yaml | grep -A10 referencePolicy
Code language: JavaScript (javascript)
This is useful when you want OpenShift to control how images are pulled, especially in enterprise registry, network, or disconnected setups.
19. Private Registry with ImageStream
If your HTTPD image is in a private registry, create a Docker config JSON secret.
oc create secret generic private-registry-secret \
--from-file=.dockerconfigjson=/path/to/config.json \
--type=kubernetes.io/dockerconfigjson
Code language: JavaScript (javascript)
Then import:
oc import-image private-httpd:latest \
--from=private-registry.example.com/team/httpd:latest \
--confirm
Code language: JavaScript (javascript)
Red Hat documents creating a kubernetes.io/dockerconfigjson secret and then running oc import-image <imagestreamtag> --from=<image> --confirm for importing ImageStreams from private registries.
20. Multi-Architecture ImageStreams
Modern clusters often contain mixed architecture nodes, such as amd64, arm64, ppc64le, or s390x.
OpenShift 4.21 supports --import-mode with oc import-image and oc tag for working with manifest lists. Red Hat documents two modes:
Legacy
PreserveOriginal
The docs say Legacy imports a single sub-manifest, while PreserveOriginal preserves the manifest list. They also note that the default import mode is Legacy.
Import preserving multi-arch manifest list:
oc import-image my-httpd:multiarch \
--from=registry.access.redhat.com/ubi9/httpd-24:latest \
--import-mode='PreserveOriginal' \
--reference-policy=local \
--confirm
Code language: JavaScript (javascript)
Import legacy mode:
oc import-image my-httpd:legacy \
--from=registry.access.redhat.com/ubi9/httpd-24:latest \
--import-mode='Legacy' \
--confirm
Code language: JavaScript (javascript)
Check:
oc describe is my-httpd
21. OpenShift Sample HTTPD ImageStream
Check the OpenShift-provided HTTPD ImageStream:
oc get is httpd -n openshift
Code language: JavaScript (javascript)
Describe:
oc describe is httpd -n openshift
Import/tag it into your own project:
oc tag openshift/httpd:latest local-httpd:latest
Or choose a specific tag after checking:
oc describe is httpd -n openshift
Example:
oc tag openshift/httpd:2.4-ubi9 local-httpd:2.4-ubi9
Enable lookup:
oc set image-lookup local-httpd
Code language: JavaScript (javascript)
Deploy:
oc create deployment httpd-from-sample \
--image=local-httpd:2.4-ubi9
Code language: JavaScript (javascript)
Expose:
oc expose deployment httpd-from-sample --port=8080
oc expose svc httpd-from-sample
Code language: JavaScript (javascript)
Test:
curl -I "$(oc get route httpd-from-sample -o jsonpath='http://{.spec.host}')"
Code language: JavaScript (javascript)
The Cluster Samples Operator can manage sample ImageStreams, and Red Hat documents that the operator monitors ImageStreamTag imports and retries failed imports about every 15 minutes until the import succeeds or the configuration changes.
22. Full Side-by-Side Hands-on Test
22.1 Clean project
oc new-project httpd-compare
Code language: JavaScript (javascript)
22.2 Direct image deployment
oc create deployment httpd-direct \
--image=registry.access.redhat.com/ubi9/httpd-24:latest
oc expose deployment httpd-direct --port=8080
oc expose svc httpd-direct
Verify:
oc get deploy httpd-direct \
-o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
oc get is
Code language: PHP (php)
Expected:
registry.access.redhat.com/ubi9/httpd-24:latest
No resources found in httpd-compare namespace.
Code language: PHP (php)
22.3 ImageStream deployment
oc import-image my-httpd:latest \
--from=registry.access.redhat.com/ubi9/httpd-24:latest \
--confirm
oc set image-lookup my-httpd
oc create deployment httpd-is \
--image=my-httpd:latest
oc expose deployment httpd-is --port=8080
oc expose svc httpd-is
Code language: JavaScript (javascript)
Verify:
oc get is
oc describe is my-httpd
oc get deploy httpd-is \
-o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
Code language: PHP (php)
22.4 Add trigger to ImageStream deployment
Find container name:
oc get deploy httpd-is \
-o jsonpath='{.spec.template.spec.containers[*].name}{"\n"}'
Code language: PHP (php)
Add trigger:
oc set triggers deploy/httpd-is \
--from-image=my-httpd:latest \
-c my-httpd
Code language: JavaScript (javascript)
If container name differs, replace my-httpd.
Check:
oc set triggers deploy/httpd-is
Code language: JavaScript (javascript)
22.5 Refresh ImageStream
oc import-image my-httpd:latest \
--from=registry.access.redhat.com/ubi9/httpd-24:latest \
--confirm
Code language: JavaScript (javascript)
Watch:
oc rollout status deploy/httpd-is
23. Troubleshooting
Problem 1: ImagePullBackOff
Check:
oc describe pod <pod-name>
Code language: HTML, XML (xml)
Common causes:
Wrong image name
Registry requires authentication
Cluster cannot reach registry
Image is blocked by image policy
Pull secret missing
Architecture mismatch
Problem 2: ImageStream not found
oc get is
oc get is -n openshift
Code language: JavaScript (javascript)
If using sample ImageStreams:
oc get configs.samples.operator.openshift.io cluster -o yaml
Code language: CSS (css)
Problem 3: Short image name does not resolve
Example failure:
oc create deployment test --image=my-httpd:latest
Fix:
oc set image-lookup my-httpd
Code language: JavaScript (javascript)
Or:
oc set image-lookup deploy/test
Code language: JavaScript (javascript)
OpenShift requires ImageStream lookup to resolve short ImageStream references in Kubernetes resources.
Problem 4: Trigger not working
Check trigger annotation:
oc get deploy httpd-is -o yaml | grep -A20 image.openshift.io/triggers
Code language: JavaScript (javascript)
Check container name:
oc get deploy httpd-is \
-o jsonpath='{.spec.template.spec.containers[*].name}{"\n"}'
Code language: PHP (php)
Recreate trigger:
oc set triggers deploy/httpd-is \
--from-image=my-httpd:latest \
-c <container-name>
Code language: HTML, XML (xml)
Problem 5: oc command behaves strangely
Your client is 4.18.7 and server is 4.21.14. Install the matching 4.21 oc client.
Red Hatโs 4.21 docs warn that if an earlier oc is installed, you might not be able to complete all OpenShift 4.21 commands.
24. When to Use Normal Images
Use direct images when:
You want Kubernetes portability.
You are deploying a simple app.
You do not need ImageStream triggers.
You do not need OpenShift-native promotion.
You manage images fully outside OpenShift.
Your CI/CD already pins images by digest.
Code language: JavaScript (javascript)
Example production-style direct image:
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd-direct-prod
spec:
replicas: 2
selector:
matchLabels:
app: httpd-direct-prod
template:
metadata:
labels:
app: httpd-direct-prod
spec:
containers:
- name: httpd
image: registry.access.redhat.com/ubi9/httpd-24@sha256:<digest>
ports:
- containerPort: 8080
Code language: HTML, XML (xml)
For production, prefer immutable digests over mutable latest tags.
25. When to Use ImageStreams
Use ImageStreams when:
You are building OpenShift-native CI/CD.
You want automatic deployment triggers.
You want dev/test/prod image promotion.
You want ImageStreamTag rollback.
You want to abstract external registry locations.
You want to support disconnected or mirrored environments.
You want better OpenShift RBAC around image references.
You use BuildConfigs, S2I, or OpenShift image workflows.
Code language: PHP (php)
Red Hat specifically lists ImageStream advantages around triggers, periodic re-import, known-good image behavior, access control, and image sharing.
26. Recommended Enterprise Pattern
For enterprise OpenShift:
Do not deploy random external images directly in production.
Import approved base images into controlled ImageStreams.
Use ImageStreamTags such as dev, qa, stage, prod.
Use triggers only where automatic rollout is desired.
Pin production releases to stable or digest-backed tags.
Use scheduled imports for approved base images.
Use registry policies and mirroring for disconnected or secured clusters.
Use matching oc client version for your OpenShift server.
Code language: PHP (php)
Recommended flow:
External Registry
|
v
Approved ImageStream: my-httpd:latest
|
v
Promotion: my-httpd:dev -> my-httpd:test -> my-httpd:prod
|
v
Deployment uses my-httpd:prod
27. Final Summary
A normal image deployment is simple and Kubernetes-portable:
oc create deployment httpd-direct \
--image=registry.access.redhat.com/ubi9/httpd-24:latest
An ImageStream deployment is OpenShift-native and better for enterprise image lifecycle management:
oc import-image my-httpd:latest \
--from=registry.access.redhat.com/ubi9/httpd-24:latest \
--confirm
oc set image-lookup my-httpd
oc create deployment httpd-is \
--image=my-httpd:latest
Code language: JavaScript (javascript)
The practical difference:
Normal image = direct pull from registry.
ImageStream = OpenShift-managed image reference, metadata, tags, imports, triggers, promotion, and governance.
Code language: JavaScript (javascript)
The best one-line answer:
Use direct images for simple Kubernetes-style deployments; use ImageStreams when you want OpenShift-native image tracking, promotion, triggers, refresh, rollback, and enterprise control.
Code language: PHP (php)
28. Cleanup
oc project httpd-image-demo
oc delete project httpd-image-demo
oc project httpd-compare
oc delete project httpd-compare
Code language: JavaScript (javascript)Iโm a DevOps/SRE/DevSecOps/Cloud Expert passionate about sharing knowledge and experiences. I have worked at Cotocus. I share tech blog at DevOps School, travel stories at Holiday Landmark, stock market tips at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow , and SEO strategies at Wizbrand.
Do you want to learn Quantum Computing?
Please find my social handles as below;
Rajesh Kumar Personal Website
Rajesh Kumar at YOUTUBE
Rajesh Kumar at INSTAGRAM
Rajesh Kumar at X
Rajesh Kumar at FACEBOOK
Rajesh Kumar at LINKEDIN
Rajesh Kumar at WIZBRAND
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services โ all in one place.
Explore Hospitals