[kubernetes] Pod 헬스 체크 (Probe)

2025. 3. 14. 02:31·Kubernetes & EKS/k8s 공부 기록

들어가기 앞서 

파드가 노드에 스케줄링되는 즉시 해당 노드의 kubelet 은 컨테이너를 실행하고, 그 이후부터는 파드가 존재하는한 컨테이너를 계속 실행한다. 컨테이너의 메인 프로세스가 충돌하는 경우, kubelet 은 애플리케이션을 자동으로 다시 시작하므로 앱 자체에서 특별한 작업을 수행하지 않더라도 Kubernetes 에서 앱을 실행하면 자동으로 스스로 치유 해결한다. 애플리케이션이 다시 시작하도록 구성하려면 앱 내부에 의존하지 않고 외부에서 애플리케이션의 상태를 확인해야만 한다. 

파드의 상태를 체크하기 위해 Kubernetes 에는 총 3가지의 '프로브(probe)' 라는 것이 존재한다. 각 프로브는 컨테이너의 상태를 체크하고 적절한 조치를 취하는 역할을 한다. 

  • Liveness Probe : 컨테이너가 죽었는지 확인, 실패 시 컨테이너 재시작
  • Readiness Probe : 서비스 받을 준비가 되었는지 확인, 실패 시 트래픽 제외
  • Startup Probe : 애플리케이션이 정상적으로 시작되었는지 확인, 실패 시 컨테이너 재시작 

Liveness Probe

kubernetes 는 liveness probe 를 통해 컨테이너의 생존 유무를 확인할 수 있다. kubernetes 는 주기적으로 liveness probe 를 실행하고 probe 가 실패하면 컨테이너를 재시작한다. pod spec 에서 각 컨테이너에 대한 liveness probe 를 지정할 수 있다. 세 가지 메커니즘 중 하나를 선택하여 컨테이너를 probing 한다.

  • HTTP GET 프로브는 컨테이너의 IP 주소, 지정한 포트 및 경로에 대해 HTTP GET 요청을 수행한다. 프로브가 응답을 받고 응답 코드가 오류를 나타내지 않는 경우, 프로브는 성공으로 간주된다. 
  • TCP 소켓 프로브는 컨테이너의 지정된 포트에 대한 TCP 연결을 시도한다. 연결이 성공적으로 수립되면 프로브는 성공한다. 그렇지 않으면 컨테이너가 다시 시작된다.
  • Exec 프로브는 컨테이너 내에서 임의의 명령을 실행하고 명령의 종료 상태 코드를 확인한다. 상태 코드가 0 이면 프로브는 성공으로 간주된다. 다른 모든 코드는 실패로 간주된다.

HTTP 기반 liveness probe 생성

apiVersion: v1
kind: Pod
metadata:
  name: kubia-liveness
spec:
  containers:
  - image: luksa/kubia-unhealthy   
	name: kubia
	livenessProbe:   
	  httpGet:
		path: /    
	    port: 8080

 

파드 디스크립터는 쿠버네티스가 컨테이너가 여전히 정상인지 확인하기 위해 경로 / 포트 8080 에서 HTTP GET 요청을 주기적으로 수행하도록 지시하는 httpGet 활성 프로브를 정의한다.

liveness 프로브가 작동하는 모습 확인

활성 프로브가 프로빙을 실패해 정상 작동하면 컨테이너가 재시작되는 것을 볼 수 있다. ( RESTARTS + 1 )

$ kubectl get po kubia-liveness
NAME             READY     STATUS    RESTARTS   AGE
kubia-liveness   1/1       Running   1          2m

또한, 컨테이너가 재실행(restart) 된 이유를 kubelet describe 를 통해 확인할 수 있다. 

$ kubectl describe po kubia-liveness
Name:           kubia-liveness
...
Containers:          
  kubia:
    Container ID:   docker://480986f8
    Image:          luksa/kubia-unhealthy
    Image ID:       docker://sha256:2b208508
    Port:
    State:          Running
      Started:      Sun, 14 May 2017 11:41:40 +0200
      Last State:   Terminated
        Reason:     Error
        Exit Code:  137
        Started:    Mon, 01 Jan 0001 00:00:00 +0000
        Finished:   Sun, 14 May 2017 11:41:38 +0200
    Ready:          True
    Restart Count:  1
    Liveness:       http-get http://:8080/ delay=0s timeout=1s
                    period=10s #success=1 #failure=3
