쿠버네티스 어나더 클래스 지상편: Sprint1 Day6 Probe

쿠버네티스를 공부하다 경계를 해야 되는 상황

기능을 내가 하는 프로젝트에 적용시키고자 할 때: 기능을 적용해서 운영에 불편한 관리 요소가 더 생기는 건 아닌지, 오히려 시스템의 복잡도만 더 증가시키는 건 아닌지에 대해서 충분히 고민하지 않는 경우가 있다.

예) 전체적인 시스템에 대해서 방화벽이 관리되고 있는데, 쿠버네티스의 NetworkPolicy 오브젝트(Pod들 간의 방화벽 역할 기능)를 적용하는 경우: 별도의 내부 방화벽 정책을 또 사용해야 될지에 대해서 충분히 고민해봐야 한다.

 

Probe

의도하지 않는 상황에서 Pod가 죽을 때 Probe에 의해 죽는 경우가 많다.→ Probe에 대해 깊이 있게 아는게 중요하다.

 

Probe 사용법

startupProbe
	httpGet:
	path: "/ready"
	port: 8080
	periodSeconds: 10
	successThreshold: 1
	failureThreshold: 10
readinessProbe
	httpGet:
	path: "/ready "
	port: 8080
	periodSeconds: 10
	successThreshold: 1
	failureThreshold: 2
livenessProbe
	httpGet:
	path: "/ready "
	port: 8080
	periodSeconds: 10
	successThreshold: 1
	failureThreshold: 2
  1. /ready URL로 :8080 포트를 사용해 10 초 간격으로 Probe를 전송한다.

  2. 컨테이너에는 /ready 라는 URL이 사전에 만들어져 있어야한다.

  3. Pod가 만들어지자 마자 Probe 기능들이 동작된다. → App은 기동 중인 상태

  4. startupProbe 실행: 오브젝트 속성대로 10초에 한 번씩 /ready 라는 API 요청을 App에 전송한다.

  5. 기동 중에는 응답을 받을 수 없으므로 계속 실패할 것이다.

  6. 10번의 요청 중 1회라도 응답이 있으면(성공) → K8s는 startupProbe 기능을 중지 → readinessProbe와 livenessProbe 기능을 동작시킵니다.

  7. readinessProbe와 livenessProbe는 오브젝트 속성대로 /ready 라는 API를 10초 간격으로 반복해서 요청합니다. → App이 살아있는 동안 200 OK 응답을 반환하며 readinessProbe와 livenessProbe 동작이 반복됨

 

readinessProbe와 livenessProbe 차이점

readinessProbe: 성공을 했을 때 외부 트래픽을 Pod가 받을 수 있는 상태로 만듦 → 서비스 활성화

livenessProbe: App이 살아있는지를 계속 체크하는 역할 → 장애가 발생하면 K8s는 App을 재기동 시킴

일반적으로 자신의 App 기동 시간에 따라 startupProbe 실패 수만 조정해서 쓰는게 대부분이다. 처음에 이렇게 사용할 때마다 API를 각각 다르게 지정하는 부분에 의문을 가질 수 있다. 어차피 장애가 나면 livenessProbe와 readinessProbe는 같이 실패를 할텐데 굳이 readinessProbe도 계속 호출이 될 필요가 있을까?

 

Application 로그를 통한 프로브 동작 분석

Pod가 실행되자마자 K8s는 startupProbe 동작 → 실제 App 상황에서는 App이 기동되기 전 초기부터 API 요청이 실패함 (WAS를 사용할 경우 access.log에 기록된다)

App 시작된 이후 startupProbe 성공, readinessProbe 실패, livenessProbe 성공됨: 사용자 초기화 구간에는 readinessProbe 가 실패되도록 의도한 것임

 

K8s에서 App을 편하게 관리하기 위해 Probe가 만들어졌다.

K8s를 사용하기 전에는 App을 기동시키고 운영자가 직접 API를 찔러보면서 상태 체크를 하고, App이 잘 동작하면 L4 스위치를 수정해서 외부 트래픽을 유입시켰다.

