Infra & DevOps/k8s(EKS)

[Kubernetes] http 에러 검증, 파드, pv

용감한 개복치 2022. 4. 26. 16:48

질문정리


애플리케이션에 HTTP 500과 같은 에러가 발생한 경우, 컨테이너를 다시 실행해야 할 것 입니다. HTTP 에러가 발생했다는 것을 어떻게 알 수 있을까요? 어떻게 해야 쿠버네티스가 에러가 발생한 컨테이너를 자동으로 재시작하게 만들 수 있을까요? (힌트: liveness probe 키워드를 검색하세요)

 

질문 재정의 :

컨테이너를 굉장히 많이 띄워보려한다. 한 백만번 띄웠는데 그 중에 300번 쯤 실패했다는 로그를 봤다. 그 때 마다 직접 새로 컨테이너를 띄울 수는 없다. 자동화를 하자. 어떻게 할까

 

  1) 어떤 에러로 실패했는지 알아내야한다.

  2) 어떻게 일일이 살피지 않고 자동으로 컨테이너를 재시작 할 수 있을까.

 

1) 어떤 에러로 실패했는지 알아내야한다.

컨테이너의 라이프 사이클 : pending -> running -> succeeded or failed or unknown

쿠버네티스 공식문서 pod의 상태요약

이 중에 에러가 발생하는지 알아내야하는데, 그걸 kubelet이 해준다.

파드가 실행되는 동안, kubelet은 일종의 오류를 처리하기 위해 컨테이너를 다시 시작할 수 있다. 파드 내에서, 쿠버네티스는 다양한 컨테이너 상태를 추적하고 파드를 다시 정상 상태로 만들기 위해 취할 조치를 결정한다.

- 쿠버네티스 공식문서

 

kubelet 이란,

클러스터의 각 노드에서 실행되는 에이전트. Kubelet은 파드에서 컨테이너가 확실하게 동작하도록 관리한다. Kubelet은 다양한 메커니즘을 통해 제공된 파드 스펙(PodSpec)의 집합을 받아서 컨테이너가 해당 파드 스펙에 따라 건강하게 동작하는 것을 확실히 한다. Kubelet은 쿠버네티스를 통해 생성되지 않는 컨테이너는 관리하지 않는다.

- 쿠버네티스 공식문서

 

에러 체크 == 상태 추적

상태 추적을 할 도구는? 컨테이너 라이프사이클 훅, 일종의 api

훅에는 두 가지 종류가 있는데, 일단 pre stop이 특정 이벤트 발생시 종료, 재시작 등에 관여함.

이 훅을 쓰려면 훅 핸들러가 필요하고 훅 핸들러 종류에는 Exec / HTTP 두 종류가 있다.

컨테이너 라이프사이클 관리 훅이 호출되면, 쿠버네티스 관리 시스템은 훅 동작에 따라 핸들러를 실행하고, httpGet  tcpSocket 은 kubelet 프로세스에 의해 실행되고, exec 은 컨테이너에서 실행된다.

 

다음과 같이 프로브(탐침). //이건 yaml에 정의해둠

  1. exec: 성공시 0을 반환 //container
  2. httpGet: (200 <= code < 400) ? true : false // kubelet, 프로브에서 httpGet 사용 > kubelet 프로세스 실행 > 컨테이너의 훅 핸들러 실행 > 상태 응답 받기  
  3. tcpSocket: http검사와 유사하며 tcp 연결을 합니다.  //kubelet
  4. grpc: etcd pod을 생성하여 gRPC 상태 확인 프로토콜을 구현합니다. //프로토콜의 일종

  2) 어떻게 일일이 살피지 않고 자동으로 컨테이너를 재시작 할 수 있을까.

파드의 spec 에는 restartPolicy 필드가 있다. 사용 가능한 값은 Always, OnFailure 그리고 Never이다. 기본값은 Always이다. restartPolicy 는 파드의 모든 컨테이너에 적용된다. restartPolicy 는 동일한 노드에서 kubelet에 의한 컨테이너 재시작만을 의미한다. 파드의 컨테이너가 종료된 후, kubelet은 5분으로 제한되는 지수 백오프 지연(10초, 20초, 40초, …)으로 컨테이너를 재시작한다. 컨테이너가 10분 동안 아무런 문제없이 실행되면, kubelet은 해당 컨테이너의 재시작 백오프 타이머를 재설정한다

// 파드의 spec 안에 restartPolicy 필드에서 정의해준다.

 

왜 파드와 PV(퍼시스턴스볼륨)를 직접 연결하지 않는걸까요?

 

파드와 pv를 직접 연결하지 않는다면 어떻게 파드는 pv를 활용하는가. => pvc를 통해 pv를 활용

 

