<registry_server>/<user_name>/<image_name>:<tag>
An image stream comprises any number of container images identified by tags. It presents a single virtual view of related images, similar to a Docker image repository.
By watching an image stream, builds and deployments can receive notifications when new images are added or modified and react by performing a build or deployment, respectively.
There are many ways you can interact with images and set up image streams, depending on where the images' registries are located, any authentication requirements around those registries, and how you want your builds and deployments to behave. The following sections cover a range of these topics.
Before working with OpenShift Enterprise image streams and their tags, it will help to first understand image tags in the context of Docker generally.
Container images can have names added to them that make it more intuitive to determine what they contain, called a tag. Using a tag to specify the version of what is contained in the image is a common use case. If you have an image named ruby, you could have a tag named 2.0 for 2.0 version of Ruby, and another named latest to indicate literally the latest built image in that repository overall.
When interacting directly with images using the docker
CLI, the docker tag
command can add tags, which essentially adds an alias to an image that can
consist of several parts. Those parts can include:
<registry_server>/<user_name>/<image_name>:<tag>
The <user_name>
part in the above could also refer to a
project or
namespace
if the image is being stored in an OpenShift Enterprise environment with an internal
registry.
OpenShift Enterprise provides the oc tag
command, which is similar to the docker
tag
command, but operates on image streams instead of directly on images.
See Red Hat Enterprise Linux 7’s
Getting
Started with Containers documentation for more about tagging images directly
using the |
Keeping in mind that an image stream in OpenShift Enterprise comprises zero or more
container images identified by tags, you can add tags to an image stream using the
oc tag
command:
$ oc tag <source> <destination>
For example, to configure the ruby image’s latest tag to always refer to the current image for the tag 2.0:
$ oc tag ruby:latest ruby:2.0
There are different types of tags available. The default behavior uses a permanent tag, which points to a specific image in time; even when the source changes, it will not reflect in the destination tag.
A tracking tag means the destination tag’s metadata will be imported during
the import. To ensure the destination tag is updated whenever the source tag
changes, use the --alias=true
flag:
$ oc tag --alias=true <source> <destination>
You can also add the --scheduled=true
flag to have the destination tag be
refreshed (i.e., re-imported) periodically. The period is configured globally at
the system level. See Importing Tag and Image
Metadata for more details.
Avoid tagging OpenShift Enterprise-managed images (i.e., those built using an OpenShift Enterprise instance and pushed to its internal registry). There is a known issue that prevents the registry client from pulling from such a tag. |
You can stop tracking a tag by removing the tag. For example, to stop tracking an existing latest tag:
$ oc tag -d ruby:latest
However, while the above command removes the tag from the image stream definition, it does not remove it from the image stream status. The image stream definition is user-defined, whereas the image stream status reflects the information the system has from the specification.
To remove a tag completely from an image stream:
$ oc delete istag/ruby:latest
Images can be referenced in image streams using the following reference types:
An ImageStreamTag
is used to reference or retrieve an image for a given
image stream and tag. It uses the following convention for its name:
<image_stream_name>:<tag>
An ImageStreamImage
is used to reference or retrieve an image for a given
image stream and image name. It uses the following convention for its name:
<image_stream_name>@<id>
The <id>
is an immutable identifier for a specific image, also called a
digest.
A DockerImage
is used to reference or retrieve an image for a given external
registry. It uses standard Docker pull specification for its name, e.g.:
openshift/ruby-20-centos7:2.0
When no tag is specified, it is assumed the latest tag will be used. |
You can also reference a third-party registry:
registry.access.redhat.com/rhel7:latest
Or an image with a digest:
centos/ruby-22-centos7@sha256:3a335d7d8a452970c5b4054ad7118ff134b3a6b50a2bb6d0c07c746e8986b28e
When viewing example image stream definitions, such as the
example
CentOS image streams, you may notice they contain definitions of
ImageStreamTag
and references to DockerImage
, but nothing related to
ImageStreamImage
.
This is because the ImageStreamImage
objects are automatically created in
OpenShift Enterprise whenever you import or tag an image into the image stream. You
should never have to explicitly define an ImageStreamImage
object in any
image stream definition that you use to create image streams.
You can view an image’s object definition by retrieving an ImageStreamImage
definition using the image stream name and ID:
$ oc export isimage <image_stream_name>@<id>
You can find valid $ oc describe is <image_stream_name> |
For example, from the ruby image stream asking for the ImageStreamImage
with the name and ID of ruby@3a335d7:
$ oc export isimage ruby@3a335d7 apiVersion: v1 image: dockerImageLayers: - name: sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 size: 0 - name: sha256:ee1dd2cb6df21971f4af6de0f1d7782b81fb63156801cfde2bb47b4247c23c29 size: 196634330 - name: sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 size: 0 - name: sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 size: 0 - name: sha256:ca062656bff07f18bff46be00f40cfbb069687ec124ac0aa038fd676cfaea092 size: 177723024 - name: sha256:63d529c59c92843c395befd065de516ee9ed4995549f8218eac6ff088bfa6b6e size: 55679776 dockerImageMetadata: Architecture: amd64 Author: SoftwareCollections.org <sclorg@redhat.com> Config: Cmd: - /bin/sh - -c - $STI_SCRIPTS_PATH/usage Entrypoint: - container-entrypoint Env: - PATH=/opt/app-root/src/bin:/opt/app-root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin - STI_SCRIPTS_URL=image:///usr/libexec/s2i - STI_SCRIPTS_PATH=/usr/libexec/s2i - HOME=/opt/app-root/src - BASH_ENV=/opt/app-root/etc/scl_enable - ENV=/opt/app-root/etc/scl_enable - PROMPT_COMMAND=. /opt/app-root/etc/scl_enable - RUBY_VERSION=2.2 ExposedPorts: 8080/tcp: {} Image: d9c3abc5456a9461954ff0de8ae25e0e016aad35700594714d42b687564b1f51 Labels: build-date: 2015-12-23 io.k8s.description: Platform for building and running Ruby 2.2 applications io.k8s.display-name: Ruby 2.2 io.openshift.builder-base-version: 8d95148 io.openshift.builder-version: 8847438ba06307f86ac877465eadc835201241df io.openshift.expose-services: 8080:http io.openshift.s2i.scripts-url: image:///usr/libexec/s2i io.openshift.tags: builder,ruby,ruby22 io.s2i.scripts-url: image:///usr/libexec/s2i license: GPLv2 name: CentOS Base Image vendor: CentOS User: "1001" WorkingDir: /opt/app-root/src ContainerConfig: {} Created: 2016-01-26T21:07:27Z DockerVersion: 1.8.2-el7 Id: 57b08d979c86f4500dc8cad639c9518744c8dd39447c055a3517dc9c18d6fccd Parent: d9c3abc5456a9461954ff0de8ae25e0e016aad35700594714d42b687564b1f51 Size: 430037130 apiVersion: "1.0" kind: DockerImage dockerImageMetadataVersion: "1.0" dockerImageReference: centos/ruby-22-centos7@sha256:3a335d7d8a452970c5b4054ad7118ff134b3a6b50a2bb6d0c07c746e8986b28e metadata: creationTimestamp: 2016-01-29T13:17:45Z name: sha256:3a335d7d8a452970c5b4054ad7118ff134b3a6b50a2bb6d0c07c746e8986b28e resourceVersion: "352" uid: af2e7a0c-c68a-11e5-8a99-525400f25e34 kind: ImageStreamImage metadata: creationTimestamp: null name: ruby@3a335d7 namespace: openshift selflink: /oapi/v1/namespaces/openshift/imagestreamimages/ruby@3a335d7
Each container in a pod has a container image. Once you have created an image and pushed it to a registry, you can then refer to it in the pod.
When OpenShift Enterprise creates containers, it uses the container’s
imagePullPolicy
to determine if the image should be pulled prior to starting
the container. There are three possible values for imagePullPolicy
:
Always
- always pull the image.
IfNotPresent
- only pull the image if it does not already exist on the node.
Never
- never pull the image.
If a container’s imagePullPolicy
parameter is not specified, OpenShift Enterprise sets it based on the image’s tag:
If the tag is latest, OpenShift Enterprise defaults imagePullPolicy
to Always
.
Otherwise, OpenShift Enterprise defaults imagePullPolicy
to IfNotPresent
.
You can access OpenShift Enterprise’s internal registry directly to push or pull
images. For example, this could be helpful if you wanted to
create an image
stream by manually pushing an image, or just to docker pull
an image
directly.
The internal registry authenticates using the same
tokens
as the OpenShift Enterprise API. To perform a docker login
against the internal registry,
you can choose any user name and email, but the password must be a valid
OpenShift Enterprise token.
To log into the internal registry:
Log in to OpenShift Enterprise:
$ oc login
Get your access token:
$ oc whoami -t
Log in to the internal registry using the token. You must have docker installed on your system:
$ docker login -u <user_name> -e <email_address> \ -p <token_value> <registry_server>:<port>
Contact your cluster administrator if you do not know the registry IP or host name and port to use. |
In order to pull an image, the authenticated user must have get
rights on the
requested imagestreams/layers
. In order to push an image, the authenticated
user must have update
rights on the requested imagestreams/layers
.
By default, all service accounts in a project have rights to pull any image in the same project, and the builder service account has rights to push any image in the same project.
Docker registries can be secured to prevent unauthorized parties from accessing certain images. If you are using OpenShift Enterprise’s internal registry and are pulling from image streams located in the same project, then your pod’s service account should already have the correct permissions and no additional action should be required.
However, for other scenarios, such as referencing images across OpenShift Enterprise projects or from secured registries, then additional configuration steps are required. The following sections detail these scenarios and their required steps.
When using the internal registry, to allow pods in project-a to reference
images in project-b, a service account in project-a must be bound to the
system:image-puller
role in project-b:
$ oc policy add-role-to-user \ system:image-puller system:serviceaccount:project-a:default \ --namespace=project-b
After adding that role, the pods in project-a that reference the default service account will be able to pull images from project-b.
To allow access for any service account in project-a, use the group:
$ oc policy add-role-to-group \ system:image-puller system:serviceaccounts:project-a \ --namespace=project-b
The .dockercfg file (or $HOME/.docker/config.json for newer Docker clients) is a Docker credentials file that stores your information if you have previously logged into a secured or insecure registry.
To pull a secured container image that is not from OpenShift Enterprise’s internal registry, you must create a pull secret from your Docker credentials and add it to your service account.
If you already have a .dockercfg file for the secured registry, you can create a secret from that file by running:
$ oc secrets new <pull_secret_name> .dockercfg=<path/to/.dockercfg>
Or if you have a $HOME/.docker/config.json file:
$ oc secrets new <pull_secret_name> .dockerconfigjson=<path/to/.docker/config.json>
If you do not already have a Docker credentials file for the secured registry, you can create a secret by running:
$ oc secrets new-dockercfg <pull_secret_name> \ --docker-server=<registry_server> --docker-username=<user_name> \ --docker-password=<password> --docker-email=<email>
To use a secret for pulling images for pods, you must add the secret to your service account. The name of the service account in this example should match the name of the service account the pod will use; default is the default service account:
$ oc secrets add serviceaccount/default secrets/<pull_secret_name> --for=pull
To use a secret for pushing and pulling build images, the secret must be mountable inside of a pod. You can do this by running:
$ oc secrets add serviceaccount/builder secrets/<pull_secret_name>
An image stream can be configured to import tag and image metadata from an image repository in an external Docker image registry. You can do this using a few different methods.
You can manually import tag and image information with the oc import-image
command using the --from
option:
$ oc import-image <image_stream_name>[:<tag>] --from=<docker_image_repo> --confirm
For example:
$ oc import-image my-ruby --from=docker.io/openshift/ruby-20-centos7 --confirm The import completed successfully. Name: my-ruby Created: Less than a second ago Labels: <none> Annotations: openshift.io/image.dockerRepositoryCheck=2016-05-06T20:59:30Z Docker Pull Spec: 172.30.94.234:5000/demo-project/my-ruby Tag Spec Created PullSpec Image latest docker.io/openshift/ruby-20-centos7 Less than a second ago docker.io/openshift/ruby-20-centos7@sha256:772c5bf9b2d1e8... <same>
You can also add the --all
flag to import all tags for the image instead of
just latest.
Like most objects in OpenShift Enterprise, you can also write and save a JSON or YAML
definition to a file then create the object using the CLI. Set the
spec.dockerImageRepository
field to the Docker pull spec for the image:
apiVersion: "v1" kind: "ImageStream" metadata: name: "my-ruby" spec: dockerImageRepository: "docker.io/openshift/ruby-20-centos7"
Then create the object:
$ oc create -f <file>
When you create an image stream that references an image in an external Docker registry, OpenShift Enterprise communicates with the external registry within a short amount of time to get up to date information about the image.
After the tag and image metadata is synchronized, the image stream object would look similar to the following:
apiVersion: v1 kind: ImageStream metadata: name: my-ruby namespace: demo-project selflink: /oapi/v1/namespaces/demo-project/imagestreams/my-ruby uid: 5b9bd745-13d2-11e6-9a86-0ada84b8265d resourceVersion: '4699413' generation: 2 creationTimestamp: '2016-05-06T21:34:48Z' annotations: openshift.io/image.dockerRepositoryCheck: '2016-05-06T21:34:48Z' spec: dockerImageRepository: docker.io/openshift/ruby-20-centos7 tags: - name: latest annotations: null from: kind: DockerImage name: 'docker.io/openshift/ruby-20-centos7:latest' generation: 2 importPolicy: { } status: dockerImageRepository: '172.30.94.234:5000/demo-project/my-ruby' tags: - tag: latest items: - created: '2016-05-06T21:34:48Z' dockerImageReference: 'docker.io/openshift/ruby-20-centos7@sha256:772c5bf9b2d1e8e80742ed75aab05820419dc4532fa6d7ad8a1efddda5493dc3' image: 'sha256:772c5bf9b2d1e8e80742ed75aab05820419dc4532fa6d7ad8a1efddda5493dc3' generation: 2
You can set a tag to query external registries at a scheduled interval to
synchronize tag and image metadata by setting the --scheduled=true
flag with
the oc tag
command as mentioned in Adding Tags to Image
Streams.
Alternatively, you can set importPolicy.scheduled
to true in the tag’s
definition:
apiVersion: v1 kind: ImageStream metadata: name: ruby spec: tags: - from: kind: DockerImage name: openshift/ruby-20-centos7 name: latest importPolicy: scheduled: true
An image stream can be configured to import tag and image metadata from insecure image registries, such as those signed with a self-signed certificate or using plain HTTP instead of HTTPS.
To configure this, add the openshift.io/image.insecureRepository
annotation
and set it to true. This setting bypasses certificate validation when
connecting to the registry:
kind: ImageStream
apiVersion: v1
metadata:
name: ruby
annotations:
openshift.io/image.insecureRepository: "true" (1)
spec:
dockerImageRepository: my.repo.com:5000/myimage
1 | Set the openshift.io/image.insecureRepository annotation to true |
The above definition only affects importing tag and image metadata. For this
image to be used in the cluster (e.g., to be able to do a |
Additionally, you can specify a single tag using an insecure repository. To do
so, set importPolicy.insecure
in the tag’s definition to true:
kind: ImageStream
apiVersion: v1
metadata:
name: ruby
tags:
- from:
kind: DockerImage
name: my.repo.com:5000/myimage
name: mytag
importPolicy:
insecure: true (1)
1 | Set tag mytag to use insecure connection to that registry. |
An image stream can be configured to import tag and image metadata from private image registries, requiring authentication.
To configure this, you need to create a secret which is used to store your credentials.
Create the secret first, before importing the image from the private repository:
$ oc secrets new-dockercfg <secret_name> \ --docker-server=<docker_registry_server> \ --docker-username=<docker_user> \ --docker-password=<docker_password> \ --docker-email=<docker_email>
For more options, see:
$ oc secrets new-dockercfg --help
After the secret is configured, proceed with creating the new image stream or
using the oc import-image
command. During the import process, OpenShift Enterprise
will pick up the secrets and provide them to the remote party.
When importing from an insecure registry, the registry URL defined in the secret
must include the |
An image stream can be configured to import tag and image metadata from the
internal registry, but from a different project. The recommended method for
this is to use the oc tag
command as shown in Adding Tags to
Image Streams:
$ oc tag <source_project>/<image_stream>:<tag> <new_image_stream>:<new_tag>
Another method is to import the image from the other project manually using the pull spec:
The following method is strongly discouraged and should be used only if the
former using |
First, add the necessary policy to access the other project:
$ oc policy add-role-to-group \ system:image-puller \ system:serviceaccounts:<destination_project> \ -n <source_project>
This allows <destination_project>
to pull images from <source_project>
.
With the policy in place, you can import the image manually:
$ oc import-image <new_image_stream> --confirm \ --from=<docker_registry>/<source_project>/<image_stream>
An image stream can also be automatically created by manually pushing an image to the internal registry. This is only possible when using an OpenShift Enterprise internal registry.
Before performing this procedure, the following must be satisfied:
The destination project you push to must already exist.
The user must be authorized to {get, update} "imagestream/layers"
in that
project. The system:image-pusher role can be added to a user to provide these
permissions. If you are a project administrator, then you would also have these
permissions.
To create an image stream by manually pushing an image:
First, log in to the internal registry.
Then, tag your image using the appropriate internal registry location. For example, if you had already pulled the docker.io/centos:centos7 image locally:
$ docker tag docker.io/centos:centos7 172.30.48.125:5000/test/my-image
Finally, push the image to your internal registry. For example:
$ docker push 172.30.48.125:5000/test/my-image The push refers to a repository [172.30.48.125:5000/test/my-image] (len: 1) c8a648134623: Pushed 2bf4902415e3: Pushed latest: digest: sha256:be8bc4068b2f60cf274fc216e4caba6aa845fff5fa29139e6e7497bb57e48d67 size: 6273
Verify that the image stream was created:
$ oc get is NAME DOCKER REPO TAGS UPDATED my-image 172.30.48.125:5000/test/my-image latest 3 seconds ago