본문 바로가기
클라우드/쿠버네티스

🚀 당신의 애플리케이션, 과연 건강한가요? 쿠버네티스 Probes로 스마트하게 관리하기!

by gasbugs 2025. 9. 3.

안녕하세요, 개발자 및 운영자 여러분! 👨‍💻👩‍💻 우리가 밤샘 코딩으로 만들어낸 소중한 애플리케이션이 쿠버네티스 클러스터 위에서 24시간 365일 안정적으로 동작하기를 바라는 마음은 모두 같을 겁니다. 하지만 세상일이 언제나 뜻대로 되는 건 아니죠. 🥲 가끔 애플리케이션이 멈추거나, 느려지거나, 아예 먹통이 되는 상황이 발생할 수 있습니다. 이때, 쿠버네티스는 마치 유능한 주치의처럼 우리의 애플리케이션 컨테이너들을 끊임없이 진찰하고 필요한 조치를 취해줍니다. 그 핵심적인 진단 도구가 바로 "Probes" 입니다.

 

오늘은 이 Probes가 무엇이고, 어떤 종류가 있으며, 어떻게 설정하는지 아주 자세하게 알아보겠습니다. 자, 그럼 시작해볼까요? 🩺✨

 


🏥 우리 컨테이너의 건강을 책임지는 세 가지 Probes

쿠버네티스의 kubelet 에이전트는 각 노드에서 실행되며 파드(Pod) 내의 컨테이너들을 관리합니다. 이 kubelet이 사용하는 세 가지 주요 Probes를 통해 컨테이너의 생존(Liveness), 준비 상태(Readiness), 그리고 초기 기동(Startup) 상태를 점검합니다.

1. Liveness Probe: "너... 아직 살아있니?" 🧟‍♂️➡️🔄

Liveness Probe는 컨테이너가 현재 "살아있는지(Live)"를 확인합니다. 즉, 애플리케이션이 비정상적인 상태(예: 데드락, 무한 루프, 메모리 누수로 인한 응답 없음)에 빠져 더 이상 작업을 수행할 수 없는 '좀비 상태'가 되었는지를 감지합니다.

  • 역할: 컨테이너가 응답 불능 상태인지 주기적으로 점검합니다.
  • 작동 방식:
    • kubelet이 Liveness Probe를 실행하고 설정된 기준에 따라 "성공" 또는 "실패"를 판단합니다.
    • 실패 시: kubelet은 해당 컨테이너를 비정상으로 판단하고 즉시 재시작(Restart) 시킵니다. 🔄 이는 컨테이너가 스스로 문제를 해결하고 깨끗한 상태로 다시 시작할 기회를 주는 자가 치유(Self-healing) 메커니즘의 핵심입니다.
    • 성공 시: 컨테이너는 계속 정상 작동합니다.
  • 언제 사용할까?: 애플리케이션이 단순히 다운된 것이 아니라, 외부적으로는 실행 중인 것처럼 보이지만 내부적으로는 처리 불가능한 상태에 빠졌을 때 유용합니다.
  • 주의 사항: Liveness Probe가 너무 민감하게 설정되면, 일시적인 부하나 준비 시간 때문에 불필요하게 컨테이너가 재시작될 수 있습니다. 특히 시작 시간이 긴 애플리케이션의 경우, Liveness Probe가 너무 일찍 시작되지 않도록 initialDelaySeconds를 충분히 주거나, Startup Probe와 함께 사용하는 것이 좋습니다.

 

2. Readiness Probe: "손님(트래픽) 받을 준비됐어?" 🚦✅

