Graceful shutdown for Spring Boot on Kubernetes
During a rolling update a pod gets SIGTERM while the Service may still route traffic to it for a moment. Without preparation, in-flight requests die with connection resets. Three things fix it.
1. Let the application finish what it started
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s
The web server stops accepting new connections and waits for active requests, up to the timeout.
2. Delay SIGTERM a little
Endpoint removal and SIGTERM happen in parallel, so a short preStop sleep gives the proxies time to forget the pod.
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 10"]
3. Give Kubernetes enough patience
terminationGracePeriodSeconds must be larger than the sleep plus the Spring timeout, otherwise the pod is killed mid-shutdown. With the values above, 45 seconds is enough.
A readiness probe on /actuator/health/readiness completes the picture: Spring flips it to refusing traffic as soon as shutdown begins.