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
Kubernetes: The Backbone of Container Orchestration
Docker Desktop: Localized Development Environment for 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:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.41.2/deploy/static/provider/cloud/deploy.yaml
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:
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
v2.9.0
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
|-- ...
- 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
apiVersion: v2
name: myapp
description: A Helm chart for my Spring Boot application
version: 1.0.0
appVersion: 1.0.0
replicaCount: 1
image:
repository: skaffold-demo-docker
tag: latest
service:
port: 8080
ingress:
enabled: true
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"]
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
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:
skaffold dev
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