A Java runtime environment should be able to run a compiled source code while a development kit, such as a development kit, is running. OpenJDK contains all libraries/binaries to compile and run the source code. The latter is essentially a superset of the runtime environment. More details on OpenJDK support and lifecycle can be found here here,
Red Hat comes with Java OpenJDK 8 and 11 and includes media container images. More details can be found at here, If you use Red Hat middleware, the s2i images are also useful for deploying them to the Red Hat Openshift Container Platform, for example.
Note that Red Hat only provides OpenJDK-based Java 8 and 11 images. With that in mind, there will certainly be situations where developers want to build their own Java runtime images. For example, there could be such minimization of memory for the runtime image. Jolokio or Hawkular and even security parameters would also need to be set up. If you do not want to go into these details, I would recommend using the Red Hat container for OpenJDK.
In this article we will:
- Create an image with Docker and Buildah.
- We will be running on the localhost with Docker and Podman.
- We will pass on our image to Quay.
- Finally, we will have a problem Open Shift,
This article was written for OpenShift 3.11 and 4.0 Beta. Let’s get started right away.
Set up
To use our images and see how they work, we use a web app as part of our bundle. Recently, Microprofile.io has the MicroProfile Starter Beta to help you get started with MicroProfile by creating a downloadable package. Go out Microprofile.io and get the package for MicroProfile with Thorntail V2.
Click the Download button to retrieve the archive file.
On my Red Hat Enterprise Linux (RHEL) computer, I first create a temporary directory, for example: demoapp
and de-archive the downloaded artifacts.
In my temporary directory, I do the following:
$ mvn clean compile package
Now we should have a demo app with a fat glass that we can call to run Thorntail.
Let’s copy that target/demo-thorntail.jar
in the temporary directory.
Here is the Dockerfile
with comments on each shift. The source code of this file can be found here GitHub.
# A Java 8 runtime example # The official Red Hat registry and the base image FROM registry.access.redhat.com/rhel7-minimal USER root # Install Java runtime RUN microdnf --enablerepo=rhel-7-server-rpms install java-1.8.0-openjdk --nodocs ; microdnf clean all # Set the JAVA_HOME variable to make it clear where Java is located ENV JAVA_HOME /etc/alternatives/jre # Dir for my app RUN mkdir -p /app # Expose port to listen to EXPOSE 8080 # Copy the MicroProfile starter app COPY demo-thorntail.jar /app/ # Copy the script from the source; run-java.sh has specific parameters to run a Thorntail app from the command line in a container. More on the script can be found at https://github.com/sshaaf/rhel7-jre-image/blob/master/run-java.sh COPY run-java.sh /app/ # Setting up permissions for the script to run RUN chmod 755 /app/run-java.sh # Finally, run the script CMD ( "/app/run-java.sh" )
Now we have the Dockerfile
Details, let us continue and build the picture.
An important point is that the Java OpenJDK runtime is packaged as “java-1.8.0-openjdk”. This does not include the compiler and others -devel
Package.
The above Dockerfile
based on RHEL, which means subscription-manager
because the host has already attached the subscriptions.
Here are two ways to do it. If you run RHEL as I do, you can choose from the two binary files that will be deployed. Both should be there rhel7-server-extras-rpms
,
You can activate this extras
repo as follows:
# subscription-manager repos --enable rhel-7-server-extras-rpms
Create and run pictures locally
Create the image with docker
:
$ docker build -t quay.io/sshaaf/rhel7-jre8-mpdemo:latest .
Start the picture with docker
and localhost: 8080 points to container port 8080:
$ docker run -d -t -p 8080:8080 -i quay.io/sshaaf/rhel7-jre8-mpdemo:latest
We can also do that buildah Command used to create container images from a working container Dockerfile
Gold from scratch. The resulting images are OCI compliant, so they can be used for any runtime that matches them OCI runtime specification (like Docker and CRI-O).
Build with buildah
:
$ buildah bud -t rhel7-jre8-mpdemo .
Create a container with buildah
:
$ buildah from rhel7-jre8-mpdemo
Now we can operate the container with Podman, which complements Buildah and Skopeo with a similar experience to the Docker command line: Allow users to run stand-alone (uncontrolled) containers. And Podman does not need a daemon to run containers and pods. Podman is also part of extras
channel and the following command should execute the container.
$ podman run -d -t -p 8080:8080 -i quay.io/sshaaf/rhel7-jre8-mpdemo:latest
For more information about Podman, see Containers without daemons: Podman and Buildah in RHEL 7.6 and RHEL 8 Beta, and Podman and Buildah for Docker users.
After we have an image, we want to deploy it on OpenShift and test our app. For that, we need the oc
Client libraries. I have my own cluster setup. You could choose to use the Red Hat Container Development Kit (CDK) / minishift Red Hat OpenShift Online or your own cluster. The procedure should be the same.
Deploy on OpenShift
For deployment in OpenShift, we need the following constructs:
- An image stream for our newly created image container
- Deployment configuration for OpenShift
- Service and routing configurations
Image data stream
To create the image stream, the OpenShift Cluster should be able to retrieve the container image from somewhere. So far, the image was on my own computer. Let us push it quay, The Red Hat Quay Container and the Red Hat Quay application enable secure storage, distribution, and provision of containers in every infrastructure. It is available as a stand-alone component or in conjunction with OpenShift.
First, I have to sign in to Quay, which I can do as follows:
$ docker login -u="sshaaf" -p="XXXX" quay.io
And then we push our newly created image to Quay:
$ docker push quay.io/sshaaf/rhel7-jre8-mpdemo
Let’s take a look at the constructs before we deploy them. For the timid, you can skip the details in the deployment template and move on to the project creator.
Now we have the picture, we define our stream:
- apiVersion: v1 kind: ImageStream metadata: name: rhel7-jre8-mpdemo spec: dockerImageRepository: quay.io/sshaaf/rhel7-jre8-mpdemo
Again, you can see our point of view directly in our image archive on Quay.io.
Deployment Configuration
Next is the deployment configuration that sets up our pods and triggers, pointing to our newly created stream, and so on.
If you are unfamiliar with containers and OpenShift deployments, you should consult them ebook,
- apiVersion: v1 kind: DeploymentConfig metadata: name: rhel7-jre8-mpdemo spec: template: metadata: labels: name: rhel7-jre8-mpdemo spec: containers: - image: quay.io/sshaaf/rhel7-jre8-mpdemo:latest name: rhel7-jre8-mpdemo ports: - containerPort: 8080 protocol: TCP replicas: 1 triggers: - type: ConfigChange - imageChangeParams: automatic: true containerNames: - rhel7-jre8-mpdemo from: kind: ImageStreamTag name: rhel7-jre8-mpdemo:latest type: ImageChange
The service
Now that we have the deployment, we also want to define a service that ensures internal load balancing, IP addresses for pods, and so on. Service is important if our newly created app should finally be exposed to other traffic.
- apiVersion: v1 kind: Service metadata: name: rhel7-jre8-mpdemo spec: ports: - name: 8080-tcp port: 8080 protocol: TCP targetPort: 8080 selector: deploymentconfig: rhel7-jre8-mpdemo
The street
And the last part of our mission is the road. It’s time we took the road to the outside world. We can define which internal service this route refers to. OpenShift helps you make the most of your Java 8 runtime deployment.
- apiVersion: v1 kind: Route metadata: name: rhel7-jre8-mpdemo spec: port: targetPort: 8080-tcp to: kind: Service name: rhel7-jre8-mpdemo weight: 100
The full template for the above can be found here on GitHub,
Let’s also create a project in OpenShift as follows:
$ oc new-project jredemos
And now we have the Java 8 runtime on OpenShift. To do this, run the following command:
$ oc process -f deployment.yaml | oc create -f -
This will create the entire deployment, and you should be able to see it:
Now execute the following command:
$ oc get routes
This shows the routes as follows:
Let’s copy the road to our browser and we should see that the web app is running on RHEL 7 with the Java 8 runtime. (The following address is specific to the cluster test and will be another cluster.)
http://rhel7-jre8-mpdemo-jredemos.apps.cluster-1fda.1fda.openshiftworkshop.com/
Summary
We have successfully created a Java 8 runtime container image with Docker or Buildah. Please pay attention to the following:
- It is important to note that this picture shows how it can be done; It does not contain things like Jolokio or Hawkular that might be required for deployments.
- In addition, the parameters required to run Java apps in containers are not taken into account, which is well explained in this article by Rafael Benevides.
- Also, always consider the support and lifecycle policy when deploying your own container images hereIf you are running Red Hat’s build from OpenJDK.
We then provided this with our basic MicroProfile demo app from OpenShift MicroProfile Starter Beta,
If you want to build a more complete demo application, consider the following resources:
The full resources for this article can be found here here,