본문 바로가기
1. K8s Core & Architecture/1.3. 파드(Pod)와 워크로드 아키텍처

컨테이너 프로브(Probes) 아키텍처: Liveness, Readiness, Startup

by K8s Architect 2026. 4. 10.

컨테이너 프로브(Probes) 아키텍처: Liveness, Readiness, Startup

클라우드 네이티브 환경에서 파드(Pod)가 'Running' 상태라는 것은 단지 컨테이너 프로세스가 종료되지 않고 켜져 있다는 물리적인 사실만을 의미합니다. 애플리케이션 내부에 교착 상태(Deadlock)가 발생하여 응답이 멈췄거나, 톰캣(Tomcat) 서버가 켜지긴 했지만 아직 스프링(Spring) 프레임워크가 초기화되지 않아 실제 사용자의 요청을 처리할 수 없는 논리적인 오류 상태는 'Running'이라는 단어 뒤에 숨겨져 쿠버네티스 컨트롤 플레인이 알아채지 못합니다.

이처럼 컨테이너의 물리적 상태와 애플리케이션의 논리적 상태 사이의 간극을 메우고, 쿠버네티스가 애플리케이션의 진정한 '건강 상태'를 파악할 수 있도록 돕는 핵심 진단 체계가 바로 프로브(Probes)입니다. 본 가이드에서는 Kubelet이 애플리케이션의 헬스 체크를 수행하는 세 가지 프로브의 아키텍처적 차이와 운영 베스트 프랙티스를 심층 분석합니다.


1. 세 가지 프로브의 역할과 동작 메커니즘

쿠버네티스의 각 노드에 상주하는 에이전트인 Kubelet은 명세서에 정의된 프로브 규칙에 따라 컨테이너를 주기적으로 찌르며(Probing) 상태를 확인합니다. 목적에 따라 세 가지로 명확히 구분됩니다.

1.1. Liveness Probe (생존 상태 검사)

"이 컨테이너의 숨통을 끊고 다시 시작해야 하는가?"를 결정하는 프로브입니다.

  • 목적: 애플리케이션이 무한 루프에 빠지거나, 메모리 누수로 멈춰버렸거나, 데드락 상태에 빠져 스스로 복구할 수 없는 치명적인 상태를 감지합니다.
  • 조치: Liveness Probe가 실패 임계치(Failure Threshold)에 도달하면, Kubelet은 자비 없이 해당 컨테이너를 강제 종료(Kill)하고 파드의 restartPolicy에 따라 컨테이너를 완전히 재시작시킵니다.
  • 비유: 의식이 없는 환자에게 심폐소생술(재부팅)을 실시하는 것과 같습니다.

1.2. Readiness Probe (준비 상태 검사)

"이 컨테이너에게 지금 당장 사용자 트래픽을 보내도 안전한가?"를 결정하는 프로브입니다.

  • 목적: 컨테이너가 켜져 있더라도 대용량 데이터를 메모리에 캐싱하거나 외부 API와 초기 동기화를 하느라 아직 요청을 받을 준비가 안 되었을 수 있습니다. 또는 운영 중에 일시적인 과부하로 잠시 트래픽을 쉬어야 할 때 사용합니다.
  • 조치: Readiness Probe가 실패하면 Kubelet은 컨테이너를 죽이지 않습니다. 대신 컨트롤 플레인의 엔드포인트(Endpoint) 컨트롤러에 신호를 보내, 해당 파드의 IP 주소를 연결된 서비스(Service)의 로드밸런싱 목록에서 즉시 제거합니다.
  • 비유: 식당의 문은 열려있지만(Running), 아직 요리 준비가 덜 되어 손님(트래픽)을 받지 않고 대기시키는 것과 같습니다.

1.3. Startup Probe (시작 상태 검사)

"이 무거운 레거시 애플리케이션이 부팅을 무사히 마쳤는가?"를 확인하는 보호용 프로브입니다.

  • 목적: 초기 구동에만 수 분이 걸리는 무거운 JVM 애플리케이션이나 방대한 스키마 마이그레이션을 수행하는 데이터베이스 컨테이너를 보호하기 위해 쿠버네티스 1.16부터 도입되었습니다.
  • 조치: Kubelet은 파드가 켜지면 가장 먼저 Startup Probe만을 실행합니다. 이 프로브가 성공할 때까지 Liveness와 Readiness Probe는 철저하게 비활성화(Disable)됩니다. 만약 Startup Probe가 없이 무거운 앱에 Liveness를 켜두면, 앱이 부팅되기도 전에 Liveness가 실패했다고 판단하여 Kubelet이 컨테이너를 무한히 재시작시키는 악순환에 빠집니다.
  • 비유: 우주선이 대기권을 완전히 돌파할 때까지 다른 모든 간섭을 차단하고 기다려주는 보호막 역할을 합니다.

2. 프로브 진단 방식 (Handlers)

