Bookmark this page

Creating Image Streams

Objectives

  • Create and Manage Red Hat OpenShift Image Streams.

Red Hat OpenShift Image Streams

Image streams are an OpenShift specific resource that you can use to reference container images by using an intermediate name that points to an image from a container registry. Kubernetes resources reference container images directly, but OpenShift resources, such as deployment configurations and build configurations, can also reference image streams. OpenShift also extends Kubernetes resources, such as StatefulSet and CronJob resources, with annotations that make them work with OpenShift image streams.

An image stream is a collection of related image stream tags. To use an image stream, you reference an image stream tag. This is similar to a container image in an image registry. But, unlike tags in an image registry, image stream tags point to the same image even if the original container image tag gets updated.

Image streams have the following benefits:

  • They provide a level of indirection to the container image that OpenShift runs.

  • They allow for rolling back to a previous container version without updating the image registry.

  • They enable build and deployment automations when an image stream tag gets updated.

  • They enable the caching of images from external image registries.

  • You can use role-based access control (RBAC) on the image stream object to secure access to container images.

The indirection that image streams provide helps to decouple applications from the source of the container images they use. That is, without this indirection, developers might see images change because of an external registry change. They also ease rollbacks of deployments to their latest known-good state by caching previous versions of the image, which also reduces bandwidth usage.

There are other scenarios where the indirection provided by an image stream proves to be helpful. Suppose that you use a database container image with security issues and the vendor takes too long to patch the image. You later find another vendor that provides a container image for the same database with the security patches. If those container images are compatible, then migrating to the new image could be as simple as updating the image stream.

For example, the following ImageStream defines the nodejs image stream name with a latest and a 16-ubi8 tag.

apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  name: nodejs 1
  ...output omitted...
spec: {}
status:
  dockerImageRepository: image-registry.openshift-image-registry.svc:5000/openshift/nodejs 2
  publicDockerImageRepository: default-route-openshift-image-registry.apps.ocp4.example.com/openshift/nodejs 3
  tags:
  - tag: 16-ubi8 4
    items:
    - created: "2023-05-03T19:51:25Z"
      dockerImageReference: registry.ocp4.example.com:8443/ubi8/nodejs-16@sha256:4fe...6d98
      image: sha256:4fe...6d98
      ...output omitted...
    - created: "2023-02-02T14:47:43Z"
      dockerImageReference: registry.ocp4.example.com:8443/ubi8/nodejs-16@sha256: c134...704d
      image: sha256:c134...704d
      ...output omitted...
  - tag: latest 5
    items:
    - created: "2023-05-03T19:51:25Z"
      dockerImageReference: registry.ocp4.example.com:8443/ubi8/nodejs-16@sha256:4fe...6d98
      image: sha256:4fe0...6d98
      ...output omitted...

1

The name of the image stream.

2

The URI of the images within the internal registry.

3

The URI of the images within the external registry.

4 5

An available tag for the image stream.

Image Names, Tags, and IDs

Image names are strings that reference a container image in an image registry. That name reference is not tied to the image contents and the same name reference can later point to a new version of a container image.

An image stream represents one or more sets of container images. Each set, or stream, is identified by an image stream tag, which contains a historic list of the container images that the image stream tag referenced along with the container image in use. Unlike container images in a registry, image stream tags can reference container images from different registries and repositories.

An image ID uniquely identifies an immutable container image by using a SHA-256 hash. Remember that you cannot modify a container image. Instead, a new container image is created and given a new ID. When you push a new container image to a registry, the server associates the existing textual name with the new image ID.

When you start a container from an image name, the currently associated image is downloaded. The actual image ID and layers behind that name can change at any moment, so the next container that you create might use a different underlying image. You cannot easily revert to an earlier image if you only know the image name. Image stream tags keep a history of the image IDs fetched from registries, which eases rolling back to previous versions of an image.

To better visualize the relationships between resource types, the following oc describe is command shows the source image and current image ID for each image stream tag:

[user@host ~]$ oc describe is php -n openshift
Name:                   php 1
Namespace:              openshift
...output omitted...
Tags:                   6
7.3 (latest) 2
  tagged from registry.redhat.io/rhscl/php-73-rhel7:latest 3
