Dhananjay.blog

Recipes for Java, Golang on Kubernetes and more.

Menu
  • Home
  • About
Menu

SpringBoot and Helm on Kubernetes

Posted on August 6, 2022

SpringBoot is an opinionated way of building Java applications using SpringBoot framework. Helm is the package manager for Kubernetes an orchestration platform for running containers.

In this article, we will go through building a spring application along with helm charts to run on Kubernetes. This post also elaborates on how to use Helm in SpringBoot application as mentioned in this post.

Pre-Requisites

Please make sure you have the following setup before proceeding :

  1. helm
  2. A Kubernetes flavor is accessible, it can either be a local setup via Minikube, Docker Desktop, or even a cloud-based setup using GKE or EKS. This article will mostly focus on using Docker Desktop to demonstrate, but the configuration and the setup should stay the same across all Kubernetes flavors.
  3. IDE for ease of use. This tutorial uses IntelliJ IDEA to demonstrate.
  4. kubectl CLI .
  5. gradle

1. Generate SpringBoot Application

We will create a sample spring boot application using Spring initializer. Intellij has a nice feature to generate within the IDE which can also be used instead of using the CLI interface. Another alternative is to use the Eclipse STS version which should have this plugin to generate spring applications using Spring initializer.

If you would rather skip the creation part just use the recipe from Spring Initializer to create a starter project.

Then click on Generate, this will create the project and download it as zip file
unzip spring-sample-app.zip && cd spring-sample-app/ and replace build.gradle file with the following content

plugins {
    id 'io.spring.dependency-management' version '1.0.12.RELEASE'
    id 'java'
    id 'com.google.cloud.tools.jib' version '3.2.1'
    id 'idea'
}
group = 'com.example'
version = '0.1'
sourceCompatibility = 1.8
repositories {
    mavenCentral()
}
dependencies {
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-actuator', version: '2.6.3'
    implementation 'org.springframework.boot:spring-boot-starter-web:2.6.3'
    testImplementation 'org.springframework.boot:spring-boot-starter-test:2.6.3'
}
tasks.named('test') {
    useJUnitPlatform()
}

Once done, from within the folder at the same level run the following command, this will generate all the configuration files and launch Intellij IDE
gradle openIdea
Click on Load Gradle project which will start downloading all dependencies.

2. Configure SpringBoot Application

Next, Create the following files in the src directory
com/example/springsampleapp/WebResource.java

package com.example.springsampleapp;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WebResource {
    private AppConfig appConfig;
    public WebResource(AppConfig appConfig){
        this.appConfig = appConfig;
    }
    @GetMapping(value = "/propertyValues")
    public @ResponseBody String getPropertyValues(){
        return String.format("Timeout=%s, Message=%s",appConfig.getTimeout(),appConfig.getMessage());
    }
}

com/example/springsampleapp/AppConfig.java

package com.example.springsampleapp;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "app")
public class AppConfig {
    private String timeout;
    private String message;
    public String getTimeout() {
        return timeout;
    }
    public void setTimeout(String timeout) {
        this.timeout = timeout;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

Add the following within configmap-reload/src/main/resources/application.properties

app.timeout=1000
app.message=Base Message from the app

Right click on SpringSampleApplication and Click Run

It should then publish an API that returns property values: http://localhost:8080/propertyValues

You can now stop the application.

3. Create Image and Push to Local Docker Registry

This step creates the image of the spring boot application using Google Cloud Tools Jib, which enables you to push to any docker complaint repository without the need for installing docker itself.

Now run let’s create and push the image to the local docker registry, first make sure Docker is running locally and you can pull images. Start Docker Desktop or Minikube before running this command:
docker image ls
The above command should pull images from your local machine or show empty if nothing is installed.

From the root directory of the spring-sample-app run the Gradle command to push the image to the local registry
./gradlew jibDockerBuild
docker image ls | grep configmap-reload

which should give the following output:
configmap-reload 0.0.1-SNAPSHOT 25084953eada

You have now successfully created the application image and upload it to your local docker registry on your computer. Jib is a very powerful tool and can be used for pushing images to many public repositories such as Docker Hub, Amazon ECR, and Google Cloud Repository. Refer to the Jibs documentation for more details.

4. Create and Configure Helm Chart

The next step is to create a helm chart for the above application, you just need to make sure you have helm installed and then follow along.

First, let’s create a template chart, the location of the chart can be any directory in your machine, in this example, it is inside the spring-sample-app/helm directory

cd spring-sample-app/helm && helm create spring-sample-app

Now let’s make changes to the values.yaml file for the helm chart to load your application in local k8s. Change the following:

values.yaml file, change the repo name

image:
repository: spring-sample-app

Also, change the Service Type from ClusterIP to LoadBalancer, this will enable accessing your service as a localhost URL.

service:
  type: LoadBalancer

chart.yaml , change the appVersion

appVersion: 0.1

Change the container port from 80 to 8080 within deployment.yamlas that’s the port our spring boot application is configured with by default. Also, change the Liveness and Readiness Probes, these are required by Kubernetes to know if the application is healthy and ready to serve requests.

          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /actuator/health
              port: http
          readinessProbe:
            httpGet:
              path: /actuator/health
              port: http

5. Deploy on Local Kubernetes

We are all set to run, navigate within the helm directory and install the chart
cd spring-sample-app/helm && helm install spring-sample-app spring-sample-app/

Output:

NAME: spring-sample-app
LAST DEPLOYED: Fri Aug  5 22:21:08 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
           You can watch the status of by running 'kubectl get --namespace default svc -w spring-sample-app'
  export SERVICE_IP=$(kubectl get svc --namespace default spring-sample-app --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
  echo http://$SERVICE_IP:80

Ensure that the pod started successfully and the service is live

kubectl get pods

NAME                                 READY   STATUS    RESTARTS   AGE
spring-sample-app-86bfdb9754-xffkq   1/1     Running   0          18s

kubectl get services

NAME                TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
spring-sample-app   LoadBalancer   10.101.153.142   localhost     80:31381/TCP   56s

The application is running within Kubernetes as a service and should be available at http://localhost/propertyValues

6. Troubleshooting

  • If something goes wrong in helm and you want to start over just delete the chart by running helm delete spring-sample-app
  • YAML is very sensitive to indentation, so please ensure that the indentation is proper
  • Java 17 version at the time of writing this article was not compatible with the latest version of SpringBoot, so ensure you don’t change the spring boot version to a higher than 2.6.3
  • if all else fails you can still download the code from the GitHub repo and try comparing it with your setup

7. Further Reading

  • Kubernetes Documentation
  • Helm Documentation

Categories

  • GO
  • Home
  • Java
  • K8s and More
  • Programming
  • Software

Tags

Container Image Docker gingonic go helm jib kafka kubernetes microservices springboot spring cloud config tdd test driven development unit testing

Recent Posts

  • Unit Testing Checklist
  • ConfigMap Custom Watcher with SpringBoot
  • Go Service Configuration with k8s ConfigMaps
  • Go MicroService in Gin using Helm On k8s
  • Container Image Reducing Size with Jib

Archives

  • March 2025
  • January 2023
  • December 2022
  • September 2022
  • August 2022

Categories

  • GO
  • Home
  • Java
  • K8s and More
  • Programming
  • Software

About

  • Privacy
  • Terms of Service
  • About
  • Contact
@2024 Dhananajay on Tech