k8s livenessProbe를 이용한 self-healing

Kubernetes의 self-healing

k8s는 자체적으로 self-healing이 가능합니다. 시스템이 영향받을 때 마다 pod, container 단위로 상태를 감지하고, 비정상적인 경우 자체적으로 교체하여 최대한 안정적인 서비스를 유지할 수 있도록 도와줍니다.

Self-healing Kubernetes restarts containers that fail, replaces containers, kills containers that don’t respond to your user-defined health check, and doesn’t advertise them to clients until they are ready to serve.

livenessProbe

k8s가 아무런 설정 없이 자체적으로 모든 실패한 케이스에 대해 식별할 수 없습니다. 물론 배포 단계나 운영중에 container, pod 자체에 죽는 등의 문제가 생기는건 k8s가 식별할 수 있어서 바로 replica와 교체하면서 운영 pod를 유지하며 빠르게 교체가 가능하지만, pod 내 사용자가 만든 applicaion에서 panic 등 실제 application이 죽지 않는 경우의 에러 형태는 감지할 수 없습니다.

만약 GET /api/status 의 response가 500인 경우 장애로 판단해야하는 경우는 어떨까요? 아무런 설정없이 k8s는 이를 장애 상황이라고 판단하기 어렵습니다. 그래서 k8s는 liveness라는 probe를 통해 pod의 상태를 식별할 수 있도록 제공합니다. 이는 사용자가 정의해둔 로직에 따라서 구별할 수 있습니다.

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: livenessTest
    image: imageAddress
    livenessProbe:
      httpGet:
        path: /api/status
        port: 8080
        httpHeaders:
        - name: X-API-Key
          value: IfHaveAPIKeyWriteThis
      initialDelaySeconds: 1
      periodSeconds: 3

위 yaml을 보면 이러한 절차로 동작이 수행되겠네요.

1) 3초 마다 livenessProbe를 수행함. 이 때 시작 전 1초의 딜레이를 가짐 2) livenessProbe가 시작되면 GET host:8080/api/status 로 웹 요청이 발생함 3) 이 때 header는 X-API-Key: IfHaveAPIKeyWriteThis 가 포함되어 전송 됨 4) 성공(200-399) 시 Pass, 실패(나머지) 시 Container를 재 시작함

여기서 하나 주의깊게 봐야할 점은 HTTP Response Code가 200~399번때 까지는 Success, 나머지는 Fail 로 본다는 점입니다. 이점만 유의하면 사용에 크게 어려운 부분은 없습니다.

추가로 livenessProbe에 httpGet 으로 지정된 부분은 livenessProbe에서 HTTPGetAction 액션 사용을 위한 내용이며, 다른 액션을 사용하면 TCP 기반이나 Exec 기반으로도 점검이 가능합니다.

livenessProbe Action

총 3가지를 지원하며 내용은 아래와 같습니다.

Action Description
HTTPGetAction 지정된 포트와 URL로 GET 요청 후 Response Status Code가 200~399까지 성공으로 판단
ExecAction 컨테이너 내부에서 명령 실행 후 Return이 0이면 성공으로 판단
TCPSocketAction 특정 IP에 대해 TCP Connection 수행, 포트가 활성화 되어 있다면 성공으로 판단

Other Probe

이외에도 다른 Probe도 존재합니다.

Probe Description
livenessProbe 컨테이너의 동작 여부 판단. 만약 실패로 판단되면 kubelet은 container를 재 시작함
readinessProbe 컨테이너가 준비되었는지 판단. 만약 실패라면 Pod의 IP가 연관된 Service에서 제거됨
startupProbe 컨테이너 내 어플리케이션이 시작되었는지 판단. 실패하면 재시작

결과는 공통으로 사용됩니다. Success: 성공 / Failure: 실패 / Unknown: probe 실패로 액션 수행 안함

References