477 words
2 minutes
Expose spring boot microservice with ingress using helm

Introduction#

In k8s deployment, ingress exposes HTTP and HTTPS routes from outside the cluster to services within the cluster.

In this article, I will take you through how to expose spring boot microservice for the outside world in k8s deployment using ingress.

This example needs kubectl minikube helm command-line tools in your machine.

Simple Spring Boot Microservice#

Let’s create one simple spring boot microservice that just returns the given name.

Initialize Project#

NAME='Expose spring boot microservice with ingress using helm' && PRJ=expose-spring-boot-microservice-with-ingress-using-helm && \
mkdir -p $PRJ && cd $PRJ && \
curl https://start.spring.io/starter.tgz \
    -d dependencies=actuator,webflux \
    -d groupId=io.github.bhuwanupadhyay -d artifactId=$PRJ -d packageName=io.github.bhuwanupadhyay.example \
    -d applicationName=Spring Boot -d name=$NAME -d description=$NAME \
    -d language=kotlin -d platformVersion=2.3.1.RELEASE -d javaVersion=11 \
    -o demo.tgz && \
    tar -xzvf demo.tgz && rm -rf demo.tgz

Simple API to return given name#

@Configuration
class NameRoutes(private val handler: NameHandler) {

    @Bean
    fun router() = router {
        accept(APPLICATION_JSON).nest {
            GET("/names/{given-name}", handler::findGivenName)
        }
    }
}

Containerizing Spring Boot Application#

From Spring Boot 2.3.0.RELEASE the maven plugin of spring boot by default support build-image goal during execution which creates an OCI image using Cloud Native Buildpacks.

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
  <executions>
   <execution>
     <goals>
      <goal>build-image</goal>
     </goals>
     <configuration>
      <imageName>docker.io/bhuwanupadhyay/${project.artifactId}:${project.version}</imageName>
     </configuration>
   </execution>
  </executions>
</plugin>

Run mvn clean install : spring boot maven plugin will create a docker image. The end part of the output log:

[INFO]
[INFO] Successfully built image 'docker.io/bhuwanupadhyay/expose-spring-boot-microservice-with-ingress-using-helm:0.0.1-SNAPSHOT'
[INFO]

To publish docker image in a registry run the following command

docker push docker.io/bhuwanupadhyay/expose-spring-boot-microservice-with-ingress-using-helm:0.0.1-SNAPSHOT

Helm Chart#

To create a helm chart from your project directory run the following command.

helm create src/microservice

Replace value image repository and tag with your published docker image name and tag in src/microservice/values.yaml inside a helm chart.

image:
  repository: docker.io/bhuwanupadhyay/expose-spring-boot-microservice-with-ingress-using-helm
  pullPolicy: IfNotPresent
  tag: '0.0.1-SNAPSHOT'

In your helm chart under src/microservice/templates/deployment.yaml change readinessProbe and livenessProbe health check settings, also modify container port to 8080 is the default for spring boot application.

ports:
  - name: http
    containerPort: 8080
    protocol: TCP
livenessProbe:
  httpGet:
    path: /actuator/health
    port: http
  initialDelaySeconds: 30
  periodSeconds: 60
  timeoutSeconds: 5
  failureThreshold: 5
readinessProbe:
  httpGet:
    path: /actuator/health
    port: http
  initialDelaySeconds: 30
  periodSeconds: 5
  timeoutSeconds: 5
  failureThreshold: 5

Enable Ingress in Helm#

Simply modify file src/microservice/values.yaml accordingly.

ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  hosts:
    - host: microservice.minikube
      paths:
        - '/'

Deployment#

Get ready for the deployment!

Start Minikube and Enable ingress#

minikube start

Minikube enable addons ingress and ingress-dns in#

minikube addons enable ingress
minikube addons enable ingress-dns

Helm deployment#

helm upgrade \
    --install -f src/microservice/values.yaml \
    example-deployment src/microservice --force

Watch the deployment and ingress#

watch kubectl get pods

Modify /etc/hosts to add your host#

# Know your host and address -> Run the following command
kubectl get ingress
# Output
NAME                              CLASS    HOSTS                   ADDRESS      PORTS   AGE
example-deployment-microservice   <none>   microservice.minikube   172.17.0.2   80      63m
# Add your host -> Run the following command
sudo sed -i "$ a 172.17.0.2 microservice.minikube" /etc/hosts

Test Microservice APIS#

Firstly, install httpie command line tool.

sudo apt install httpie

Open New Terminal - Call microservice APIS

# GET given name
http http://microservice.minikube/names/k8sname
# Output
{
    "givenName": "k8sname"
}

We are done ! Thanks for reading. Github

References#

Expose spring boot microservice with ingress using helm
https://semusings.dev/posts/2020/2020-06-17-expose-spring-boot-microservice-with-ingress-using-helm/
Author
Bhuwan Prasad Upadhyay
Published at
2020-06-17