...
Events:
  ... Killing container with id docker://95246981:pod "kubia-liveness ..."
  container "kubia" is unhealthy, it will be killed and re-created.

liveness probe 의 추가 속성 구성 

명시적으로 지정한 살아있음 프로브 옵션 외에도 지연(delay), 타임아웃(timeout), 주기(period) 등과 같은 추가 속성을 볼 수 있다.

  1. delay=0s : 부분은 컨테이너가 시작된 직후에 프로빙이 시작된다는 것을 나타냄
  2. timeout=1s :  컨테이너는 1초 안에 응답을 반환해야하며 그렇지 않으면 프로브가 실패로 간주된다.
  3. probe period=10s : 컨테이너는 10초마다 프로브가 수행되며 프로브가 연속적으로 세 번 실패하면 컨테이너가 다시 시작된다.

이러한 추가 매개변수는 프로브를 정의할 때 지정할 수 있다.

livenessProbe:
  httpGet:
    path: /
    port: 8080
    initialDelaySeconds: 15     # 쿠버네티스는 첫 번째 프로브를 실행하기 전에 15초 동안 기다린다.

초기 지연을 설정하지 않으면 프로브가 시작하자마자 컨테이너를 프로빙하기 시작하므로 앱이 요청 수신을 시작할 준비가 되지 않아 일반적으로 실패하게 된다. 실패 횟수가 임계값을 초과하면 컨테이너가 제대로 시작하기 전에 다시 시작된다.

효과적인 liveness probe 만들기

  • 프로덕션 환경의 파드는 항상 라이브니스 프로브를 정의해야 함.
  • 프로브가 없으면 Kubernetes는 앱이 살아있는지 확인할 수 없음.
  • 프로브는 특정 URL에서 내부 구성 요소의 상태를 점검해야 하며, 외부 요인(예: DB 연결 문제)에 영향을 받지 않아야 함.
    • 예를 들어, 프론트엔드 웹 서버의 프로브는 백엔드 데이터베이스에 연결이 안 될 때 실패해선 안된다. 만약 데이터베이스에 원인이 있다면, 웹 서버를 다시 시작해도 문제가 해결되지 않아 반복적인 재시작이 발생할 수 있다.
  • 프로브는 가벼워야 하며, 실행 시간이 길어지면 컨테이너 성능에 영향을 줄 수 있음.
  • JVM 기반 앱에서는 Exec 프로브 대신 HTTP GET 프로브를 사용하는 것이 효율적임.
  • 재시도 루프를 직접 구현할 필요 없음, Kubernetes가 이미 자동으로 재시도를 수행함.
  • Kubelet은 컨테이너 충돌 시 자동 재시작하지만, 노드 자체가 실패하면 컨트롤 플레인이 새로운 파드를 생성해야 함.
  • 노드 장애 시 파드를 복구하려면 ReplicationController 또는 유사한 메커니즘으로 관리해야 함.

Readiness Probe

readiness probe 는 주기적으로 호출되며, 특정 파드가 클라이언트 요청을 받아들여야 하는지 여부를 결정한다. 컨테이너의 readiness probe 가 성공을 반환하면 해당 컨테이너가 요청을 받아들일 준비가 되었다는 신호이다. 쿠버네티스는 컨테이너에 실행되는 앱이 단순한 GET / 요청에 응답하는지 확인할 수 있을 뿐만 아니라 앱이 준비 상태인지 확인하기 위해 특정 URL 경로에 접근할 수도 있다. 앱의 구체적인 내용을 고려한 이러한 상세한 readiness probe 는 앱 개발자의 책임이다.

Readiness Probe 유형

liveness 프로브와 마찬가지로, 준비성 프로브에는 세 가지 유형이 있다.

  • Exec probe : 프로세스를 실행한다. 컨테이너의 상태는 프로세스의 종료 상태 코드에 의해 결정
  • HTTP GET probe : 컨테이너에 HTTP GET 요청을 보내고 응답의 HTTP 상태 코드에 따라 컨테이너가 준비 상태인지 여부 결정
  • TCP 소켓 probe : 컨테이너의 지정된 포트에 TCP 연결을 연다. 연결이 설정되면 컨테이너는 준비된 것으로 간주

Readiness Probe 작동 이해

