질문정리
애플리케이션에 HTTP 500과 같은 에러가 발생한 경우, 컨테이너를 다시 실행해야 할 것 입니다. HTTP 에러가 발생했다는 것을 어떻게 알 수 있을까요? 어떻게 해야 쿠버네티스가 에러가 발생한 컨테이너를 자동으로 재시작하게 만들 수 있을까요? (힌트: liveness probe 키워드를 검색하세요)
질문 재정의 :
컨테이너를 굉장히 많이 띄워보려한다. 한 백만번 띄웠는데 그 중에 300번 쯤 실패했다는 로그를 봤다. 그 때 마다 직접 새로 컨테이너를 띄울 수는 없다. 자동화를 하자. 어떻게 할까
1) 어떤 에러로 실패했는지 알아내야한다.
2) 어떻게 일일이 살피지 않고 자동으로 컨테이너를 재시작 할 수 있을까.
1) 어떤 에러로 실패했는지 알아내야한다.
컨테이너의 라이프 사이클 : pending -> running -> succeeded or failed or unknown
이 중에 에러가 발생하는지 알아내야하는데, 그걸 kubelet이 해준다.
파드가 실행되는 동안, kubelet은 일종의 오류를 처리하기 위해 컨테이너를 다시 시작할 수 있다. 파드 내에서, 쿠버네티스는 다양한 컨테이너 상태를 추적하고 파드를 다시 정상 상태로 만들기 위해 취할 조치를 결정한다.
- 쿠버네티스 공식문서
kubelet 이란,
클러스터의 각 노드에서 실행되는 에이전트. Kubelet은 파드에서 컨테이너가 확실하게 동작하도록 관리한다. Kubelet은 다양한 메커니즘을 통해 제공된 파드 스펙(PodSpec)의 집합을 받아서 컨테이너가 해당 파드 스펙에 따라 건강하게 동작하는 것을 확실히 한다. Kubelet은 쿠버네티스를 통해 생성되지 않는 컨테이너는 관리하지 않는다.
- 쿠버네티스 공식문서
에러 체크 == 상태 추적
상태 추적을 할 도구는? 컨테이너 라이프사이클 훅, 일종의 api
훅에는 두 가지 종류가 있는데, 일단 pre stop이 특정 이벤트 발생시 종료, 재시작 등에 관여함.
이 훅을 쓰려면 훅 핸들러가 필요하고 훅 핸들러 종류에는 Exec / HTTP 두 종류가 있다.
컨테이너 라이프사이클 관리 훅이 호출되면, 쿠버네티스 관리 시스템은 훅 동작에 따라 핸들러를 실행하고, httpGet 와 tcpSocket 은 kubelet 프로세스에 의해 실행되고, exec 은 컨테이너에서 실행된다.
다음과 같이 프로브(탐침). //이건 yaml에 정의해둠
- exec: 성공시 0을 반환 //container
- httpGet: (200 <= code < 400) ? true : false // kubelet, 프로브에서 httpGet 사용 > kubelet 프로세스 실행 > 컨테이너의 훅 핸들러 실행 > 상태 응답 받기
- tcpSocket: http검사와 유사하며 tcp 연결을 합니다. //kubelet
- 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
https://kimjingo.tistory.com/153
https://kubernetes.io/ko/docs/concepts/storage/volumes/
https://velog.io/@jm1225/livenessProbe
https://kubernetes.io/ko/docs/concepts/workloads/pods/pod-lifecycle/
https://kubernetes.io/ko/docs/concepts/containers/container-lifecycle-hooks/
'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 |