...output omitted...
  * registry.redhat.io/rhscl/php-73-rhel7@sha256:22ba...09b5 4
...output omitted...
7.2
  tagged from registry.redhat.io/rhscl/php-72-rhel7:latest
...output omitted...
  * registry.redhat.io/rhscl/php-72-rhel7@sha256:e8d6...e615
...output omitted...

1

The name of the image stream

2

The tag name, which is also tagged as the latest image

3

The image name

4

The image ID of the current image for the 7.3 tag

If the php:7.3 image stream tag is updated, the oc describe is command shows multiple image IDs for that tag:

[user@host ~]$ oc describe is php -n openshift
Name:                   php
Namespace:              openshift
...output omitted...
7.3 (latest)
  tagged from registry.redhat.io/rhscl/php-73-rhel7:latest
...output omitted...
  * registry.redhat.io/rhscl/php-73-rhel7@sha256:22ba...09b5
...output omitted...
    registry.redhat.io/rhscl/php-73-rhel7@sha256:bc61...1e91
...output omitted...
7.2
  tagged from registry.redhat.io/rhscl/php-72-rhel7:latest
...output omitted...
  * registry.redhat.io/rhscl/php-72-rhel7@sha256:e8d6...e615
...output omitted...

In the previous example, the asterisk (*) shows which image ID is the current one for each image stream tag.

Managing Image Streams and Tags

An image stream tag keeps track of its last-fetched image IDs. Pushing a new image to an external registry does not automatically update an image stream tag. This behavior isolates applications in OpenShift clusters from unexpected changes to images in external registries. By using image stream tags, OpenShift ensures that all pods use exactly the same image.

Build configurations in the cluster automatically update the image stream tag defined as their output image. If the resources that use that image stream tag have a trigger which reacts the tag being updated, then the cluster automatically updates those resources with the new image.

To create an image stream tag resource for an image from an external registry, use the oc import-image command. Use the --from option to specify the source for the image. If you do not specify a tag name, then the latest tag is used by default. The tag name for the image stream tag can be different from the container image tag on the source registry server.

For example, the following command imports a my-app-stream container image from an external container registry and periodically checks for updates:

[user@host ~]$ oc import-image myimagestream --confirm --scheduled=true \
--from example.com/example-repo/my-app-image

To create one image stream tag resource for each container image tag that exists in the source registry server, add the --all option to the oc import-image command. The following command creates or updates all image stream tags for new tags on the source registry server:

[user@host ~]$ oc import-image myimagestream --confirm --all \
--from registry/myorg/myimage

Running the oc import-image command on an existing image stream updates one of its current image stream tags to the current image IDs on the source registry server, such as in the following command:

[user@host ~]$ oc import-image myimagestream[:tag] --confirm

Exert finer control over an image stream tag by using the oc tag command. This enables you to associate an image stream tag with the following:

  • A different registry than the one in its image stream

  • A different container image name and tag

  • An image ID that might not be the one currently associated with the image tag on the registry server

  • An alias for the image stream tag

For example, to update the latest image stream tag to point to a different tag you can run the following command:

[user@host ~]$ oc tag myimagestream:tag _myimagestream:latest

Creating Image Streams From Private Registries

To create image streams and image stream tags that refer to a private registry, OpenShift needs an access token to that registry server. The oc import-image command searches the secrets in the current project for one that matches the registry hostname.

The following example commands use Podman to log in to a private registry, create a secret to store the access token, and create an image stream that points to the private registry:

[user@host ~]$ podman login -u myuser registry.example.com
[user@host ~]$ oc create secret generic regtoken \
--from-file .dockerconfigjson=${XDG_RUNTIME_DIR}/containers/auth.json \
--type kubernetes.io/dockerconfigjson
[user@host ~]$ oc import-image myimagestream --confirm \
--from registry.example.com/myorg/myimage

After you create an image stream, you can use it to deploy an application by using the oc new-app command and by using the -i option to specify the image stream.

By default, an image stream resource is only available to create applications or builds in the same project.