Readiness Probe는 컨테이너가 "외부 트래픽을 처리할 준비가 완료되었는지(Ready)"를 확인합니다. 컨테이너가 시작되었다고 해서 바로 모든 서비스 요청을 처리할 수 있는 것은 아닙니다. 애플리케이션 초기화, 데이터베이스 연결, 캐시 로딩 등 준비 과정에 시간이 필요할 수 있습니다.

  • 역할: 컨테이너가 현재 서비스 요청을 수락할 준비가 되었는지 점검합니다.
  • 작동 방식:
    • kubelet이 Readiness Probe를 실행하여 성공/실패를 판단합니다.
    • 실패 시: kubelet은 해당 컨테이너를 비정상으로 판단하지만, 재시작 시키지 않습니다. 대신, 쿠버네티스 Service의 엔드포인트 목록에서 이 컨테이너의 IP 주소를 제거합니다. 🚫 이렇게 되면 Service는 준비되지 않은 컨테이너로는 더 이상 트래픽을 라우팅하지 않습니다.
    • 성공 시: 컨테이너의 IP 주소를 Service의 엔드포인트 목록에 다시 추가하여 정상적으로 트래픽을 받을 수 있게 합니다.
  • 언제 사용할까?: 데이터베이스 연결, 외부 API 의존성 초기화, 대용량 캐시 로딩 등 애플리케이션이 실제로 요청을 처리할 수 있게 되기까지 시간이 걸리는 경우에 필수적입니다. 롤링 업데이트(Rolling Update) 시에도 새로운 파드가 완전히 준비될 때까지 기존 파드가 트래픽을 처리하도록 하여 서비스 중단을 방지하는 데 중요한 역할을 합니다.
  • 주의 사항: Readiness Probe는 보통 Liveness Probe보다 더 엄격한 기준을 적용할 수 있습니다. "살아있는 것"을 넘어 "제대로 작동하는 것"을 목표로 합니다.

3. Startup Probe: "아직 워밍업 중이야, 기다려줘! 🚀"

시작하는 데 매우 긴 시간이 소요되는 애플리케이션(예: 복잡한 Java 애플리케이션, 대용량 데이터를 로딩하는 서비스)의 경우, Liveness나 Readiness Probe가 너무 일찍 시작되어 컨테이너가 아직 준비 중임에도 불구하고 "실패"로 판단하고 불필요하게 재시작 시키는 문제가 발생할 수 있습니다. Startup Probe는 이런 상황을 해결하기 위해 도입되었습니다.

  • 역할: 시작 시간이 긴 컨테이너에게 충분한 초기 시작 시간을 보장합니다.
  • 작동 방식:
    • Startup Probe가 설정되면, 이 Probe가 성공할 때까지 Liveness와 Readiness Probe는 작동하지 않습니다. 🤫
    • 실패 시: failureThreshold와 periodSeconds에 설정된 시간 동안 Startup Probe가 계속 실패하면, 컨테이너는 시작에 실패했다고 판단되어 재시작됩니다.
    • 성공 시: Startup Probe가 성공하면, 그제야 Liveness와 Readiness Probe가 활성화되어 정상적인 컨테이너 상태 점검을 시작합니다.
  • 언제 사용할까?: 시작 시간이 예측 불가능하거나 매우 긴 레거시 애플리케이션, 또는 많은 초기화 작업이 필요한 마이크로서비스에 적합합니다.
  • 주의 사항: Startup Probe는 periodSeconds와 failureThreshold를 곱한 값이 애플리케이션의 최대 예상 시작 시간보다 충분히 길게 설정되어야 합니다. 그렇지 않으면 여전히 초기화 중인 애플리케이션이 실패로 간주되어 재시작될 수 있습니다.

🛠️ Probes 설정 방법: 어떻게 진단할까?

쿠버네티스는 컨테이너의 상태를 점검하는 세 가지 기본적인 방법을 제공합니다. 이 방법들은 Liveness, Readiness, Startup Probe 모두에 적용할 수 있습니다.

1. HTTP httpGet: 웹 API로 상태 확인 🌐

가장 흔하고 일반적으로 사용되는 방법입니다. kubelet이 지정된 IP 주소, 포트, HTTP 경로로 GET 요청을 보냅니다.

  • 성공 기준: HTTP 응답 코드가 200 이상 400 미만(예: 200 OK, 301 Redirect 등)일 경우 성공으로 간주합니다.
  • 예시:
    livenessProbe:
      httpGet:
        path: /healthz    # 헬스 체크 엔드포인트 경로
        port: 8080        # 애플리케이션이 리스닝하는 포트
        # host: example.com # (선택 사항) 특정 호스트 헤더 지정
        # scheme: HTTPS     # (선택 사항) HTTPS 사용 시
      initialDelaySeconds: 15 # 컨테이너 시작 후 15초 뒤부터 Liveness 체크 시작
      periodSeconds: 20       # 20초마다 체크
      timeoutSeconds: 5       # 5초 안에 응답이 없으면 실패
      failureThreshold: 3     # 3회 연속 실패 시 재시작
    
  • 장점: 웹 서버, REST API 등 HTTP 기반 서비스에 가장 적합하며, 상세한 상태 로직(예: DB 연결, 외부 API 호출 등)을 헬스 체크 엔드포인트 내부에 구현할 수 있습니다.

