쿠버네티스 Liveness Probe

이준석·2023년 2월 15일
0

Liveness Probe 정의

오랜 시간 동안 실행되는 많은 응용 프로그램은 문제가 발생하면 중단된 상태로 전환되며 다시 시작해야만 복구할 수 있다.
Kubernetes는 이러한 상황을 감지하고 해결하기 위한 liveness probe를 제공한다.

1. liveness-exec.yaml 파일 생성

이 연습에서는 registry.k8s.io/busybox 이미지를 기반으로 컨테이너를 실행하는 Pod를 만든다.

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5
  • periodSeconds: kubelet이 5초마다 liveness probe를 수행하도록 지정

  • initialDelaySeconds: 첫 번재 probe를 수행하기 전에 5초 기다리는 것을 지정

  • /bin/sh -c "touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600": 처음 30초동안은 성공 코드를 반환, 30초 후에는 실패 코드를 반환하는 것을 지정

명령이 성공하면 0을 반환하고 kubelet은 컨테이너가 살아 있고 건강한 것으로 간주한다.
명령이 0이 아닌 값을 반환하면 kubelet은 컨테이너를 종료하고 다시 시작한다.

2. liveness-exec Pod 생성

kubectl apply -f exec-liveness.yaml

3. 30초 이내에 Pod 이벤트 확인

kubectl describe pod liveness-exec
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  12s   default-scheduler  Successfully assigned default/liveness-exec to minikube
  Normal  Pulling    9s    kubelet            Pulling image "registry.k8s.io/busybox"
  Normal  Pulled     6s    kubelet            Successfully pulled image "registry.k8s.io/busybox" in 3.120555208s (3.120582984s including waiting)
  Normal  Created    6s    kubelet            Created container liveness
  Normal  Started    6s    kubelet            Started container liveness

아직 Unhealthy 없이 정상이다.

4. 30초 이후에 Pod 이벤트 재확인

kubectl describe pod liveness-exec
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  95s                default-scheduler  Successfully assigned default/liveness-exec to minikube
  Normal   Pulled     89s                kubelet            Successfully pulled image "registry.k8s.io/busybox" in 3.120555208s (3.120582984s including waiting)
  Warning  Unhealthy  44s (x3 over 54s)  kubelet            Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  Normal   Killing    44s                kubelet            Container liveness failed liveness probe, will be restarted
  Normal   Pulling    14s (x2 over 92s)  kubelet            Pulling image "registry.k8s.io/busybox"
  Normal   Created    12s (x2 over 89s)  kubelet            Created container liveness
  Normal   Started    12s (x2 over 89s)  kubelet            Started container liveness

Unhealthy가 생겼고 해당 컨테이너가 종료되고 다시 생성됐음을 알 수 있다.

5. 30초 더 기다렸다가 파드 상태 확인

kubectl get pod liveness-exec
NAME            READY   STATUS    RESTARTS      AGE
liveness-exec   1/1     Running   1 (72s ago)   2m33s

RESTARTS가 1회 증가되었음을 알 수 있다.
RESTARTS는 실패한 컨테이너가 다시 생성됐을 때, 즉시 숫자가 증가한다.



Liveness HTTP 요청 정의

다른 종류의 liveness probe는 HTTP GET 요청을 사용한다.
다음은 registry.k8s.io/liveness 이미지를 기반으로 컨테이너를 실행하는 Pod를 만든다.

1. liveness-http.yaml 파일 생성

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3
  • periodSeconds: kubelet이 3초마다 liveness probe를 수행하도록 지정

  • initialDelaySeconds: 첫 번재 probe를 수행하기 전에 3초 기다리는 것을 지정

probe를 수행하기 위해 kubelet은 컨티이너에서 실행 중이고 포트 8080에서 수신 대기 중인 서버에 HTTP GET 요청을 보낸다.
서버의 경로에 대한 핸들러가 성공 /healthz 코드를 반환하면 kubelet은 컨테이너가 살아 있고 건강한 것으로 간주한다.
핸들러가 실패 코드를 반환하면 kubelet은 컨테이너를 종료하고 다시 시작한다.

200번대, 300번대 코드는 성공을 나타낸다.
다른 코드는 실패를 나타낸다.

server.go에서 서버의 소스 코드를 볼 수 있다.

http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
    duration := time.Now().Sub(started)
    if duration.Seconds() > 10 {
        w.WriteHeader(500)
        w.Write([]byte(fmt.Sprintf("error: %v", duration.Seconds())))
    } else {
        w.WriteHeader(200)
        w.Write([]byte("ok"))
    }
})

컨테이너가 활성 상태인 처음 10초 동안 /healthz 핸들러는 상태 코드 200을 반환한다.
그 후 핸들러는 상태 코드 500을 반환한다.

위의 yaml 파일에서 컨테이너가 시작된 후 3초 기다린 후에 상태 확인을 시작하고 3초마다 상태 확인을 하니, 첫 번째 두 개의 상태 확인은 성공한다.
그러나 10초 후에는 상태 확인에 실패하고 kubelet이 컨테이너를 종료하고 다시 시작한다.

2. liveness-http Pod 생성

kubectl apply -f liveness-http.yaml

3. 10초 이후에 Pod 이벤트를 확인

kubectl describe pod liveness-http
Events:
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  27s               default-scheduler  Successfully assigned default/liveness-http to minikube
  Normal   Pulled     23s               kubelet            Successfully pulled image "registry.k8s.io/liveness" in 2.507501709s (2.507541747s including waiting)
  Normal   Pulling    5s (x2 over 26s)  kubelet            Pulling image "registry.k8s.io/liveness"
  Warning  Unhealthy  5s (x3 over 11s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 500
  Normal   Killing    5s                kubelet            Container liveness failed liveness probe, will be restarted
  Normal   Created    4s (x2 over 23s)  kubelet            Created container liveness
  Normal   Pulled     4s                kubelet            Successfully pulled image "registry.k8s.io/liveness" in 1.552769347s (1.55277954s including waiting)
  Normal   Started    3s (x2 over 23s)  kubelet            Started container liveness

10초 이후 Unhealthy가 생겼고 해당 컨테이너가 종료되고 다시 생성됐음을 알 수 있다.



참고 자료

Kubernetes Documentation

0개의 댓글