파드의 라이프 사이클
쿠버네티스의 트러블 슈팅 중 가장 많이 발생하는 것이 파드의 기동 실패 원인 분석이다.
개인의 개발 환경에서 컨테이너 이미지를 빌드하고 쿠버네티스 환경에 배포했을 때 제일 먼저 경험하는 것이 컨테이너가 기동하지 않거나 재시작을 반복하는 현상이다.
파드의 상태가 가지는 의미를 이해하고 적절한 대처를 할 수 있어야 문제를 해결할 수 있다.
문제를 파악하기 위해서는 kubectl get pods 명령어를 실행 해 나타나는 STATUS 열의 정보가 중요하다.
이 필드의 정보는 Kubernetes API를 통해 획득하는데, 이 API를 통해서 얻을 수 있는 다양한 정보 중에서 도움이 될 만한 정보가 선별되어 STATUS 열에 표시된다.
STATUS | 의미와 대책 |
ContainerCreating | 이미지를 다운로드 중이거나 컨테이너를 생성하는 중에 있음을 의미한다. 컨피그맵과 시크릿이 마운트되지 않아 컨테이너 생성이 보류된 경우일 수도 있다. |
CrashLoopBackOff | 파드 내의 컨테이너가 종료되어 다음 기동 시 까지 대기 상태에 있음을 의미한다. 2회 이상 컨테이너가 종료되면, CrashLookBackOff 시간 동안 대기하게 된다. 이 상황에서는 컨테이너 내의 프로세스를 재검토할 필요가 있다. |
Pending | 파드 생성 요구를 받았지만 하나 이상의 컨테이너가 생성되지 않은 상태를 의미한다. 리소스 부족 등의 이유로 스케줄이 되지 않는 경우에 해당된다. |
Running | 파드의 모든 컨테이너가 생성되어 실행 중임을 의미한다. |
Terminating | 컨테이너에 종료 요청 시그널을 보낸 후 컨테이너가 종료할 때까지 대기 중임을 의미한다. 유예 시간을 넘겨도 컨테이너가 종료할 수 없는 경우는, 컨테이너를 강제로 종료한다. |
Succeeded | 파드 내 모든 컨테이너가 정상적으로 종료했음을 의미한다. |
Completed | 파드 내 컨테이너가 정상적으로 종료되었음을 의미한다. 파드 내에 복수의 컨테이너가 있는 경우, 첫 번째 컨테이너가 정상 종료(Exit 코드=0)하면 표시된다. |
Error | 컨테이너가 이상 종료된 경우다. Exit 코드!=0인 경우에 이상 종료로 간주한다. 파드 내에 복수의 컨테이너가 있는 경우, 첫 번째 컨테이너가 이상 종료되면 표시된다. |
Failed | 파드 내에 적어도 하나의 컨테이너가 이상 종료했음을 의미한다. |
Unknown | 파드의 상태를 얻을 수 없는 상황을 의미한다. |
파드의 종료 처리
쿠버네티스는 종료 요청 시그널은 받은 컨테이너의 애플리케이션이 일정 시간 내에 종료 처리를 완료하고 정상 종료를 하도록 요구하고 있다.
쿠버네티스에는 운영 중인 애플리케이션을 가동 중에 업데이트하는 롤아웃이라 불리는 기능이 있다.
이 기능을 담당하는 컨트롤러는 가동 중인 애플리케이션에 종료 요청 시그널을 보내고 유예 시간까지 파드의 종료를 기다린다.
만약, 유예 시간내에 종료 되지 않으면 강제로 종료된다.
애플리케이션이 동작 중에 강제로 종료되면, 데이터 분실 등의 장애로 이어질 수 있다.
따라서, 애플리케이션은 유예 시간 내에 메모리상의 데이터를 퍼시스턴트 볼륨에 보존하거나 데이터베이스와의 세션을 종료하는 등의 종료 처리를 수행해야 한다.
만약에 이러한 요청에 대응하는 구현이 되어 있지 않다면 애플리케이션은 문제를 일으킬 소지가 있는 것이다.
파드가 삭제 요청을 받으면 컨테이너의 메인 프로세스에게 종료 요청 시그널을 보낸다.
만약 컨테이너에 종료 요청 시그널에 대한 처리가 구현되지 않은 경우에는 유예 시간 동안 기다린뒤 당제로 종료된다.
종료 처리의 흐름
- 사용자가 kubectl delete pod를 실행하면 파드의 종료 처리가 시작된다.(기본 유예 시간은 30초)
- kubectl get pod의 status는 Terminating이라고 표시된다.
- 다음 세 가지 작업이 동시에 진행된다.
더보기
- 파드의 PreStop hook이 정의되어 있으면, 파드 내에서 호출된다.
유예 시간을 넘어서면 PreStop hook이 실행되고 있어도 파드 내에 메인 프로세스에 시그널이 보내지며, 2초 후에 SIGKILL로 강제 종료된다. - PreStop hook이 정의되어 있지 않다면, 곧바로 파드 내에 메인 프로세스에 시그널 신호가 송신되며 종료 처리가 개시된다.
- 파드가 서비스의 엔드포인트 목록에서 제거되며, 로드밸런서(kube-proxy 등)의 목록에서도 제거된다.
- 파드의 PreStop hook이 정의되어 있으면, 파드 내에서 호출된다.
- 유예 시간을 넘어서서 파드 내의 프로세스가 살아 있다면, 파드의 메인 프로세스에 SIGKILL을 보내서 강제 종료한다.
- 제거 대상인 파드가 표시되지 않게 된다.
PreStop은 컨테이너가 종료되기 직전에 호출되는데 이것은 컨테이너 내의 프로세스가 종료 요청 시그널을 받을 수 없는 제약이 있는 경우에 종료 요청을 받는 수단이 된다.
또한 kubectl delete를 실행할 때 옵션 "--grace-period=초"를 통해 유예 시간을 별도로 지정할 수 있다.
0을 설정하면 즉시 파드를 제거한다.
'Docker & Kubernetes' 카테고리의 다른 글
서비스의 기본 (0) | 2021.11.23 |
---|---|
클러스터 네트워크 (0) | 2021.11.23 |
파드의 기본 (0) | 2021.11.23 |
쿠버네티스 API 오브젝트 (0) | 2021.11.23 |
쿠버네티스의 아키텍처 및 계층 구조 (0) | 2021.11.23 |