2. TCP tcpSocket: 포트 연결 확인 🔌

kubelet이 컨테이너의 지정된 포트로 TCP 연결을 시도합니다.

  • 성공 기준: TCP 연결이 성공적으로 수립되면 성공으로 간주합니다.
  • 예시:
    readinessProbe:
      tcpSocket:
        port: 5432        # 데이터베이스 또는 gRPC 서버 포트
      initialDelaySeconds: 10
      periodSeconds: 5
      timeoutSeconds: 1
      failureThreshold: 3
    
  • 장점: HTTP 엔드포인트가 없는 서비스(예: MySQL, PostgreSQL, gRPC 서버)의 포트가 열려있고 응답하는지 확인할 때 유용합니다. 애플리케이션이 완전히 시작되지 않았더라도 포트만 열려 있다면 기본 연결 가능 여부를 판단할 수 있습니다.

3. Exec exec: 컨테이너 내부 명령어 실행 🧑‍💻

kubelet이 컨테이너 내부에서 특정 명령어를 실행합니다.

  • 성공 기준: 명령어의 종료 코드(Exit Code)가 0일 경우 성공으로 간주합니다. 0이 아닌 다른 코드(예: 1)가 반환되면 실패입니다.
  • 예시:
    startupProbe:
      exec:
        command:
        - cat             # 실행할 명령어
        - /tmp/app-started # 이 파일이 존재하면 성공 (파일 생성은 애플리케이션이 직접 수행)
      initialDelaySeconds: 0 # Startup Probe는 보통 초기 지연 없음
      periodSeconds: 5
      failureThreshold: 120 # 5초 * 120회 = 600초 (10분) 동안 기다림
    
  • 장점: 가장 유연한 방법입니다. 파일 존재 여부 확인, 특정 프로세스 실행 여부, 복잡한 커스텀 스크립트 실행 등 HTTP나 TCP로 검사하기 어려운 고급 로직을 구현하여 컨테이너의 상태를 진단할 수 있습니다.

💡 프로브 설정 시 고려사항 및 팁

  • initialDelaySeconds: 컨테이너가 시작된 후 첫 프로브를 실행하기까지 기다리는 시간입니다. 애플리케이션이 초기화될 시간을 충분히 주어 불필요한 실패를 방지해야 합니다.
  • periodSeconds: 프로브를 실행하는 주기입니다. 너무 짧으면 클러스터에 부하를 줄 수 있고, 너무 길면 문제 감지가 늦어집니다. 적절한 균형을 찾는 것이 중요합니다.
  • timeoutSeconds: 프로브 요청이 '성공' 응답을 받기까지 기다리는 최대 시간입니다. 이 시간 안에 응답이 없으면 실패로 간주합니다.
  • failureThreshold: 프로브가 연속적으로 실패했을 때 '실패'로 간주하기까지의 횟수입니다. 일시적인 문제로 인한 오작동을 피하기 위해 1보다 큰 값을 설정하는 것이 좋습니다.
  • Liveness와 Readiness의 분리: Liveness는 "죽었나?"에 집중하고, Readiness는 "준비됐나?"에 집중하세요. 둘의 로직이 동일할 필요는 없습니다. 오히려 분리하는 것이 더 견고한 애플리케이션을 만듭니다.
  • 가벼운 헬스 체크 엔드포인트: httpGet이나 exec를 사용할 때, 헬스 체크 로직은 최대한 가볍고 빠르게 응답하도록 설계해야 합니다. 복잡한 DB 쿼리나 외부 API 호출을 넣으면 헬스 체크 자체가 부하가 될 수 있습니다.

🎉 결론: Probes는 안정적인 서비스 운영의 핵심

쿠버네티스 Probes는 단순한 건강 검진을 넘어, 애플리케이션의 자가 치유와 무중단 배포를 가능하게 하는 핵심적인 기능입니다. 각 Probes의 역할과 작동 방식을 정확히 이해하고, 애플리케이션의 특성에 맞게 적절히 설정하는 것이 안정적이고 효율적인 쿠버네티스 환경을 구축하는 첫걸음입니다.

오늘부터 여러분의 애플리케이션 컨테이너들에게도 꼼꼼한 건강 검진을 시작해주세요! 💖


Tags: 쿠버네티스, Kubernetes, Probe, LivenessProbe, ReadinessProbe, StartupProbe, HealthCheck, 컨테이너, 데브옵스, MSA, 애플리케이션관리, SelfHealing