Wouldn’t it be cool if OpenShift provided an out-of-the-box way to build and deploy Quarkus applications? Red Hat has provided just that in the form of a Quarkus Helm chart. This Helm chart makes it easy to build and deploy Quarkus applications in OpenShift. In this post, let’s review the Quarkus Helm Chart, why it’s needed, and why it’s valuable.
The Quarkus Helm chart was front and center in a session presented with Austin Dewey and Andy Block on a prior OpenShift Commons livestream. Here is the link to the recording if you’re interested in watching.
Now, let’s begin the discussion by reviewing the Quarkus run modes and describing some of the skills required to build and deploy a Quarkus application in OpenShift.
The Quarkus Run Modes and Challenges Involved
You’re likely familiar with Quarkus, but to recap, Quarkus is a Kubernetes-native Java stack by Red Hat. It boasts a lower memory (RSS) usage and faster startup times than other cloud-native stacks. (See the Quarkus homepage for more information.)
Quarkus has two different run modes: JVM (Java Virtual Machine) and Native. Most Java developers know the JVM mode. To run in this mode, you compile your Quarkus application down to bytecode and run it on top of a JVM, similar to running more traditional Java workloads, using build tools like Maven and Gradle. The other run mode is Native, less familiar to most Java developers. Running a Quarkus application in Native mode means the application is compiled to a native binary, similar to compiling a C or Golang program, using GraalVM or Mandrel.
The decision to run Quarkus in JVM or Native mode depends on your requirements. JVM mode tends to have higher throughput, while Native mode generally has a lower memory requirement and almost instantaneous startup time. You can learn more about Quarkus' run modes and benchmarks from the Quarkus Runtime Performance blog post.
While the Quarkus run modes offer runtime flexibility, they can increase the complexity of building and deploying a Quarkus app in OpenShift. First, you need to know how to properly configure your build, achieved in OpenShift using a BuildConfig. Second, the JVM and Native modes will each warrant a different configuration using tools like Source-to-Image or a Dockerfile. Beyond the build, you also need to think about the steps involved in deploying your Quarkus application and which OpenShift resources you will use.
Luckily, using Helm, many of the considerations discussed can be abstracted to provide a more streamlined developer experience.
Helm to the Rescue!
Helm is known as the “Kubernetes Package Manager.” Similar to how a traditional package manager is used to install software to your OS, Helm works the same way by installing software to Kubernetes/OpenShift. Using Helm, you can install a Quarkus application using the simple command, “helm install”!
Helm accomplishes this by serving as a wrapper around all of the application’s required resources. This wrapper is called a “Chart” and is created and maintained by a Chart maintainer.
Helm serves as a wrapper around k8s/OCP resources
Users can customize their installation by passing in parameters to the chart called “values.” Values are YAML-formatted, so it’s common for users to create a YAML values file and pass it in using the “--values” flag of the “helm install” command. An example values file might appear similar to the following:
Then, the user can install the chart by running the “helm install” command. Here is an example invocation:
helm install quarkus-app redhat-charts/quarkus --values my-values.yaml
This command would install a variety of OpenShift resources, and the only work that you, as the user, would have needed to do is write your values file and run the “helm install” command. Sound easy? Well, then read on to learn about how the Quarkus Helm chart can make building and deploying Quarkus applications in OpenShift, or another Kubernetes environment, a breeze.
The Quarkus Helm Chart
The goal of the Quarkus Helm Chart is simple: configure as much out of the box as possible to provide a seamless user experience. This chart has several best practices and Quarkus-isms baked in, so all you need to do is install the chart, configure values as needed, and away you go! Let's look at some of the features this chart provides to improve the developer experience around Quarkus.
JVM and Native Modes
The Quarkus Helm Chart allows you to build Quarkus applications easily in both JVM and Native modes. Simply set the build.mode value to either "jvm" or "native", and the Helm chart will take care of the rest.
If you set build.mode to "jvm", the chart will generate an s2i build, using the java:11 builder that comes included with OpenShift. If you choose "native", the Helm chart will generate a Docker build and provide an inline Dockerfile. You can override the s2i builder or the Dockerfile if the defaults do not support your requirements.
Externalized Application Properties
Another feature of the Quarkus Helm Chart is that it allows you to externalize your “application.properties” file into a ConfigMap. Externalizing application properties is important because if you leave them in the default location (src/main/resources), you will need to recompile your application whenever they are changed. It's common when deploying across environments to make slight modifications to your properties (such as url’s, usernames, and passwords for databases). The externalized application properties feature lets you easily extract those properties into a ConfigMap so that you can use the same image across each of your environments.
Here’s an example of configuring this feature in your values file:
If you ran "helm install" against this configuration, Helm would create a ConfigMap with the contents found in the deploy.applicationProperties.properties value. It would also mount your application.properties file under the /deployments/config/directory.
ConfigChange and ImageChange Triggers
The Quarkus Helm chart comes with ConfigChange and ImageChange triggers already baked in. Having these triggers included means that, as soon as you run "helm install," your build will automatically start, and after a short while, your new pods will automatically roll out once the build finishes. These triggers make building and deploying a primarily hands-off process. Just run "helm install" and wait for the end-to-end process to complete!
One goal of writing this Helm chart was to allow users to add additional configuration, such as:
- Environment variables
- Init and sidecar containers
- Liveness and readiness probes
- Volumes and volume mounts
You can configure each of these items in your values file as freeform fields that resemble their full Kubernetes spec. As an example, here is how you can configure a sidecar container in your values file:
- name: my-extra-container
command: ["sleep", "infinity"]
Some of these, such as ports and readiness and liveness probes, have defaults, but you can easily override these in your values file.
Now that you know more about the features included, let’s take a peek at what the Quarkus Helm Chart installs for you in your OpenShift environment.
The End Result
The result of the Quarkus Helm chart is, in its current iteration, the creation of six different OpenShift resources:
- BuildConfig (Optional)
- ImageStream (Optional)
- ConfigMap (Optional)
- Route (Optional)
The BuildConfig and ImageStream are for building your application and pushing it to the internal registry (unless you already have a Quarkus image you want to use, in which case you can set build.enabled to false and skip the creation of these resources). The rest of the resources facilitate the deployment of your application. The Quarkus Helm Chart will always create a Deployment and a Service for you; however, a ConfigMap will only be created if deploy.applicationProperties.enabled is true, and a Route will only be created if deploy.route.enabled is true.
It's worth pointing out that if build.enabled is true, you only need to configure a single value in your values file to have Helm build and deploy your own application:
Of course, you can provide more values if you need to configure your application further, but this is all you need at a minimum to get started.
Now, let's take a quick look at how you can install the chart in OpenShift.
Installing the Quarkus Chart
The traditional way of installing the Quarkus Helm Chart is through the Helm CLI. In this case, you’ll add the Red Hat Developers Helm Chart Repository using the “helm repo add” command:
helm repo add redhat-charts https://redhat-developer.github.io/redhat-helm-charts/index.yaml
Then, after creating your values file, install the chart by running the “helm install” command:
helm install quarkus-app redhat-charts/quarkus --values values.yaml
You can also install the chart by leveraging the built-in Helm support in the OpenShift Console in the Developer Perspective. In this case, the Red Hat Helm Chart Repository is already configured, so you don't have to worry about adding it. All you need to do when installing through the console is click “Add” on the left hand navigation bar, and then select "Helm Chart":
Select “Helm Chart” from the developer perspective
The list of available Helm charts will be displayed. Locate and select the Quarkus Helm chart. Finally, you can configure your values from the UI and install from there!
Configuring Quarkus values from the OpenShift UI
Thanks for Reading
This Helm chart can be useful to all Quarkus developers out there. For more information, such as the supported chart values, please refer to the chart's documentation. Additionally, if you have any questions, found a bug, or have additional thoughts or ideas, we would love to hear from you. Submit an issue on the GitHub repository or interact with the Helm on Red Hat OpenShift team by sending an email to firstname.lastname@example.org.
How-tos, Java, helm, configuration, Quarkus, ci/cd