Kubernetes has become the de facto standard for container orchestration, allowing you to efficiently manage and scale containerized applications. Helm, on the other hand, is a powerful tool for simplifying the deployment of Kubernetes applications using packages called charts. In this article, we’ll walk through the process of deploying a Spring Boot application on an Enterprise Kubernetes such as OpenShift using Helm charts.
Step 1: Set up a sample Spring Boot application
The first step will be creating a minimal Spring Boot application with a REST Controller to show some environment variables. Across this tutorial, we will learn how to use a Kubernetes Component such as the ConfigMap to externalize the values of Environment Variables.
Here is our basic Spring Boot Controller:
import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloWorldController { @Value("${VAR1:default1}") private String var1; @Value("${VAR2:default2}") private String var2; @GetMapping("/ping") public String hello() { return "Hello world. Here are some variables: "+var1+ " - "+var2; } }
Then, we will create a Dockerfile to build a Container image of our Spring Boot application:
FROM adoptopenjdk/openjdk11:alpine-jre ADD ./target/demo-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java", "-jar","/app.jar"]
To learn more about Spring Boot with Docker check this article: Running a Spring Boot application with Docker
Let’s build the Spring Boot application first:
mvn install
Step 2: Build and Deploy the Container Image
Next, we will create the Image of our application:
docker build . -t helm-chart-demo-docker-img
After that, you should have an image tagged as “helm-chart-demo-docker-img” available in your local Docker Repository:
$ docker images helm-chart-demo-docker-img latest 9e84290218c8 2 minutes ago 168MB
Great. For the purpose of our example, we will push the Image on a Private Repository (quay.io) so that we can later access it from our OpenShift project or any other project. Therefore, let’s first login to the Private repository:
docker login quay.io
Enter your credentials and verify that login succeeds. Finally, let’s tag again our Docker image and push it to the Quay Respository:
docker tag helm-chart-demo-docker-img quay.io/fmarchio/demo && docker push quay.io/fmarchio/demo
Step 3: Create the Helm Chart
A Helm chart is a package of pre-configured Kubernetes resources that make it easier to deploy, manage, and maintain applications on a Kubernetes cluster. Think of it as a bundle that includes all the necessary files, templates, configurations, and metadata required to deploy a specific application or service onto Kubernetes. Helm charts enable you to define, version, and share complex application deployments as a single unit.
Here are the main components that make up a Helm chart:
- Chart.yaml: This file contains metadata about the Helm chart, including the chart’s name, version, description, maintainers, and other relevant information.
- values.yaml: This file defines configurable variables or parameters that can be used to customize the behavior of the chart. These values can be overridden when installing the chart, allowing for dynamic configuration.
- Templates: The heart of a Helm chart, these are YAML files that define the Kubernetes resources (such as Deployments, Services, ConfigMaps, etc.) required to run your application. These templates can reference the variables defined in
values.yaml
to create dynamic and customizable configurations.
To create the structure of an Helm Chart you can use the “helm create” command, followed by the chart name. For example:
helm create helm-chart-demo
Step 4: Customize the Helm Chart
- Navigate to the
helm-chart-demo/values.yaml
file. This is where you can define variables that will be used throughout your chart. - Update the
image
field to point to the Docker image you built earlier. - You can customize other values such as port numbers, environment variables, and resources as needed.
replicaCount: 1 image: pullPolicy: Always repository: quay.io/fmarchio/demo tag: latest service: type: NodePort port: 9899
The file Chart.yaml file contains some metadata information such as the Chart Name, description, Chart type and version:
apiVersion: v2 name: helm-chart-demo description: A Helm chart for Kubernetes type: application version: 0.1.0 appVersion: "1.16.0"
We will not go deep into the details of the template files which you can find in the source code of this article (see end of the article).
Step 5: Deploy and Test the chart
Since we will deploy this example on OpenShift, let’s create a new project for it:
oc new-project spring-demo
Next, since our Helm Chart will fetch Images from a Private Repository (Quaty.io) we will need to add permissions to pull images from that Repository. We will create a secret from the local config.json file and link it to the secret:
oc create secret generic quay.io --from-file=.dockerconfigjson=~/.docker/config.json --type=kubernetes.io/dockerconfigjson oc secrets link default quay.io --for=pull
Then, we will install the Helm Chart with the “helm install” command, passing as argument the Chart Name and the Directory where the YAML files are located:
helm install helm-chart-demo ./helm-chart-demo
You should be able to see the following message:
NAME: helm-chart-demo LAST DEPLOYED: Wed Aug 16 15:03:30 2023 NAMESPACE: spring-demo STATUS: deployed REVISION: 1 TEST SUITE: Non
Finally, expose the Service with a Route:
oc expose svc helm-chart-demo
Check that the Pod is running, for example from the Web Console you should see:
You can now test the Spring Boot Controller with:
curl helm-chart-demo-spring-demo.apps-crc.testing/ping
As a result, you should be able to see
Hello world. Here are some variables: default1 - default2
Step 6: Externalizing the Configuration
Finally, we will show how to modify the deployment.yaml file so that Environment Variables are taken from a ConfigMap. To do that, modify the deployment.yaml file so that it fetches Variables from a ConfigMap named “my-config”:
apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "helm-chart-demo.fullname" . }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app: helm-chart-demo template: metadata: labels: app: helm-chart-demo spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - containerPort: 9899 envFrom: - configMapRef: name: my-config
Next, you can either create the ConfigMap from the command line or add a file in the templates directory. For example, add the file my-config.yaml
apiVersion: v1 kind: ConfigMap metadata: name: my-config data: VAR1: value1 VAR2: value2
The beauty of Helm is that you don’t need an image rebuild but just an “helm upgrade” so that a new Deploy will be available:
helm upgrade helm-chart-demo helm-chart-demo
You should be able to see that the Helm Chart has been upgraded:
You should also be able to see that your Deployment now includes the ConfigMap:
Now, by requesting again the REST Endpoint, you will see the variables from the ConfigMap as response:
curl helm-chart-demo-spring-demo.apps-crc.testing/ping Hello world. Here are some variables: value1 - value2
Conclusion
Deploying a Spring Boot application on Kubernetes using Helm charts streamlines the deployment process and ensures consistency across different environments. By following the steps outlined in this article, you’ll be able to package your Spring Boot application into a Docker container, create a Helm chart to define Kubernetes resources, and deploy your application with ease. As your application evolves, you can update your Helm chart to reflect changes and maintain a smooth deployment process.
Source code: https://github.com/fmarchioni/masterspringboot/tree/master/helm/helm-spring-boot
Found the article helpful? if so please follow us on Socials