pv란, persistence volume. 즉 stateless한 컨테이너와 달리 유지되는 볼륨. 볼륨이란 컨테이너 내부에서 관리되는 디스크 자원으로 쉽게말해 저장소. 컨테이너는 상태 지속성이 없는 특징을 가지기 때문에 컨테이너 간의 디스크 공유가 어렵다. 자유롭게 컨테이너를 만들고 부수고 하되, 데이터에서는 stateless한 상태를 보완하기 위해 추상화 볼륨의 개념을 도입.

쉽게 말해 가상의 저장소를 만든 것. 이 가상의 저장소 중에서 (볼륨 종류 많음) 컨테이너의 상태와 상관없이 지속되는 볼륨을 persistence volume으로 정의.

 

pv의 필요성 :

직접적인 물리 스토리지와의 연결은 데이터 손실의 위험과 관리의 어려움이 존재 + 컨테이너간의 데이터 공유 및 stateless한 상태 보완 하고싶음 = 가상화된 쿠버네티스 내부의 리소스인 pv 만듦.

 

그렇다면, pod는 어떻게 pv에게 요청을 보내는 걸까 => pvc를 활용 or pod에 직접 활용할 pv 정의

pvc란, persistence volume claim. pod의 사용자가 pv에게 요청하는 것들의 모음집.

pvc의 필요성 :

  1) 각각의 파드는 유동적으로 상황에 따라 필요한 스토리지의 종류가 다르다. 알아서 할당 해 주면 좋겠다.

  2) 파드는 선언적 방식으로 정의 되기 때문에 스토리지에 대해 동적할당을 하기 힘들다. 파드는 언제 어떻게 생성되고 없어질지 모른다. 파드의 stateless한 장점을 살리기 위해서 동적으로 자원이 분배되어야 한다. 

  3) pv의 원래 목적인 유동적 컨테이너 상황과 별개로 데이터의 보존을 위해 pv자체가 pod의 생성 및 삭제와 상관없이 보존되어야함. 이러한 사고를 방지하기 위해 중간에 바인딩을 위한 pvc 존재.

 

 

 

 

*** 참고 문헌 ***

https://arisu1000.tistory.com/27849

 

쿠버네티스 볼륨(kubernetes volume : PersistentVolume, PersistentVolumeClaim)

컨테이너는 기본적으로 상태가 없는(stateless) 앱을 사용합니다. 상태가 없다는건 어떤 이유로건 컨테이너가 죽었을때 현재까지의 데이터가 사라진다는 것입니다. 상태가 없기 때문에 컨테이너

arisu1000.tistory.com

https://kimjingo.tistory.com/153

 

[k8s] Volume - PV/PVC(퍼시스턴트 볼륨과 퍼시스턴트 볼륨 클레임)

쿠버네티스에서 볼륨(Volume)을 사용하는 구조는 PV라고 하는 퍼시스턴트 볼륨(PersistentVolume)과 PVC라고 하는 퍼시스턴트 볼륨 클레임(PersistentVolumeClaim) 2개로 분리되어 있습니다. PV/PVC PV는 볼륨 자..

kimjingo.tistory.com

https://kubernetes.io/ko/docs/concepts/storage/volumes/

 

볼륨

컨테이너 내의 디스크에 있는 파일은 임시적이며, 컨테이너에서 실행될 때 애플리케이션에 적지 않은 몇 가지 문제가 발생한다. 한 가지 문제는 컨테이너가 크래시될 때 파일이 손실된다는 것

kubernetes.io

https://velog.io/@jm1225/livenessProbe

 

livenessProbe

컨테이너 시작시 {initialDelaySeconds}초 대기 후, 컨테이너에 연결을 시도하고 {periodSeconds}초마다 수행, 탐침이 원하는 값이 아닌 값을 반환시 컨테이너를 재시작 한다.

velog.io

https://kubernetes.io/ko/docs/concepts/workloads/pods/pod-lifecycle/

 

파드 라이프사이클

이 페이지에서는 파드의 라이프사이클을 설명한다. 파드는 정의된 라이프사이클을 따른다. Pending 단계에서 시작해서, 기본 컨테이너 중 적어도 하나 이상이 OK로 시작하면 Running 단계를 통과하

kubernetes.io

https://kubernetes.io/ko/docs/concepts/containers/container-lifecycle-hooks/

 

컨테이너 라이프사이클 훅(Hook)

이 페이지는 kubelet이 관리하는 컨테이너가 관리 라이프사이클 동안의 이벤트에 의해 발동되는 코드를 실행하기 위해서 컨테이너 라이프사이클 훅 프레임워크를 사용하는 방법에 대해서 설명한

kubernetes.io

 

'Infra & DevOps > k8s(EKS)' 카테고리의 다른 글

[EKS] Observability  (0) 2024.03.31
[EKS] Storage  (0) 2024.03.22
[EKS] network  (0) 2024.03.17
[EKS] VPC CNI  (1) 2024.03.16
[EKS] 설치 및 기본 사용  (0) 2024.03.10