Sunday, November 12, 2023

Deploying Spring Boot Apps Locally with Skaffold, Helm and Docker for Kubernetes

Introduction:

In the ever-evolving landscape of software development and deployment, the integration of Spring Boot,Skaffold, Helm, Docker, and local Kubernetes enviroment has become a powerful combination for building scalable and containerized applications.




Skaffold: Automating Kubernetes Development Workflows

Skaffold is a powerful command-line tool designed to streamline the development and deployment workflows for Kubernetes applications. It acts as the orchestrator, automating tasks such as building container images, deploying to Kubernetes clusters, and monitoring code changes in real-time.

Helm: Simplifying Kubernetes Application Management


Helm is a package manager for Kubernetes applications, making it easier to define, install, and upgrade applications. Helm uses charts, which encapsulate pre-configured Kubernetes resources, allowing developers to share and deploy applications with ease.

Kubernetes: The Backbone of Container Orchestration


Kubernetes is an open-source container orchestration platform that automates the deployment, scaling, and management of containerized applications. It provides a robust framework for running and coordinating applications in a distributed environment.

Docker Desktop: Localized Development Environment for Containers


Docker Desktop is an application that simplifies the development and deployment of containerized applications. It includes a local Kubernetes cluster, providing developers with a consistent environment for building, testing, and deploying containers.

Prerequisites

Before we dive into the world of streamlined Spring Boot development with Skaffold, Helm, Docker, and Kubernetes, ensure you have the following prerequisites installed on your machine:

Skaffold:

Follow the official Skaffold installation guide based on your operating system: Skaffold Installation Guide.

Helm:

Install Helm by following the Helm installation instructions: Helm Installation Guide.

Kubernetes:

Choose one of the following options based on your preference:

Docker Desktop:

Install Docker Desktop, which includes Kubernetes support. Download it from the official Docker website: Docker Desktop.

Minikube:

If you prefer using Minikube, follow the installation instructions: Minikube Installation Guide.

Ingress-Nginx Controller:


Install the Ingress-Nginx Controller for routing external HTTP/S traffic to services in the Kubernetes cluster. Use one of the following methods:

Using kubectl:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.41.2/deploy/static/provider/cloud/deploy.yaml
Using helm:

helm install --namespace default nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginxSpring Boot 3:

For more details, refer to the official Ingress-Nginx deployment guide: Ingress-Nginx Deployment Guide.

If still not work after install then stop and start Docker Desktop Kubernetes.

Directory etc/folder:


Adding the IP-to-hostname mapping in /etc/hosts: in this post
127.0.0.1       myapp.local

Spring Boot 3:

Create a Spring Boot 3 application. 

Environment Setup

Helm Version:

helm version
version.BuildInfo{Version:"v3.13.0", GitCommit:"825e86f6a7a38cef1112bfa606e4127a706749b1", GitTreeState:"clean", GoVersion:"go1.20.8"}
Skaffold Version:

skaffold version
v2.9.0
Kubernetes Nodes:

kubectl get nodes
NAME             STATUS   ROLES           AGE    VERSION
docker-desktop   Ready    control-plane   7d4h   v1.28.2


Project Structure: 


skaffold-dockerfile-demo
|-- myapp-chart
|   |-- templates
|   |   |-- deployment.yaml
|   |   |-- ingress.yaml
|   |   |-- service.yaml
|   |-- Chart.yaml
|   |-- values.yaml
|-- Dockerfile
|-- skaffold.yaml
|-- src
|-- ...

myapp-chart:

This directory encapsulates the Helm chart for your application. Helm charts provide a way to package, distribute, and manage Kubernetes applications.

