헬스체크와 롤아웃 전략
Pod는 "떴다"와 "정상"을 구별해야 한다
컨테이너가 시작됐다고 해서 요청을 받아도 되는 상태인 것은 아니다. JVM 예열, 캐시 웜업, DB 커넥션 풀 초기화가 끝나야 비로소 트래픽을 허용할 수 있다. 반대로 이미 떠 있는 컨테이너가 데드락에 빠져 아무것도 못 하는 상태일 수도 있다. 쿠버네티스는 이 두 문제를 세 가지 프로브(Probe)로 해결한다.
세 가지 프로브
Liveness Probe — "살아 있는가?"
앱이 데드락·무한루프·메모리 누수 등으로 응답 불능이 되면 kubelet이 컨테이너를 재시작한다.
핵심 규칙: Liveness Probe는 외부 의존성을 절대 확인하지 않는다. DB가 다운됐을 때 Liveness가 실패하면, 멀쩡한 Pod들이 줄줄이 재시작되어 장애가 증폭된다.
Readiness Probe — "트래픽을 받을 준비가 됐는가?"
실패하면 해당 Pod를 Service의 엔드포인트에서 제거한다. Pod는 죽지 않는다. 준비가 되면 엔드포인트에 다시 추가된다. 롤링 업데이트 중 신규 Pod의 안전을 보장하는 핵심이다.
Startup Probe — "초기화가 끝났는가?"
Startup Probe가 성공할 때까지 Liveness/Readiness Probe를 아예 실행하지 않는다. 시작이 느린 앱(레거시 Java, 대용량 모델 로딩 등)을 위해 설계됐다.
성공할 때까지 반복 ↓ 성공 Liveness Probe
실패 → 재시작 Readiness Probe
실패 → 엔드포인트 제거
프로브 메커니즘
| 메커니즘 | 설명 |
|---|---|
httpGet | 지정 경로에 HTTP GET 요청; 2xx–3xx이면 성공 |
exec | 컨테이너 내 명령어 실행; 종료 코드 0이면 성공 |
tcpSocket | TCP 포트 연결 시도; 연결되면 성공 |
grpc | gRPC Health Checking Protocol v1 호출 (Kubernetes 1.24+) |
공통 파라미터
| 파라미터 | 기본값 | 설명 |
|---|---|---|
initialDelaySeconds | 0 | 컨테이너 시작 후 첫 프로브까지 대기 시간 |
periodSeconds | 10 | 프로브 실행 주기(초) |
timeoutSeconds | 1 | 프로브 응답 대기 시간(초); 초과 시 실패로 간주 |
failureThreshold | 3 | 연속 실패 횟수; 이 값 초과 시 Fail 판정 |
successThreshold | 1 | 연속 성공 횟수; Readiness는 1 이상으로 설정 가능 |
Startup Probe 설정 예: failureThreshold: 30, periodSeconds: 10 → 최대 300초(5분) 동안 초기화를 기다린다.
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz
port: 8080
periodSeconds: 15
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
failureThreshold: 3/healthz와 /ready를 분리하는 것이 중요하다. /healthz는 앱 자체만 확인하고, /ready는 DB 연결·캐시 준비 등 서비스 가능 여부를 확인한다.
롤아웃 전략
쿠버네티스 Deployment는 두 가지 업데이트 전략을 제공한다.
RollingUpdate (기본값)
구버전 Pod를 점진적으로 교체한다. 두 버전이 동시에 트래픽을 받는 순간이 생긴다. API 하위 호환성을 유지해야 한다.
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25% # 희망 복제본 수를 초과해 임시 생성할 수 있는 Pod 최대치
maxUnavailable: 25% # 업데이트 중 사용 불가 상태로 둘 수 있는 Pod 최대치maxSurge: 0, maxUnavailable: 1→ 하나씩 교체, 추가 노드 없이 진행 (리소스 절약형)maxSurge: 1, maxUnavailable: 0→ 먼저 새 Pod를 띄우고 나서 구 Pod를 내린다 (무중단 보장형)
새 Pod가 Readiness Probe를 통과해야 구 Pod가 내려가기 때문에, Readiness Probe가 없으면 롤아웃이 안전을 보장하지 못한다.
Recreate
구 Pod를 모두 내린 뒤 새 Pod를 띄운다. 단순하지만 다운타임이 발생한다. 두 버전이 동시에 뜨면 안 되는 앱(예: 싱글톤 잠금, DB 스키마 마이그레이션 직후)에 사용한다.
strategy:
type: Recreate롤아웃 흐름 한눈에 보기
안티패턴 정리
| 실수 | 결과 |
|---|---|
| Liveness에서 DB 연결 확인 | DB 장애 시 Pod 재시작 폭풍 |
/healthz와 /ready를 동일 엔드포인트로 사용 | 초기화 중인 Pod에 트래픽이 유입됨 |
initialDelaySeconds를 너무 길게 설정 | 실제 장애를 늦게 감지 |
Startup Probe 없이 긴 initialDelaySeconds | 이미 죽은 컨테이너를 오래 방치 |
| Readiness Probe 없이 RollingUpdate | 준비 안 된 Pod에 트래픽 유입 가능 |
References
- https://kubernetes.io/docs/concepts/configuration/liveness-readiness-startup-probes/
- https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
- https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
- https://oneuptime.com/blog/post/2026-02-09-health-checks-liveness-vs-readiness/view
- https://oneuptime.com/blog/post/2026-02-09-rolling-update-maxsurge-maxunavailable/view
- https://www.bluematador.com/blog/kubernetes-deployments-rolling-update-configuration
- https://spacelift.io/blog/kubernetes-liveness-probe
- https://octopus.com/devops/kubernetes-deployments/kubernetes-deployment-strategies/