Companion code for "Deploying Spring Boot 4 on Kubernetes: Probes, Graceful Shutdown, Limits and JVM Ergonomics". A dependency outage under three probe-group setups, a rolling restart under load four ways (three runs each), the JVM's ergonomic choices for nine pod shapes, one GC-heavy load under five CPU limits with throttling counters, and an HPA driven by a Micrometer gauge through prometheus-adapter. Measured on k3s v1.36.4. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01C3TETMrqVUWeFkNtz3Jbo3
3.5 KiB
3.5 KiB
Spring Boot 4 on Kubernetes: probes, graceful shutdown, limits and JVM ergonomics
Companion project for Deploying Spring Boot 4 on Kubernetes: Probes, Graceful Shutdown, Limits and JVM Ergonomics on ankurm.com.
A small Spring Boot 4 service, the manifests that deploy it, and one script per experiment - a
dependency outage under three probe configurations, a rolling restart under load four ways, the JVM's
ergonomic choices for nine pod shapes, the same GC-heavy load under five CPU limits, and a
HorizontalPodAutoscaler driven by a Micrometer gauge. Every figure in the article is in
docs/output/.
Versions
| Spring Boot | 4.1.1 |
| JDK | Temurin 25.0.4.1 (in gcr.io/distroless/java25-debian13:nonroot) |
| Kubernetes | k3s v1.36.4+k3s1, single node, 2 vCPU / 8 GB, cgroup v1 (docs/01-the-lab.md) |
| Prometheus | 3.14.0 |
| prometheus-adapter | 0.12.0 |
Quickstart
export JAVA_HOME=/path/to/jdk-25
mvn -DskipTests package
docker build -f docker/Dockerfile -t sbd/k8s-demo:1 .
# load the image into your cluster (k3s ctr images import / kind load docker-image / minikube image load)
kubectl apply -f k8s/00-namespace.yaml -f k8s/downstream.yaml -f k8s/orders.yaml -f k8s/client.yaml
./scripts/demo-probes.sh # ...and the other demo-*.sh; see the table below
What is in it
| Path | |
|---|---|
k8s/orders.yaml |
the baseline Deployment: startup/liveness/readiness probes, preStop: sleep, MaxRAMPercentage=75 |
k8s/downstream.yaml |
a dependency to take away |
k8s/gc-lab.yaml |
the single pod the CPU-limit experiment reshapes |
k8s/hpa/ |
Prometheus, prometheus-adapter with one rule, the HPA |
WorkController |
/work (timed requests, the app.inflight.requests gauge), /alloc (GC load) |
DownstreamHealthIndicator |
a health indicator whose probe group is the experiment |
JvmController |
/diag/jvm, /diag/gc - ergonomics and cgroup throttling counters. Diagnostic; delete before shipping |
LoadGen |
the in-cluster load generator, run from the same image |
Documentation
- The lab
- Probes: which checks belong in which probe
- JVM ergonomics: what the JVM decides from your pod spec
- CPU limits and the garbage collector
- Graceful shutdown and the rolling-update race
- HPA on a custom Micrometer metric
Captured output
| File | Produced by |
|---|---|
probes-*.txt |
scripts/demo-probes.sh |
startup-probe.txt |
scripts/demo-startup.sh |
jvm-ergonomics.txt |
scripts/demo-ergonomics.sh |
gc-throttling.txt + raw GC logs |
scripts/demo-gc-throttling.sh |
shutdown-post-summary.txt, shutdown-*.txt |
scripts/demo-shutdown.sh (METHOD=GET for the -get- files) |
hpa-custom-metric.txt, hpa-custom-metrics-api.txt |
scripts/demo-hpa.sh |