Java Spring Boot K8s
Architecture Visual
Java Spring Boot K8s
Spring Boot is the dominant framework for enterprise Java development. When combined with Kubernetes (K8s), it provides a robust platform for scaling complex domains. This blueprint focuses on “Day 2 Operations”—ensuring your service survives in the chaotic environment of a distributed cluster.
Architecture
This setup assumes a standard 12-Factor App approach.
- Ingress Controller: Routes external traffic to services.
- Service: Stable network endpoint for Pods.
- Deployment: Manages ReplicaSets and rolling updates.
- ConfigMap/Secret: Injects configuration (environment variables) at runtime.
- Spring Actuator: Exposes health and metrics for K8s to monitor.
Use Cases
- Banking Systems: High-transaction, ACID-compliant ledger services.
- Legacy Modernization: Migrating monolithic JARs from websphere to containerized microservices.
- Complex Domains: Systems requiring Domain-Driven Design (DDD) where Java’s type safety shines.
Implementation Guide
We will containerize a Spring Boot application and deploy it with production-grade configuration.
Prerequisites
- JDK 17+
- Docker
- Minikube or Kind (for local K8s)
- Kubectl
Step 1: Spring Boot Application
Ensure pom.xml includes Actuator for health checks.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Enable graceful shutdown in application.properties:
server.shutdown=graceful
management.endpoints.web.exposure.include=health,metrics,prometheus
management.endpoint.health.probes.enabled=true
Step 2: Efficient Dockerfile
Use a multi-stage build to keep the image small (distroless is recommended for security).
# Build Stage
FROM eclipse-temurin:17-jdk-alpine as build
WORKDIR /workspace/app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
RUN ./mvnw install -DskipTests
RUN mkdir -p target/dependency && (cd target/dependency; jar -xf ../*.jar)
# Run Stage
FROM eclipse-temurin:17-jre-alpine
VOLUME /tmp
ARG DEPENDENCY=/workspace/app/target/dependency
COPY --from=build ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=build ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=build ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.DemoApplication"]
Step 3: Kubernetes Deployment
Create k8s/deployment.yaml. Note the Liveness and Readiness probes.
apiVersion: apps/v1
kind: Deployment
metadata:
name: payment-service
labels:
app: payment-service
spec:
replicas: 3
selector:
matchLabels:
app: payment-service
template:
metadata:
labels:
app: payment-service
spec:
containers:
- name: payment-service
image: my-registry/payment-service:v1
ports:
- containerPort: 8080
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
# Startup Probe (New in K8s 1.20+): Give it time to boot
startupProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
failureThreshold: 30
periodSeconds: 10
# Liveness: Restart if dead
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
# Readiness: Don't send traffic until ready
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secrets
key: password
Production Readiness Checklist
[ ] Graceful Shutdown: Enabled server.shutdown=graceful so in-flight requests finish before SIGTERM kills the pod.
[ ] Liveness Probes: Configured to restart the pod only if the JVM is truly broken.
[ ] Readiness Probes: Configured to stop traffic if the DB connection checks fail (or is that an anti-pattern? Usually readiness should be shallow, but Actuator handles this well).
[ ] Resource Limits: Memory limits set to avoid OOMKilled. Remember to set -XX:MaxRAMPercentage if using newer Java containers.
[ ] Observability: Prometheus metrics exposed via /actuator/prometheus are being scraped.
[ ] SecurityContext: Container running as non-root user? (Add securityContext to YAML).
[ ] PodDisruptionBudget: PDB configured to ensure HA during cluster upgrades.
Cloud Cost Estimator
Dynamic Pricing Calculator