🔎Kubernetes의 Container Probe란?

Kubernetes에서 Pod를 배포하면 Pod에서 정의한 컨테이너가 실행되는데요. 컨테이너 내부에서 실행되어야 하는 프로세스가 정상 작동할 때 비로소 Pod를 통해 원하는 서비스를 이용할 수 있게 됩니다.

Pod를 배포하고 운영하다보면 동작 중이던 컨테이너의 상태가 정상인지 주기적으로 확인이 필요할 때가 있습니다. 혹은 해당 컨테이너가 외부 트래픽을 받을 준비가 되었는지 알아야 할 때도 있죠.

이렇게 컨테이너의 상태를 주기적으로 진단할 때 사용하는 것이 바로, Container Probe입니다.

🩺Container Probe의 진단 유형과 Probe의 종류

Kubernetes의 Container Probe는 Manifest의 컨테이너 레벨에서 정의되는데요. 정의된 진단 설정에 따라 kubelet이 해당 컨테이너 내부에서 주기적으로 진단을 수행합니다.

Probe는 아래와 같이 4가지 방법 중 하나로 컨테이너의 상태를 진단할 수 있습니다.

  • exec
    • 컨테이너 내부에서 실행할 명령어 지정
    • 명령어 실행 후 상태 코드가 0이면 성공으로 진단
    • exec는 수행될 때마다 컨테이너 내에 새로운 프로세스가 생성되기 때문에 Node의 CPU 사용량이 증가할 수 있으므로 주의가 필요
  • grpc
    • gRPC 요청으로 진단하며, gRPC Health Check이 미리 구현되어 있어야 함
    • 응답 status가 SERVING이면 성공으로 진단
  • httpGet
    • 특정 port 및 path로 Pod의 IP에 대해 HTTP GET 요청으로 진단
    • 응답 status code가 200 이상 400 미만이면 성공으로 진단
  • tcpSocket
    • 특정 port로 Pod의 IP에 대해 TCP 요청으로 진단
    • 해당 port가 열려 있으면 성공으로 진단

이렇게 수행한 진단 결과는 아래 3가지 중 하나로 나옵니다.

  • Success: 진단 성공
  • Failure: 진단 실패
  • Unknown: 진단 실패, Faliure와 달리 kubelet이 추가 진단 실행

kubelet이 수행하는 Probe는 아래와 같이 3가지 유형으로 나뉘는데요.

  • Readiness Probe
  • Liveness Probe
  • Startup Probe

각 Probe에 대해 아래에서 더 자세히 알아보겠습니다.

✨Readiness, Liveness, Startup Probe

Readiness Probe

Readiness Probe트래픽과 관련이 있는데요. Readiness Probe를 사용하면 해당 컨테이너로 트래픽이 들어오는 시점을 제어할 수 있기 때문입니다.

즉, 컨테이너의 상태 진단 결과가 성공인 시점부터 해당 컨테이너에 트래픽이 들어오는 것을 허용하고 싶을 때 Readiness Probe를 사용하는 것이죠.

각 Probe는 컨테이너 레벨에서 정의한다고 했는데요. 아래 Pod Manifest 예제로 Probe를 어떻게 정의하는지 알아보겠습니다.

apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: registry.k8s.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:  # Readiness Probe를 정의하는 부분입니다.
      httpGet:
	    path: /healthz
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 10

위 예제에서 Readiness Probe를 정의하는 부분만 살펴보면 해당 Probe의 작동 방식은 아래와 같습니다.

  • 위 Readiness Probe는 HTTP GET 요청으로 진단 수행 (httpGet)
  • HTTP GET 요청을 보내는 Port와 경로는 8080/healthz
  • kubelet이 첫 Probe 진단을 수행되는 시점은 컨테이너 실행 후 15초 뒤 (initialDelaySeconds)
  • kubelet은 10초 간격으로 Probe 진단 수행 (periodSeconds)

위 예제에선 컨테이너에 readinessProbe 하나만 정의되었지만, 필요에 따라 컨테이너에 대해 Probe를 종류별로 모두 정의할 수도 있습니다.

Liveness Probe

Liveness Probe는 동작 중인 컨테이너의 상태를 주기적으로 진단할 때 사용됩니다.

Kubernetes에 배포된 컨테이너의 프로세스에 이슈가 생기거나 프로세스의 상태가 Unhealthy인 경우, kubelet이 이를 감지하여 자동으로 Pod의 restartPolicy(재시작 정책)에 따라 조치를 취하기 때문에 Liveness Probe가 반드시 필요한 것은 아닙니다.

하지만 Probe의 컨테이너 상태 진단 결과에 따라 종료 또는 재시작이 필요한 경우라면 Liveness Probe를 사용할 수 있습니다.

위 예제 코드에서 봤던 것처럼, 모든 Probe는 spec.containers 레벨에서 정의할 수 있는데요. 위 코드에 exec를 수행하는 Liveness Probe를 추가로 정의한다면 아래와 같겠습니다.

spec:
  containers:
  - name: goproxy
    image: registry.k8s.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:  # Readiness Probe를 정의하는 부분입니다.
      httpGet:
	    path: /healthz
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 10
    livenessProbe:  # 동일한 컨테이너에 대해 Liveness Probe를 추가로 정의했습니다.
      exec:
        command:
		- cat
		- /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

위 예제처럼 Liveness Probe와 Readiness Probe를 동일한 컨테이너에 대해 함께 사용할 경우, 아래와 같이 각 Probe의 역할 수행을 기대할 수 있습니다.

  • Readiness Probe로 해당 컨테이너가 준비될 때까지 들어오는 트래픽 제어
  • Liveness Probe로 해당 컨테이너 동작 중에 진단 실패 시 자동으로 재시작

Startup Probe

마지막으로 Startup Probe는, 그 이름처럼 컨테이너가 정상적으로 시작했는지 여부를 진단합니다.

가동하는 데에 시간이 오래 걸리는 컨테이너의 상태를 진단해야 하는 경우라면, Liveness Probe의 periodSeconds 값을 길게 설정해서 진단 주기를 넓히기보다는 Startup Probe를 정의해서 컨테이너의 시작 성공 여부를 파악하는 것이 좋은데요.

그래야 Liveness Probe로는 동작 중인 컨테이너의 상태를 적절한 주기로 진단할 수 있기 때문입니다.

Startup Probe는 아래와 같이 정의할 수 있습니다.

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

위 예제를 보면 failureThreshold(최대 실패 허용 횟수) 값이 설정되어 있는데요.

해당 Startup Probe는 최대 300초(30 * 10) 동안 주기적으로 컨테이너가 정상적으로 실행했는지를 진단하고, 300초가 지나도록 진단에 실패하면 Pod의 restartPolicy(재시작 정책)에 따라 컨테이너를 재시작하거나 종료하게 됩니다.

한 가지 참고할 점은, Startup Probe의 진단이 성공하기 전까진 Readiness Probe와 Liveness Probe가 실행되지 않다는 것입니다.

이렇게 각 Probe는 수행 시점과 역할이 조금씩 다르기 때문에, 컨테이너의 성격이나 운영 정책에 따라 적절한 조합으로 Probe를 사용한다면 더욱 효과적으로 Pod를 배포하고 운영할 수 있습니다.

References