본문 바로가기
Framework and Tool/Kubernetes

Kubernetes - Liveness probe

by ocwokocw 2022. 10. 10.

- 출처: Kubernetes in action

- 파드 유지

쿠버네티스의 최대 장점은 컨테이너 목록을 제공하면 관리자가 신경쓰지 않아도 클러스터 어딘가에서 계속 실행되고 있다고 믿을 수 있다는것이다.
 
파드가 워커 노드에 스케줄링되면 노드의 kubelet은 컨테이너를 실행한다. 이때 주 프로세스에 crash가 발생하면 kubelet은 컨테이너를 재시작한다. 
 
하지만 문제는 앱이 쓸 수 없게 되는 상황에서 언제나 crash가 발생하지는 않는다는것이다. 예를 들어 자바 앱에서 메무리 누수가 일어나는 경우 OOM이 일어날지언정 JVM 프로세스는 계속 실행된다. 이럴 경우 OOM 익셉션을 잡아서 재시작하면 되겠지만 이런식으로 모든 경우의 수를 대비할수는 없다.
 
그러므로 앱 내부 기능이 아닌 외부에서 앱의 상태를 체크해주는 무엇인가가 필요하다.
 

- 라이브니스 프로브

쿠버네티스는 라이브니스 프로브를 통해 컨테이너가 살아있는지 확인한다. 관련 설정은 Spec 섹션에 정의할 수 있으며 지정하면 일정 주기로 프로브를 실행한다.
 
쿠버네티스가 컨테이너에 프로브를 실행하는 매커니즘에는 3 가지 유형이 있다.
 
  • HTTP GET 요청(IP, 포트, 경로): 4xx나 5xx 응답이 아니면 성공으로 간주
  • TCP 소켓 프로브: 컨테이너의 지정된 포트에 TCP 연결
  • EXEC 프로브: 컨테이너내의 임의 명령 수행, 종료상태가 0이면 성공 그 외는 실패로 간주

- HTTP 기반 라이브니스 프로브 생성

보통 웹 앱의 경우에는 웹서버가 요청을 처리하는지 확인하는 라이브니스 프로브를 이용한다. 아래 예제는 일정 횟수의 요청 후에 실패를 응답하는 Node.js 앱 이미지를 이용 yaml 파일이다. spec.livenessProbe 섹션에 http get 프로브를 설정해주면 된다.
 
apiVersion: v1
kind: Pod
metadata:
  name: kubia-liveness
spec:
  containers:
  - image: luksa/kubia-unhealthy
    name: kubia
    livenessProbe: # http get liveness probe
      httpGet:
        path: / # http get path
        port: 8080 # http port
 
파드가 생성되고 시간이 조금 지나서(대략 2분) 파드를 조회한다.
 
 
 
"RESTARTS" 필드를 보면 파드가 컨테이너를 다시 시작 했음을 알 수 있다. 재시작해서 현재 잘 동작하고 있는 사실도 의미가 있겠지만 시스템 관리자라면 왜 다시 시작되었는지 궁금할것이다.
 
"kubectl descibe" 명령어로 조회해보면 컨테이너의 재시작 정보를 알 수 있다.
 
 
 
만약 종료된 이전 컨테이너의 로그를 보고 싶다면 "kubectl log [파드명] --previous"를 통해 조회할 수 있다.
 
 
 
종료코드에 해당하는 Exit Code 정보는 프로세스가 외부신호에 의해 종료 되었음을 나타낸다. 128 + x 로 구성되며, x는 프로세스에 전송된 신호이다. 137의 경우 x가 9(SIGKILL), 143의 경우 x가 15(SIGTERM)을 나타낸다.
 
describe 정보를 다시 한번 살펴보면 "Liveness" 정보도 알 수 있다. 각 항목은 다음을 의미한다.
 
  • delay=0s: 컨테이너 시작된 후 바로 프로브가 시작된다.
  • timeout=1s: 컨테이너가 1초 안에 응답하지 않으면 프로브가 실패한것으로 카운트된다.
  • period=10s: 10초 마다 프로브를 실행
  • failure=3: 프로브가 3번 연속 실패하면 컨테이너가 재시작된다.
 
기본적인 httpGet 외에도 livenessProbe 섹션에 추가적인 매개 변수를 지정할 수 있다. 예를 들어 초기지연을 설정하려면 initialDelaySeconds 속성을 라이브니스 프로브에 추가한다.
 
livenessProbe: # http get liveness probe
      httpGet:
        path: / # http get path
        port: 8080 # http port
      initialDelaySeconds: 15
 
보통 앱이 컨테이너가 시작되자 마자 응답할 수 있는 경우는 드물기 때문에 프로브가 바로 시작되면 안된다. 그래서 실질적으로는 초기지연으로 앱이 구동 완료되어 프로브에 응답할 시간까지 기다려줘야 한다.
 
만약 이 시간을 너무 짧게 할당하면 앱이 시작되기 전에 프로브를 여러 번 시도하고, 실패했다고 가정하여 컨테이너를 재시작하고 이 과정을 반복하여 무한루프에 빠지게 된다.

- 효과적인 라이브니스 프로브

라이브니스 프로브는 있으면 좋다는 정도가 아니라 운영 환경이라면 필수적으로 지정해야 한다.
 
그렇다면 라이브니스 프로브는 어떤 걸 확인해야 할까? 단순 http 요청 만으로도 없는것보다는 훨씬 좋다. 좋은 라이브니스 프로브는 보통 root가 아닌 특정 Path(ex - /health)로 요청한다. 그리고 서버는 해당 Path에서 구성요소가 살아있는지 확인한 후 상태에 따라 응답한다. 이때 특정 Path로 요청한다면 인증이 필요하지 않은지 확인해야 한다.
 
또한 프로브의 대상이 되는 컨테이너 내부상태만 확인해야 한다. 예를 들어 웹서버와 디비 컨테이너가 있고 디비에 장애가 발생하여 웹서버에서 디비로 요청하는 네트워크에 장애가 있다고 하더라도 웹서버에 대해서 프로브를 실행했을 때 웹서버가 이상없다면 성공을 반환해야 한다. 디비가 정상이 아니라고 해서 웹서버에 대한 프로브 요청에 실패로 응답하면 웹서버를 재시작할 것이므로 이런 조치가 디비 장애복구에 도움이 안되기 때문이다.
 
서버의 구성요소를 잘 확인하는것도 중요하지만 너무 무거운 연산을 하면 안된다. 또한 재시도 루프를 자체적으로 구현할 필요는 없는데 쿠버네티스는 실패 임계값을 1로 설정해도 프로브를 여러번 시도해서 필요가 없기 때문이다.

- 마치면서

쿠버네티스는 컨테이너의 주 프로세스에서 Crash가 발생하거나 라이브니스 프로브가 실패하면 컨테이너를 재시작한다. 이 작업은 파드를 호스팅하는 kubelet에서 수행하며 Control Plane(마스터노드)에서 관여하지는 않는다. 하지만 노드 자체가 다운되면 이로 인해 중단된 파드를 대체하여 생성하는 작업은 마스터 노드의 역할이다.
 
 

'Framework and Tool > Kubernetes' 카테고리의 다른 글

Kubernetes - ReplicaSet, DaemonSet  (0) 2022.10.14
Kubernetes - Replication controller  (0) 2022.10.11
Kubernetes - Namespace  (0) 2022.10.09
Kubernetes - Label 및 Annotation  (0) 2022.10.09
Kubernetes - Pod  (0) 2022.10.09

댓글