late::binding

Graceful shutdown for Spring Boot on Kubernetes

· #spring

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.

← all notes