Using Image Streams with Kubernetes Resources

You can use image streams with native Kubernetes resources that use container images. OpenShift has an image lookup mechanism for image streams, which replaces the image field in a resource definition with the image ID taken from the image stream. When using image streams with Kubernetes resources, you can only reference image streams that reside in the same project as the resource.

You can enable the lookup mechanism for all resources by using a particular image stream with the following command:

[user@host ~]$ oc set image-lookup myimagestream

The previous command affects resources from the same project and enables the lookup for all the tags in the image stream. You cannot enable image lookup in the default project or any of the openshift- projects.

For finer control, you can enable image lookup on a specific Kubernetes resource with the following command:

[user@host ~]$ oc set image-lookup resource/name

This sets the alpha.image.policy.openshift.io/resolve-names annotation on the resource, which enables the image lookup.

For example, enabling the image lookup on a MySQL Deployment resource produces the following manifest:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: myproject
spec:
  replicas: 1
  template:
    metadata:
      annotations:
        alpha.image.policy.openshift.io/resolve-names: '*'
    spec:
      containers:
      - image: mysql:latest
        imagePullPolicy: Always
        name: mysql

When OpenShift creates a pod by using the previous template, it looks for the mysql:latest image stream tag and replaces the container image field with the current image ID that the image stream tag references.

Sharing an Image Stream Between Multiple Projects

One common practice is to use a separate project to store shared resources for multiple users and teams. One such project might store resources such as image streams and templates, both of which developers refer to when deploying applications to their projects.

OpenShift comes with a shared project called openshift that provides quick-start application templates. It also contains image streams for S2I builder images for popular programming language runtimes, such as Python and Node.js.

Important

Starting with Red Hat OpenShift Container Platform 4, the Samples operator manages the openshift project and might remove manually added resources.

You have the following two options for building and deploying applications that use an image stream from another project:

  • Create a secret with an access token to the private registry within each project that uses the image stream, and link that secret to each project's service accounts.

  • Create a secret with an access token to the private registry only on the project where you create the image stream, and configure that image stream tag by using the --reference-policy=local option of the oc import-image command. The local reference policy always gets the image from the integrated image registry. Then, grant rights to use the image stream to service accounts from each project that uses the image stream.

The first option resembles deploying an application from a container image in a private registry. This negates some benefits of using image streams because, if the image stream tag that you refer to changes to reference another registry, then you must create a secret in all dependent projects.

The second option enables projects that reference the image stream to remain isolated from changes in the image stream tags that they consume.

The following example demonstrates the second option. It creates an image stream in the shared project and uses that image stream to deploy an application in the myapp project. Output from each command is omitted to better show the sequence of commands and their structure.

[user@host ~]$ podman login -u myuser registry.example.com
[user@host ~]$ oc project shared
[user@host ~]$ oc create secret generic regtoken \
--from-file .dockerconfigjson=${XDG_RUNTIME_DIR}/containers/auth.json \
--type kubernetes.io/dockerconfigjson
[user@host ~]$ oc import-image myis --confirm \
--reference-policy local \  1
--from registry.example.com/myorg/myimage
[user@host ~]$ oc policy add-role-to-group system:image-puller \   2
system:serviceaccounts:myapp  3
[user@host ~]$ oc project myapp
[user@host ~]$ oc new-app -i shared/myis

1

The --reference-policy local option configures the image stream to cache image layers in the internal registry, so that projects referencing the image stream do not need an access token to the external private registry.

2

The system:image-puller role allows a service account to pull the image layers that the image stream cached in the internal registry.

3

The system:serviceaccounts:myapp group includes all service accounts from the myapp project.

The oc policy command does not require cluster administrator privileges, but only project administrator privileges.

References

How to Simplify Container Image Management in Kubernetes with OpenShift Image Streams

Further information about image streams, image stream tags, and image IDs is available in the Understanding Containers, Images, and Image Streams chapter of the Images guide for Red Hat OpenShift Container Platform 4.12 at https://access.redhat.com/documentation/en-us/openshift_container_platform/4.12/html-single/images/index#about-containers-images-and-image-streams

Revision: do288-4.12-0d49506