SpringBoot on Kubernetes with Helm Charts

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:

  1. Chart.yaml: This file contains metadata about the Helm chart, including the chart’s name, version, description, maintainers, and other relevant information.
  2. 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.
  3. 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

  1. Navigate to the helm-chart-demo/values.yaml file. This is where you can define variables that will be used throughout your chart.
  2. Update the image field to point to the Docker image you built earlier.
  3. 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:

helm chart spring boot

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:

helm chart spring boot tutorial

You should also be able to see that your Deployment now includes the ConfigMap:

helm chart install spring boot

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
Twitter Icon       Facebook Icon       LinkedIn Icon       Mastodon Icon