Kubelet은 컨테이너의 상태를 진단하기 위해 4가지 방식의 핸들러(Handler)를 지원합니다. 인프라 환경과 애플리케이션의 특성에 맞춰 가장 가벼운 방식을 선택해야 합니다.

  1. HTTP GET: 가장 보편적인 방식입니다. 지정된 경로(예: /healthz)와 포트로 HTTP GET 요청을 보내고, HTTP 응답 상태 코드가 200~399 범위에 있으면 성공으로 간주합니다.
  2. TCP Socket: 컨테이너의 지정된 포트로 직접 TCP 연결(3-way Handshake)을 시도합니다. 포트가 열려 연결이 맺어지면 성공입니다. HTTP 서버가 아닌 Redis, gRPC 인프라 등에 적합합니다.
  3. Exec (명령어 실행): 컨테이너 내부로 들어가 특정 셸 명령어(예: cat /tmp/healthy)를 실행합니다. 명령어의 종료 코드(Exit Code)가 0이면 성공으로 판정합니다. 외부와 통신하지 않는 배치 처리 컨테이너 진단에 유용합니다.
  4. gRPC: 쿠버네티스 1.24부터 정식 지원된 방식으로, gRPC 헬스 체크 프로토콜을 네이티브하게 사용하여 RPC 서비스의 상태를 정밀하게 파악합니다.

3. 프로브 타이밍 제어 파라미터 튜닝

프로브의 동작 간격과 실패 기준을 조절하는 파라미터를 정확히 설정하지 않으면, 멀쩡한 컨테이너가 재시작되거나 장애가 났는데도 트래픽이 차단되지 않는 문제가 발생합니다.

  • initialDelaySeconds: 컨테이너가 시작된 후, 첫 번째 프로브 진단을 시도하기 전까지 기다리는 대기 시간입니다. (Startup Probe가 있다면 주로 생략됩니다.)
  • periodSeconds: 진단을 얼마나 자주(주기적으로) 수행할지 결정합니다. (기본값: 10초)
  • timeoutSeconds: Kubelet이 진단 요청을 보낸 후 응답을 기다리는 제한 시간입니다. 이 시간을 초과하면 실패로 간주합니다. (기본값: 1초)
  • successThreshold: 실패 상태에서 정상 상태로 돌아오기 위해 연속으로 성공해야 하는 횟수입니다. (Liveness와 Startup은 무조건 1이어야 합니다.)
  • failureThreshold: 정상 상태에서 장애 상태로 판정하기 위해 연속으로 실패해야 하는 횟수입니다. 이 횟수를 채우면 컨테이너가 재시작되거나(Liveness) 트래픽이 차단(Readiness)됩니다. (기본값: 3회)

4. 아키텍처 설계 시 주의해야 할 안티 패턴 (Anti-Patterns)

프로브를 설정할 때 개발자들이 가장 흔히 저지르는 치명적인 아키텍처적 실수는 바로 "외부 의존성(External Dependencies)을 Liveness Probe에 포함시키는 것"입니다.

예를 들어, 웹 서버 애플리케이션의 /healthz 엔드포인트 로직 내부에 "데이터베이스(MySQL)와의 연결 상태를 확인"하는 코드를 넣고 이를 Liveness Probe로 묶었다고 가정해 보겠습니다.
만약 데이터베이스 서버에 잠시 네트워크 병목이 생겨 응답이 지연되면, 웹 서버의 Liveness Probe는 이를 실패로 간주합니다. Kubelet은 웹 서버 컨테이너 자체는 아무런 문제가 없음에도 불구하고, 웹 서버 파드 전체를 재시작해 버립니다.

수십 개의 웹 서버 파드가 데이터베이스 일시 장애 때문에 동시에 재부팅되면, 부팅 후 데이터베이스로 다시 엄청난 커넥션 폭풍(Connection Storm)을 일으켜 데이터베이스를 완전히 뻗게 만드는 연쇄 장애(Cascading Failure)를 유발합니다.

올바른 설계 패턴 (Best Practices):

  • Liveness Probe: 철저하게 '컨테이너 내부의 프로세스 자체가 건강한가?'(스레드 상태, 데드락 여부 등)만을 검사해야 합니다. 외부 시스템의 상태를 물어봐서는 안 됩니다.
  • Readiness Probe: 외부 의존성(DB, 캐시 등)이 끊어져 사용자 요청을 도저히 처리할 수 없다면, Readiness Probe에서 실패를 반환하게 하여 트래픽 유입만 부드럽게 차단(격리)해야 합니다. 이를 통해 의존성이 복구되었을 때 파드가 재시작 충격 없이 즉각적으로 서비스를 재개할 수 있도록 설계해야 합니다.

쿠버네티스의 프로브는 애플리케이션의 숨소리를 듣는 청진기와 같습니다. 맹목적인 재시작이 능사가 아니며, Liveness와 Readiness의 역할을 철저히 분리하고 앱의 부팅 특성에 맞춰 Startup 프로브를 조화롭게 구성하는 것이 무중단 클라우드 네이티브 운영의 핵심입니다.