Kubernetes에서 기동 안정성을 확보하는 방법
Spring Boot 애플리케이션은 기동 과정에서 JVM 초기화, 클래스 로딩, 스프링 컨텍스트 구성, 커넥션 풀 준비 등 다양한 작업을 수행한다. 이 과정이 끝나기 전까지는 애플리케이션이 정상적으로 요청을 처리하지 못하는 경우가 많다. Kubernetes 환경에서는 이 구간을 제대로 처리하지 않으면 컨테이너가 반복 재시작되는 문제가 발생할 수 있다. 이 글에서는 Startup Probe를 활용해 Spring Boot 애플리케이션을 안전하게 warmup하는 방법을 정리한다.
Spring Boot 기동 시 자주 발생하는 문제
Spring Boot는 기동 시간이 비교적 긴 편이다. 특히 다음과 같은 경우 문제가 자주 발생한다.
- JVM warmup과 클래스 로딩 시간이 긴 경우
- JPA 엔티티 초기화와 스키마 검증이 포함된 경우
- HikariCP 등 커넥션 풀 초기화가 늦는 경우
- 외부 서비스(DB, 메시지 브로커 등)에 의존하는 초기 로직이 있는 경우
이 상태에서 Kubernetes가 Liveness Probe만 사용하면, 아직 정상 기동 중임에도 불구하고 장애로 판단해 컨테이너를 재시작할 수 있다.
Startup Probe란 무엇인가
Startup Probe는 애플리케이션의 초기 기동 완료 여부를 판단하기 위한 Probe다.
Startup Probe가 성공하기 전까지는 다음 Probe들이 동작하지 않는다.
- Liveness Probe
- Readiness Probe
즉, Kubernetes에게 “아직 기동 중이니 기다려라”라는 신호를 주는 역할을 한다.
Startup Probe와 Warmup의 관계
Startup Probe는 warmup 자체를 수행하지 않는다.
대신 warmup이 끝날 때까지 Kubernetes가 성급하게 판단하지 않도록 시간을 확보해준다.
일반적인 역할 분리는 다음과 같다.
- Startup Probe
- 애플리케이션이 뜰 때까지 기다리는 용도
- Readiness Probe
- warmup 완료 전까지 트래픽 차단
- Liveness Probe
- 정상 기동 이후에만 장애 감지
이 구조를 사용하면 기동 안정성과 트래픽 제어를 동시에 확보할 수 있다.
Spring Boot에서 Warmup 처리 방식
Spring Boot에서는 보통 Actuator를 사용해 상태를 노출한다.
/actuator/health/actuator/health/liveness/actuator/health/readiness
Readiness 상태를 warmup 완료 시점에 맞춰 성공하도록 설계하면, 초기 기동 중에는 트래픽이 전달되지 않는다.
Spring Boot Actuator 설정 예시
application.yml 예시는 다음과 같다.
management:
endpoints:
web:
exposure:
include: health
health:
livenessstate:
enabled: true
readinessstate:
enabled: true
이 설정을 통해 Kubernetes가 liveness와 readiness 상태를 분리해서 확인할 수 있다.
Kubernetes Startup Probe 설정 예시
다음은 Spring Boot 애플리케이션을 기준으로 한 Probe 설정 예시다.
startupProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
failureThreshold: 30
periodSeconds: 10
이 설정은 최대 5분 동안 애플리케이션 기동을 기다린다.
Startup Probe가 성공하기 전까지는 다른 Probe가 실행되지 않는다.
Readiness Probe와 함께 사용하는 방식
Warmup이 끝나기 전까지 트래픽을 차단하려면 Readiness Probe를 함께 설정한다.
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
이 방식의 흐름은 다음과 같다.
- 애플리케이션 기동 중
- Startup Probe 대기
- 트래픽 전달 없음
- 기동 완료 후 warmup 진행
- Readiness 실패 상태 유지
- warmup 완료
- Readiness 성공
- 트래픽 전달 시작
Liveness Probe는 최소한으로 설정
Liveness Probe는 정말로 복구 불가능한 상태만 감지하도록 설정하는 것이 좋다.
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
periodSeconds: 10
failureThreshold: 3
외부 의존성(DB, API 호출 등)을 Liveness Probe에 포함시키면 불필요한 재시작이 발생할 수 있다.
Startup Probe 설정 시 자주 하는 실수
다음과 같은 설정은 문제를 유발하기 쉽다.
- Startup Probe 없이 긴 기동 시간을 가진 애플리케이션 운영
- Startup Probe timeout을 너무 짧게 설정
- Readiness와 Liveness를 동일한 엔드포인트로 사용
- 외부 서비스 상태를 Liveness Probe에 포함
Probe는 장애 감지가 아니라 운영 안정성 확보 수단이라는 관점에서 접근해야 한다.
어떤 경우에 Startup Probe가 특히 중요한가
Startup Probe는 다음과 같은 환경에서 효과가 크다.
- Spring Boot 기반 애플리케이션
- JPA, Hibernate 초기화가 포함된 서비스
- 커넥션 풀 수가 많거나 초기화 비용이 큰 경우
- Blue-Green 또는 Rolling 배포 환경
이러한 경우 Startup Probe 없이 운영하면 배포 안정성이 크게 떨어질 수 있다.
정리
Startup Probe는 Spring Boot 애플리케이션의 기동 과정을 Kubernetes가 올바르게 이해하도록 돕는 장치다. Warmup 자체는 Readiness Probe로 제어하고, Startup Probe는 기동 완료 전까지 다른 판단을 유예하는 역할을 맡는다. 이 구조를 적용하면 불필요한 재시작을 방지하고, 안정적인 배포와 트래픽 처리가 가능해진다.