모니터링 화면에서 장애 알람을 받으면 운영자가 시스템에 접속해서 App을 다시 살렸다.

→ Probe가 자동화 기능을 제공한다

 

Probe의 자동화 과정

모든 App 에는 초기화 과정(트래픽을 받을 수 있는 준비를 하는 과정)이 있다: Pod 생성 → Jar 파일 실행 → Spring 초기화 → DB 연결

⇒ APP 초기화 중에는 API를 받을 수 없는 상태이다: 외부 API 접근 차단 필요

초기화가 완료되었는지 App 상태 체크

 

User 초기화 과정: 초기 데이터를 로딩 / 필수로 연결시켜야하는 시스템이 있어 연동 시스템이 살아있는지 체크 / DB 데이터에 대한 검증(Validation) 과정

⇒ App이 기동되었으므로 API를 받을 수 있는 상태이나 여전히 외부 API 접근 차단 필요

App이 살아있는지 App 상태 체크

 

App 기동

⇒ 외부 트래픽에 제대로 된 응답을 줄 수 있으므로 외부 API 접근 허용

App이 살아있는지 App 상태 체크는 여전히 필요

 

readinessProbe: Service를 Pod에 연결한다.

Service와 Pod를 Selector와 labels로 연결했더라도 K8s는 실제로 미리 연결하지 않는다. startupProbe가 성공하면 startupProbe 기능을 중지하고 → livenessProbe와 readinessProbe 기능을 활성화 시킨다

livenessProbe는 설정된 API를 계속 호출하면서 App이 잘 살아있는지 판단하고 API가 실패하면 장애라고 판단하고 Pod를 재기동시켜준다.

readinessProbe는 API 호출이 성공되기 전까지 Service를 Pod에 연결하지 않고 있다가 API 호출이 성공되면 두 오브젝트를 연결하고 트래픽이 들어오게 된다. 중간에 readinessProbe가 실패하게 되면 K8s는 연결을 해제했다가 성공 후 연결을 시킨다.

 

readinessProbe와 livenessProbe 사용의 주의점

readinessProbe는 유저 초기화 과정을 위해서 App은 기동이 됐지만 의도적으로 외부 트래픽을 받지 않게 할 때 사용할 의도가 있다면 readinessProbe와 livenessProbe의 API를 분리해야한다.

readinessProbe와 livenessProbe의 API는 App이 중지되기 전까지 지속적으로 API 요청을 받기 때문에 로직을 가볍게 만들어야한다.

 

일시적인 장애 상황에서 Probe를 더 잘 활용하는 방법

App이 서비스 중인 상태에서 갑자기 일시적인 장애가 발생하는 경우 App에 부하가 높아지고 Leak이 걸리거나 Thread Full이 찰 수 있다. 이러한 상황에서 외부에서 API 요청이 지속적으로 발생하면서 시스템이 멈추거나 시간이 지나 스스로 해결이 될 수도 있다.

그러나 이 과정에서 readinessProbe와 livenessProbe가 실패하게 되면 K8s는 Pod를 재기동시킨다. 시간이 지나면 App이 정상으로 돌아올 수 있는 상황에서 Probe에 의해 Pod가 재기동되면서 이전에 App에서 처리 중인 작업들은 모두 실패가 될 수 있다.

 

일시적인 부하 상황에서 readinessProbe는 실패 시 외부 API 접근을 금지시키고 App에 추가적인 부담을 감소시키기 때문에 그대로 둬도 된다. livenessProbe는 상태 체크 주기를 readinessProbe와 같지 않게, 실패하는데 걸리는 시간을 좀 더 길게 설정해서 Pod가 재기동 되는걸 더 지연시킨다.

중요한 시스템은 Pod를 이중화하므로 일시적인 장애에 빠르게 재기동 시키는 것이 좋은 방법이 아닐 수 있음을 고려한다.

댓글을 작성해보세요.

채널톡 아이콘