쿠버네티스는 컨테이너가 시작될 때 설정된 시간 동안 기다린 후 첫 번째 준비 상태 확인을 수행한다. 이후 주기적으로 프로브를 호출하며, readiness probe 의 결과에 따라 동작한다. 만약 파드가 준비되지 않았다고 보고되면 해당 파드는 서비스에서 제거된다. 그러나 파드가 다시 준비되면 다시 서비스에 추가된다. liveness probe 와는 달리, 준비성 검사에 실패하면 컨테이너가 종료되거나 다시 시작되지 않는다. liveness probe 는 불건전한 컨테이너를 종료하고 새로운 건강한 컨테이너로 교체하여 파드를 건강하게 유지한다. readiness probe 는 요청을 처리할 준비가 된 파드만 해당 요청을 수신한다. 이는 컨테이너가 시작될 때 필요하지만, 컨테이너가 장기간 실행된 후에도 유용한 메커니즘 이다.

그림 5.11에서 볼 수 있듯이, 만약 파드의 준비성 프로브가 실패하면 해당 파드는 엔드포인트 개체에서 제거됩니다. 서비스에 연결하는 클라이언트는 해당 파드로 리디렉트되지 않습니다. 이는 파드가 서비스의 레이블 선택기와 일치하지 않는 경우와 동일한 효과를 줍니다.

Readiness Probe 중요성

애플리케이션 서버를 실행하는 일부 파드가 백엔드 데이터베이스와 같은 다른 파드가 제공하는 서비스에 의존한다고 가정해보자. 그러면 프론트엔드 파드 중 하나가 데이터베이스에 연결할 수 없게 되면, 해당 파드가 다른 요청을 처리할 수 없다고 쿠버네티스에 알리는 것이 좋다. 이렇게 하면 클라이언트가 오직 건강한 파드에만 요청을 보내고 시스템에 문제가 있음을 알지 못하게 할 수 있다.

Readiness Probe 생성

kubectl edit 명령을 사용하여 ReplicationController 혹은 Deployment 의 YAML을 열고, spec.template.spec.containers 아래 첫 번째 컨테이너에 다음과 같이 readiness probe를 정의한다.

apiVersion: v1
kind: ReplicationController
...
spec:
  ...
  template:
... spec:
      containers:
      - name: kubia
        image: luksa/kubia
        readinessProbe:       
          exec:
            command:
            - ls
            - /var/ready
...

 

준비성 프로브는 컨테이너 내부에서 주기적으로 ls /var/ready 명령을 실행한다. ls 명령은 파일이 존재하면 종료 코드를 0으로 반환하고, 그렇지 않으면 비정상적인 종료 코드를 반환한다.

Startup Probe

시작 프로브(Startup Probe)는 컨테이너가 정상적으로 시작되었는지 확인하는 역할을 한다. 일반적인 경우 애플리케이션이 실행되기 전에 초기화 과정이 필요한 경우가 많으며, 이 과정에서 애플리케이션이 즉시 준비되지 않을 수 있다. 시작 프로브가 설정되지 않으면, Kubernetes는 라이브니스 프로브를 통해 컨테이너의 상태를 감시하게 되며, 초기화 시간이 긴 애플리케이션의 경우 라이브니스 프로브가 실패하여 컨테이너가 불필요하게 재시작될 수 있다.

Startup Probe 필요성

특정 애플리케이션은 기동 시 많은 초기화 작업을 수행하므로, 일반적인 라이브니스 프로브보다 더 긴 유예 시간이 필요할 수 있다. 시작 프로브를 활용하면 애플리케이션이 완전히 실행될 때까지 라이브니스 프로브가 트리거되지 않도록 설정할 수 있다. 즉, 애플리케이션이 정상적으로 시작되면 이후 라이브니스 프로브를 통해 지속적으로 상태를 감시할 수 있다.

Startup Probe 유형

시작 프로브는 라이브니스 및 준비성 프로브와 동일한 방식으로 동작하며, 다음과 같은 세 가지 유형이 있다.

  • Exec 프로브: 컨테이너 내부에서 명령을 실행하고 종료 코드에 따라 상태를 판단
  • HTTP GET 프로브: 컨테이너에 HTTP GET 요청을 보내고 응답 상태 코드로 정상 여부를 확인
  • TCP 소켓 프로브: 지정된 포트로 TCP 연결을 시도하여 컨테이너가 수락하면 정상으로 간주

