Liveness Probe vs. Readiness Probe

ka8main.png

쿠버네티스에서 Liveness Probe와 Readiness Probe는 컨테이너의 상태를 체크하여 트래픽 라우팅 및 자동 복구에 중요한 역할을 한다.
이 글에서는 두 개의 프로브(probe)가 어떤 차이가 있는지, 언제 사용해야 하는지에 대해 살펴본다.

Liveness Probe (생존 여부 확인)

역할:
Liveness Probe는 컨테이너가 살아 있는지 확인하는 역할을 한다.
만약 컨테이너가 정상적인 상태를 유지하지 못하면, 쿠버네티스가 해당 컨테이너를 자동으로 재시작한다.

예제: HTTP 기반 Liveness Probe

livenessProbe:
  httpGet:
    path: /live
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10

http://localhost:8080/live 엔드포인트를 10초마다 호출하여 컨테이너의 생존 여부를 체크.
응답이 없거나 500 에러를 반환하면 Pod를 강제 재시작.

사용 사례

  • 애플리케이션이 무한 루프에 빠져 응답을 하지 않는 경우
  • 애플리케이션이 메모리 부족(OutOfMemoryError) 등으로 내부적으로 멈춘 경우
  • 복구 불가능한 상태가 되면 Pod를 자동으로 재시작해야 하는 경우

Readiness Probe (준비 여부 확인)

역할:
Readiness Probe는 컨테이너가 트래픽을 받을 준비가 되었는지 확인하는 역할을 한다.
이 프로브가 실패하면 쿠버네티스가 해당 Pod를 서비스 엔드포인트에서 제외하여 트래픽이 전달되지 않는다.
하지만 Pod 자체는 재시작되지 않는다.

예제: HTTP 기반 Readiness Probe

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10

http://localhost:8080/ready 엔드포인트를 10초마다 호출하여 컨테이너가 트래픽을 받을 준비가 되었는지 확인.
응답이 없거나 500 에러를 반환하면 트래픽을 받지 않도록 설정하지만, Pod는 유지됨.

사용 사례

  • 애플리케이션이 초기화 중(ex. DB 연결, 캐시 로드)이라 아직 트래픽을 받을 준비가 되지 않은 경우.
  • 일시적으로 응답할 수 없는 상태(ex. 외부 API 응답 대기)일 때 트래픽을 차단해야 하는 경우.
  • 트래픽을 받을 준비가 되었는지를 애플리케이션이 직접 결정해야 하는 경우.

Readiness Probe를 애플리케이션이 제어하는 방법

예시: HTTP 엔드포인트를 활용

애플리케이션이 준비되지 않은 경우 503 Service Unavailable을 반환하여 트래픽을 차단하고, 준비 완료 시 200 OK를 반환하면 된다.

Spring Boot 예제

@RestController
public class ReadinessController {

    private boolean isReady = false;

    @GetMapping("/ready")
    public ResponseEntity<String> readinessCheck() {
        if (isReady) {
            return ResponseEntity.ok("Ready");
        } else {
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("Not Ready");
        }
    }

    @PostMapping("/ready/enable")
    public ResponseEntity<String> enableReadiness() {
        isReady = true;
        return ResponseEntity.ok("Readiness enabled");
    }

    @PostMapping("/ready/disable")
    public ResponseEntity<String> disableReadiness() {
        isReady = false;
        return ResponseEntity.ok("Readiness disabled");
    }
}

POST /ready/enable을 호출하면 트래픽을 받기 시작하고, POST /ready/disable을 호출하면 트래픽을 차단할 수 있다.

readinessProbelivenessProbe를 설정하지 않으면?

readinessProbe가 없을 때

  • Pod가 애플리케이션 초기화가 끝나기 전에 트래픽을 받음.
  • DB 연결 등 필수 작업이 끝나지 않아도 클라이언트 요청이 전달될 수 있음.
  • 첫 번째 요청이 실패할 가능성이 높음.

livenessProbe가 없을 때

  • 애플리케이션이 응답하지 않아도 컨테이너가 자동으로 재시작되지 않음.
  • 메모리 부족이나 무한 루프 상태에서도 서비스가 계속 죽어 있는 상태로 유지될 수 있음.
  • 관리자가 직접 kubectl delete pod 명령을 실행해야 함.

정리된 기본 동작

설정 여부 readinessProbe livenessProbe
설정 O 준비가 완료될 때만 트래픽을 받음 비정상 상태일 때 자동 재시작
설정 X (기본값) Pod가 생성되자마자 트래픽을 받음 Pod가 살아 있다고 간주되며, 문제가 생겨도 감지 못함

startupProbe와의 차이점

startupProbe는 애플리케이션이 아예 시작되지 못한 경우를 감지하는 프로브다.
만약 livenessProbe를 너무 일찍 실행하면 애플리케이션이 부팅되기도 전에 재시작될 수 있는데, 이를 방지하기 위해 사용한다.

예제: startupProbe + livenessProbe 조합

startupProbe:
  httpGet:
    path: /start
    port: 8080
  failureThreshold: 30
  periodSeconds: 10

livenessProbe:
  httpGet:
    path: /live
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 10

startupProbe는 최대 5분(10초 x 30회) 동안 애플리케이션이 부팅될 때까지 기다림.
startupProbe가 성공한 후 livenessProbe가 정상적으로 동작.

정리

🚀 쿠버네티스에서 안정적인 서비스를 운영하려면 readinessProbelivenessProbe를 반드시 설정해야 한다!
특히, 초기화 시간이 긴 애플리케이션은 startupProbe도 함께 활용하는 것이 좋다.