templates: Contains YAML templates for Kubernetes resources like Deployment, Ingress, and Service.
  • deployment.yaml: Defines the deployment configuration for your Spring Boot application.
  • apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: {{ .Chart.Name }}
    spec:
      replicas: {{ .Values.replicaCount }}
      selector:
        matchLabels:
          app: {{ .Chart.Name }}
      template:
        metadata:
          labels:
            app: {{ .Chart.Name }}
        spec:
          containers:
            - name: {{ .Chart.Name }}
              image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
              ports:
                - name: http
                  containerPort: {{ .Values.service.port }}
  • ingress.yaml: Configures the Ingress resource for routing external traffic.
  • apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: {{ .Chart.Name }}-ingress
    spec:
      defaultBackend:
        service:
          name: {{ .Chart.Name }}-service
          port:
            number: {{ .Values.service.port }}
      ingressClassName: nginx
      rules:
        - host: myapp.local
          http:
            paths:
              - pathType: Prefix
                backend:
                  service:
                    name: {{ .Chart.Name }}-service
                    port:
                      number: {{ .Values.service.port }}
                path: /
  • service.yaml: Specifies the Kubernetes Service for your application.
  • apiVersion: v1
    kind: Service
    metadata:
      name: {{ .Chart.Name }}-service
    spec:
      ports:
        - name: http-web
          port: {{ .Values.service.port }}
          protocol: TCP
          #targetPort: 8080
          nodePort: 30090
      selector:
        app: {{ .Chart.Name }}
      type: NodePort
      #type: LoadBalancer
Chart.yaml: Describes the metadata and configuration of the Helm chart.

apiVersion: v2
name: myapp
description: A Helm chart for my Spring Boot application
version: 1.0.0
appVersion: 1.0.0

values.yaml: Contains default configuration values for your Helm chart.

replicaCount: 1

image:
  repository: skaffold-demo-docker
  tag: latest

service:
  port: 8080

ingress:
  enabled: true


Dockerfile: Check the reference help me for created Dockerfile 

This file instructs Docker on how to build the Docker image for your Spring Boot application.
FROM eclipse-temurin:17-jdk-focal

WORKDIR /app

COPY .mvn/ .mvn
COPY mvnw pom.xml ./
RUN ./mvnw dependency:go-offline

COPY src ./src

CMD ["./mvnw", "spring-boot:run"]


skaffold.yaml:

Skaffold configuration file that automates the development workflow. It defines how to build and deploy your application. In this post the skaffokd build by Dockerfile, however in the GitHub also I added by Jib Maven.

apiVersion: skaffold/v2beta10
kind: Config
build:
  artifacts:
    - image: skaffold-demo-docker
      context: .
      docker:
        dockerfile: Dockerfile

deploy:
  helm:
    releases:
      - name: myapp
        chartPath: ./myapp-chart
        valuesFiles:
          - ./myapp-chart/values.yaml

Spring Boot App


UserController:
 
import com.henry.dockerfiledemo.record.UserRecord;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @GetMapping("/hello")
    public String hello() {
        return "hello world";
    }

    @GetMapping("/user")
    public UserRecord helloUser() {
        return new UserRecord("Henry", "Xiloj");
    }
}


Test:

Run next command: we can check in dev mode our changes. Otherwise try with skaffold run. For more command check official documentation

skaffold dev














Curl:
 curl http://myapp.local/hello








curl http://myapp.local/user








Helm Commands:

helm list




Kubectl commands: for check deployement, sevices, ingress etc


kubectl get all
kubectl get deployment
kubectl get svc
kubectl get ingress


Source Code


Here on GitHub.





References


https://skaffold.dev/
https://helm.sh/
https://www.docker.com/blog/kickstart-your-spring-boot-application-development/
https://stackoverflow.com/questions/65193758/enable-ingress-controller-on-docker-desktop-with-wls2
https://kubernetes.github.io/ingress-nginx/deploy/



Creating REST APIs with OpenAPI, Spring Boot 3.3.3, Java 21, and Jakarta

 Introduction In today's software landscape, designing robust and scalable REST APIs is a crucial aspect of application development. Wit...