Red Hat OpenShift is a Kubernetes-based container platform. Typically, any containerized applications that deploys and runs properly in a Kubernetes cluster will also deploy and run properly in an OpenShift cluster. However, OpenShift includes some default security settings that require you to change how your container image is built in order to deploy to OpenShift.
This article shows you how to alter your Kubernetes container image to run on OpenShift as well as how to verify whether your container image requires modification before migration. This article is most meaningful for those who design and build container images.
This article highlights four of the areas covered in the original learning path that give people the most trouble when trying to adapt Kubernetes images to run on OpenShift. These include:
Building OCI-compliant container images
Running processes without root user access in container images
Building container images with the base image as Red Hat Enterprise Linux or a Universal Base Image
Storing images in an integrated image registry or in an external image registry
Build an OCI-compliant container image
CRI and OCI-compliance
A container runtime takes a container image and runs the application defined in the image. Originally in Kubernetes, the individual nodes of the cluster used Docker's runtime to run containers. To accommodate more container runtimes, Kubernetes created an abstraction between Kubernetes and the container runtime called the Container Runtime Interface (CRI). CRI helps to use a wide variety of container runtimes without the need to recompile.
CRI-compliant runtimes are also OCI-compliant and therefore can run OCI-compliant images.
Before you can understand how to build OCI-compliant container images, you must first understand how the Open Container Initiative (OCI) relates to OpenShift.
The Open Container Initiative (OCI) was created to ensure that all container runtimes can run images produced by any build tool. OCI has published specifications for container image formats and for runtimes. Container images should comply with the OCI Image Format Specification so that they will be able to run in any container runtime that is compliant with the OCI Runtime Specification. The OCI does not replace Docker; the Docker Engine is OCI-compliant.
OpenShift Container Platform v4 has replaced the Docker container engine with CRI-O, which is a lightweight container engine focused on OCI-compatible runtimes and container images.
Migrate OCI-compliant images to OpenShift
To migrate your images to OpenShift, you need to make sure your container image is OCI-compliant so that it'll run in OCI-compliant container runtimes such as the one in CRI-O. To produce OCI-compliant images, use image build tools that produce OCI-compliant images. While you can use Docker to build images, the tools Buildah, Podman, and Skopeo help to build, run, and manage OCI-compliant images, independent of the container runtime.
Build images with no processes running with root access
By default, image build tools use root to build an image which will also run as root (where uid=0), unless the Dockerfile specifies a different user. By default, OpenShift runs containers using an arbitrarily assigned non-root user ID. An image that performs actions which succeed because the user is root, such as accessing files that cannot be accessed by other users, will not be able to perform these actions in OpenShift.
Example showing how root access affects processes
To show you how root access affects common processes, let's look at an example of deleting a file inside the root directory of a base operating system file system. The following example shows an Ubuntu OS.
The following Dockerfile has instructions to delete the /etc/passwd file (related to base OS ubuntu) which needs root user access.
When deploying the image on OpenShift using the oc new-app command you get these results:
You receive a warning message: Image "us.icr.io/test-namespace/root-app:v1" runs as the 'root' user which may not be permitted by your cluster administrator.
$ oc new-app us.icr.io/test-namespace/root-app:v1
--> Found Docker image 811f173 (46 hours old) from us.icr.io for "us.icr.io/ksoc/root-app:v10"
* An image stream tag will be created as "root-app:v10" that will track this image
* This image will be deployed in deployment config "root-app"
* The image does not expose any ports - if you want toload balance or send traffic to this component
you will need tocreate a service with'oc expose dc/root-app --port=[port]' later
* WARNING: Image "us.icr.io/test-namespace/root-app:v1" runs as the 'root'user which may not be permitted by your cluster administrator
--> Creating resources ...
deploymentconfig.apps.openshift.io "root-app" created
--> Success
Run 'oc status'toview your app.
Show more
The pod status is CrashLoopBackOff which shows that the container has crashed.
oc get pods
NAME READY STATUS RESTARTS AGE
root-app-1-lljqm 0/1 CrashLoopBackOff 15s
Show more
The pod log shows that the delete command failed to execute on OpenShift Container Platform because its default settings don't allow processes with root access to run inside an image.
$ oc logs root-app-1-lljqm
Starting Shell Script...
rm: cannot remove '/etc/passwd': Permission denied
shell.sh: 2: shell.sh: -> execution of rm command failed.: not found
Ending Shell Script...
Show more
How to address root access permissions during migration
Before migration, you need to assess whether your container image requires root access and modify the image not to run as root.
If the image does not require any root user access, the best practice is to specify a USER who is non-root in your Dockerfile as shown.
FROM <base-image>
..
..
USER <user-id>
..
..
CMD [.., ...]
If your application truly needs to perform root-access operations, follow the instructions in the SCC learning path, specifically RunAsAny in the section about access control.
Build images using Red Hat Universal Base Images (UBI)
As explained in "Design, build, and deploy universal application images," container images are made up of three main parts -- Linux libraries, language runtime, and application. These layers includes all the required language runtimes, interpreters, libraries, and your application.
Build an application image on a base image that already includes the Linux libraries and ideally the language runtime as well. Then you just need to add your application, which will run in the language runtime. Choosing the base image has a major impact on how secure, efficient, and upgradeable your container is in the future.
You can run images built on a variety of Linux distributions on OpenShift (similar to Kubernetes), but these images may have compatibility problems when run in OpenShift and will not be supported by Red Hat.
If you plan to create an image that will be deployed on OpenShift, and you want to maximize compatibility with the container host and have Red Hat support your image, you need to build your image from a Red Hat Universal Base Image (UBI). UBIs are supported by Red Hat, offer great security, performance and life cycles, and are listed in the Red Hat Container Catalog.
Integrated image registry or an external image registry
After building the image, you need to push the image to an image registry. An image registry is a content server that can store and serve container images. Kubernetes requires an external image registry. In Kubernetes, you can use any public image registry like Docker Hub or set up a private registry and access the images from there.
An OpenShift cluster includes an integrated image registry or you can use external image registries as well. Two advantages of the integrated image registry are that it is the default destination for images after they are built and includes image notification support. An advantage of an external registry is that multiple clusters can share the registry and therefore share its images.
For example, the command oc new-app makes use of the integrated image registry by default. It builds the image using a source code repository (in the case of s2i build), pushes the image into the integrated image registry, and deploys the app using the image.
Image registry considerations for migration
To migrate your workload from Kubernetes to OpenShift, you need to pick whether you want to use an external or internal registry.
If you decide to work with an external registry, you can use any OCI-compliant registry, such as the IBM Cloud Container Registry or the Quay registry. These provide many useful features out of the box like security scanning, high availability, and more. If the image registry is private, ensure that you have the required permissions to access it, usually configured in a pull secret. Otherwise, the pod will fail with an ImagePullBackOff status.
If your team does not already have an external image registry, then the integrated image registry is a quick way to get started. It gives you the ability to provision new image repositories on the fly and provides a great experience because of an entirely integrated computing environment.
Summary
This article highlights a few things to be aware of when you migrate your images from Kubernetes to OpenShift. If you are building new images to deploy on OpenShift, check out our learning path: Design, build, and deploy universal application images.
Conclusion
You have learned that if the container image is not OCI compliant or if it runs any process as a root user then the container image will not work on OpenShift. You need to take corrective actions as explained in the article. You should use UBI as the base image to achieve support from Red Hat. Also, you can plan to use the integrated image registry for your pre-production scenarios to get the benefit of its integration with OpenShift.
About cookies on this siteOur websites require some cookies to function properly (required). In addition, other cookies may be used with your consent to analyze site usage, improve the user experience and for advertising.For more information, please review your cookie preferences options. By visiting our website, you agree to our processing of information as described in IBM’sprivacy statement. To provide a smooth navigation, your cookie preferences will be shared across the IBM web domains listed here.