Startup Probe 작동 방식

Kubernetes는 컨테이너가 시작될 때 설정된 시간 동안 시작 프로브를 반복적으로 호출하여 애플리케이션이 정상적으로 실행되었는지 확인한다. 시작 프로브가 성공하면 Kubernetes는 라이브니스 프로브를 활성화하고 이후에는 라이브니스 프로브를 통해 컨테이너의 상태를 모니터링한다. 만약 시작 프로브가 여러 번 실패하면 Kubernetes는 컨테이너를 종료하고 다시 시작한다.

Startup Probe 추가 예시

apiVersion: v1
kind: ReplicationController
...
spec:
  ...
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:latest
        startupProbe:
          httpGet:
            path: /healthz
            port: 8080
          failureThreshold: 30
          periodSeconds: 10
  • /healthz 엔드포인트를 호출하여 상태를 확인합니다.
  • 최대 30번 실패할 때까지 컨테이너를 재시작하지 않습니다.
  • 10초마다 프로브를 실행합니다.
  • 즉, 최대 5분(30 * 10초)까지 애플리케이션의 초기화 시간을 보장할 수 있습니다.

Startup Probe 활용 사례

  • 기동 시간이 긴 애플리케이션
    • Java 기반 애플리케이션(JVM 기동)
    • 복잡한 초기화 과정이 필요한 대형 애플리케이션
  • 데이터베이스 의존성이 있는 애플리케이션
    • 외부 서비스(DB, API 등)가 준비되기 전에 애플리케이션이 기동될 경우
  • 캐시 로딩이 필요한 애플리케이션
    • 초기에 많은 데이터를 로드해야 하는 서비스

Startup Probe 고려 사항

  • Startup Probe를 설정하면, Liveness Probe가 즉시 동작하지 않음
  • failureThreshold와 periodSeconds를 적절히 조정해야 불필요한 재시작을 방지할 수 있음
  • 애플리케이션 초기화 단계에서 반드시 성공할 수 있는 엔드포인트를 설정해야 함

'Kubernetes & EKS > k8s 공부 기록' 카테고리의 다른 글

[kubernetes] EKS 파드 스케줄링: podAntiAffinity  (0) 2025.03.31
[kubernetes] Taint and Tolerance  (0) 2025.03.31
[kubernetes] Resource Requirements and Limits  (0) 2025.03.14
[kubernetes] Node Selector & Node Affinity  (0) 2025.03.14
[kubernetes] RollingUpdate 와 PodDisruptionBudget(PDB)  (1) 2025.03.08
'Kubernetes & EKS/k8s 공부 기록' 카테고리의 다른 글
  • [kubernetes] Taint and Tolerance
  • [kubernetes] Resource Requirements and Limits
  • [kubernetes] Node Selector & Node Affinity
  • [kubernetes] RollingUpdate 와 PodDisruptionBudget(PDB)
Hyukops
Hyukops
안녕하세요
  • Hyukops
    Hyukops 님의 Tech Blog
    Hyukops
    • 분류 전체보기 (141)
      • Introduction (1)
      • Kubernetes & EKS (43)
        • k8s in action (9)
        • k8s 공부 기록 (17)
        • k8s 운영 가이드 (10)
        • k8s 운영 특이사항 (7)
      • Service Mesh (29)
        • Istio 공부 기록 (20)
        • Istio 운영 특이사항 (9)
      • CICD (10)
        • argoCD 공부 기록 (6)
        • argoCD 운영 특이사항 (4)
      • Logging & Monitoring (5)
        • Prometheus 운영 특이사항 (0)
        • fluent bit 운영 특이사항 (5)
      • Infrastructure as Code (8)
        • terraform 공부 기록 (3)
        • terraform 운영 특이사항 (5)
      • AWS (40)
        • aws 공부 기록 (29)
        • 솔루션 사례 & 문제 해결 (11)
      • Database (5)
        • postgreSQL (5)
  • 태그

    prometheus
    eks
    kubernetes
    argocd
    fluentbit
    Istio
    Database
    k8s in action
    fluent bit
    Terraform
    MSK
    aws saa
    canary
    PostgreSQL
    Logging
    AWS
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Hyukops
[kubernetes] Pod 헬스 체크 (Probe)
상단으로

티스토리툴바