Zero‑Downtime Deployment with Kubernetes and Spring Boot: Health Checks, Rolling Updates, Graceful Shutdown, Autoscaling, Prometheus Monitoring, and Config Separation
This guide explains how to achieve zero‑downtime releases of a Spring Boot application on Kubernetes by configuring readiness/liveness probes, rolling‑update strategies, graceful shutdown, horizontal pod autoscaling, Prometheus metrics collection, and externalized configuration via ConfigMaps.
This guide demonstrates how to achieve zero‑downtime releases of a Spring Boot application on Kubernetes by configuring health checks, rolling updates, graceful shutdown, autoscaling, Prometheus monitoring, and externalized configuration.
Health Check Configuration
Define readiness and liveness probes using exec, tcpSocket or httpGet. Add the actuator dependency and expose /actuator/health/readiness and /actuator/health/liveness on a dedicated management port (50000) via application.yaml.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency> management:
server:
port: 50000
endpoint:
health:
probes:
enabled: true
endpoints:
web:
exposure:
base-path: /actuator
include: healthRolling Update
Use a Deployment with strategy.type: RollingUpdate and set maxSurge and maxUnavailable to control the number of pods that can be added or unavailable during the upgrade.
apiVersion: apps/v1
kind: Deployment
metadata:
name: {APP_NAME}
spec:
replicas: {REPLICAS}
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1Graceful Shutdown
Enable Spring Boot graceful shutdown ( server.shutdown=graceful) and expose /actuator/shutdown. The Dockerfile must contain curl to invoke the endpoint from a pre‑stop lifecycle hook.
curl -X POST 127.0.0.1:50000/actuator/shutdown FROM openjdk:8-jdk-alpine
ARG JAR_FILE
ARG WORK_PATH="/app"
ARG EXPOSE_PORT=8080
ENV JAVA_OPTS="" \
JAR_FILE=${JAR_FILE}
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \
&& apk add --no-cache curl
COPY target/${JAR_FILE} ${WORK_PATH}/
WORKDIR ${WORK_PATH}
EXPOSE ${EXPOSE_PORT}
ENTRYPOINT exec java $JAVA_OPTS -jar $JAR_FILEAutoscaling
Define resource limits and requests, then create a HorizontalPodAutoscaler that scales between {REPLICAS} and 6 based on CPU utilization (target 50%).
resources:
limits:
cpu: 0.5
memory: 1Gi
requests:
cpu: 0.15
memory: 300Mi
---
kind: HorizontalPodAutoscaler
apiVersion: autoscaling/v2beta2
spec:
minReplicas: {REPLICAS}
maxReplicas: 6
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50Prometheus Integration
Add micrometer-registry-prometheus dependency, enable the metrics and prometheus endpoints, and annotate the pod for Prometheus scraping.
management:
metrics:
tags:
application: ${spring.application.name}
endpoints:
web:
exposure:
base-path: /actuator
include: metrics,prometheus annotations:
prometheus.io/port: "50000"
prometheus.io/path: /actuator/prometheus
prometheus.io/scrape: "true"Configuration Separation
Create a ConfigMap from an external application-test.yaml and mount it into the container, activating the profile with SPRING_PROFILES_ACTIVE=test.
# Generate ConfigMap yaml (dry‑run)
kubectl create cm -n <namespace> <APP_NAME> --from-file=application-test.yaml --dry-run=1 -o yaml > configmap.yaml
# Apply the ConfigMap
kubectl apply -f configmap.yaml env:
- name: SPRING_PROFILES_ACTIVE
value: test
volumeMounts:
- name: conf
mountPath: "/app/config"
readOnly: true
volumes:
- name: conf
configMap:
name: {APP_NAME}Summary Configuration
The final deployment combines the actuator dependency, management port 50000, health probes, graceful shutdown, rolling‑update strategy, resource limits, HPA, Prometheus annotations and ConfigMap‑based external configuration, providing a complete zero‑downtime CI/CD pipeline for Spring Boot services on Kubernetes.
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.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
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.
