How to Deploy Production-Ready Spring Boot Apps on Kubernetes (V2 Guide)
Learn step-by-step how to prepare, containerize, and securely deploy a Spring Boot application on Kubernetes, covering health checks, metrics, logging, JVM tuning, multi-stage Docker builds, Helm-like resources, ConfigMaps, Secrets, Ingress, HPA, monitoring, CI/CD pipelines, and rollback strategies for production-grade reliability.
1. Preparation
1.1 Application Optimization
Health check endpoints : configure /actuator/health and /actuator/info.
Metrics monitoring : integrate Prometheus via Micrometer.
Log collection : output JSON‑structured logs and ship them to ELK or Loki.
JVM tuning : set heap size and GC options according to container limits (e.g., -XX:+UseG1GC).
1.2 Containerization Preparation
Use a multi‑stage Dockerfile to minimise image size.
Base images: distroless or alpine.
Run containers as a non‑root user.
Scan images with tools such as Trivy or Grype.
2. Containerizing the Spring Boot Application
2.1 Dockerfile Example
# Build stage
FROM eclipse-temurin:17-jdk-jammy as builder
WORKDIR /app
COPY . .
RUN ./gradlew bootJar
# Runtime stage
FROM gcr.io/distroless/java17
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar
USER 1000:1000
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]3. Kubernetes Deployment Configuration
3.1 Deployment Manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot-app
labels:
app: spring-boot-app
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: spring-boot-app
template:
metadata:
labels:
app: spring-boot-app
spec:
containers:
- name: app
image: your-registry/your-app:1.0.0
ports:
- containerPort: 8080
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1000m"
memory: "1024Mi"
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 20
periodSeconds: 5
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true3.2 PodDisruptionBudget (high availability)
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: spring-boot-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: spring-boot-app3.3 Service
apiVersion: v1
kind: Service
metadata:
name: spring-boot-service
spec:
selector:
app: spring-boot-app
ports:
- port: 80
targetPort: 80803.4 Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: spring-boot-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: spring-boot-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 704. Configuration Management
4.1 ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: spring-boot-config
data:
application-prod.properties: |
server.servlet.context-path=/api
spring.datasource.url=jdbc:mysql://db-service:3306/appdb
logging.level.root=INFO4.2 Secret (recommended SealedSecrets/External Secrets)
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: base64encoded
password: base64encoded5. Advanced Configuration
5.1 Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: spring-boot-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: yourdomain.com
http:
paths:
- path: /api(/|$)(.*)
pathType: Prefix
backend:
service:
name: spring-boot-service
port:
number: 805.2 Pod Anti‑Affinity
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: spring-boot-app
topologyKey: kubernetes.io/hostname6. Monitoring and Logging
6.1 Prometheus Scrape Configuration
- job_name: 'spring-boot-app'
metrics_path: '/actuator/prometheus'
scrape_interval: 15s
kubernetes_sd_configs:
- role: pod
namespaces:
names: ['default']
relabel_configs:
- source_labels: [__meta_kubernetes_pod_label_app]
action: keep
regex: spring-boot-app6.2 Fluentd Log Filter
<filter kubernetes.**>
@type parser
key_name log
reserve_data true
<parse>
@type json
time_key time
time_format %Y-%m-%dT%H:%M:%S.%NZ
</parse>
</filter>7. CI/CD (GitHub Actions + ArgoCD)
name: CI-CD
on:
push:
branches: [ main ]
jobs:
build-test-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run Unit Tests
run: ./gradlew test
- name: Build with Gradle
run: ./gradlew bootJar
- name: Build & Push Docker
uses: docker/build-push-action@v2
with:
push: true
tags: your-registry/your-app:${{ github.sha }}
- name: Deploy via ArgoCD
run: |
argocd app sync spring-boot-app
argocd app wait spring-boot-app8. Rollback Strategy
# View rollout history
kubectl rollout history deployment/spring-boot-app
# Roll back one revision
kubectl rollout undo deployment/spring-boot-app
# Roll back to a specific revision
kubectl rollout undo deployment/spring-boot-app --to-revision=29. Best‑Practice Checklist
Container security : enable securityContext and run as non‑root.
Configuration management : prefer External Secrets or SealedSecrets.
High availability : configure PodDisruptionBudget and anti‑affinity.
Auto‑scaling : use HPA with Prometheus metrics.
Blue‑green/Canary releases : adopt Argo Rollouts or Flagger.
CI/CD pipelines : include testing, image scanning, and security checks.
Monitoring & alerts : Prometheus + Grafana + Alertmanager.
Logging : structured JSON logs collected by Loki or ELK.
Operations handbook : prepare troubleshooting commands and capacity‑planning docs.
Regular image scanning & upgrades : keep images safe and up‑to‑date.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ray's Galactic Tech
Practice together, never alone. We cover programming languages, development tools, learning methods, and pitfall notes. We simplify complex topics, guiding you from beginner to advanced. Weekly practical content—let's grow together!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
