파드 속 컨테이너의 장애
개요
컨테이너는 쉽게 휘발될 수 있다.
파드는 기본적으로 스펙에 명시된 restartPolicy에 맞춰 컨테이너의 장애를 처리한다.
컨테이너의 장애 정의에 대해서는 컨테이너 프로브를 참고한다.
쿠버네티스에서는 이를 보완하기 위해 파드를 두지만, 사실 클러스터의 관점에서는 파드 역시 어느 정도 휘발성이 있는 것으로 취급한다.
이후에 볼 Deployment에서 보면 알 수 있겠지만 파드는 생겼다 줄었다하는 게 원래 존재 방식이다.
재시작 절차
재시작은 일단 다음 정도의 과정을 거친다.
- initial crash
- 처음으로 실패가 발생했을 때
- 쿠버네티스는
restartPolicy에 정의된 정책을 토대로 동작을 시도한다.
- repeated crashes
- 첫 충돌이 발생한 후 쿠버네티스는 역시 정의된 딜레이 시간에 맞춰 연속적으로 재시작을 시도하게 된다.
- 이때 시간을 점진적으로 늘리면서 재시작 주기를 길게 늘린다.
- 이를 통해 과도하게 재시작을 하는 상황을 막는다.
- CrashLoopBackOff state
- 충돌과 재시작이 지속적으로 반복되고 있다는 것을 의미한다.
- Backoff reset
- 컨테이너가 일정 시간동안 성공적으로 실행되었을 경우
- 쿠버네티스는 재실행 연기 시간을 초기화하고, 이후에 발생한 실패를 첫 실패로 간주한다.
CrashLoopBackOff
이 중 CrashLoopBackOff 상태는 컨테이너 실패에 따라 자주 보게 되는 상태일 것이다.
크룹백은 언제 주로 발생하는가?
- 어플리케이션이 에러를 일으켜 컨테이너가 종료될 때
- 설정 파일이나 환경 변수가 없어서 실행 상의 에러 발생
- 메모리나 cpu가 충분하지 않아 리소스 제한이 걸렸을 때
- 예정된 시간 동안 어플리케이션이 헬스체크를 실패했을 때
- liveness probe에서 실패 상태가 적용될 때
- 등등..
뭐가 많지만, 결국 컨테이너가 제대로 실행되지 않는 상태들이다.
하지만 이 에러를 대응하기 위해서는 다양한 방법을 시도해볼 필요가 있어서 이렇게 세분화한 것이다.
얼마나 이 에러에 대한 질문이 많았으면 공식 문서에도 떡하니 박아놨다.
- 로깅
kubectl logs를 통해 로그를 확인한다.
- 이벤트 확인
kubectl describe pod를 통해 리소스나 설정에 관한 힌트를 얻는다.
- 설정 검토
- 환경 변수나 볼륨 마운트, 외부 자원이 전부 제대로 설정되었는지 확인하기
- 리소스 제한 확인
- 수동으로 리소스를 제한할 때 지나치게 적게 리소스를 부여한 것이 아닌지 체크해본다.
- 앱 디버깅
- 앱 자체에서 발생하는 이슈일 수도 있으니 개발자더러 확인하라 시킨다.
- 개발 환경과 배포 환경이 다른 데에서 이슈가 발생할 가능성도 존재한다.
재시작 정책(restartPolicy)
그래서 재시작 정책에는 무엇이 있단 말인가?
- Always
- 종료 후에는 항상 재시작
- 정상 종료여도 무조건 재시작이나, init 컨테이너는 한번만 실행된다.
- OnFailure
- 비정상 종료일 때만 재시작
- Never
- 무조건 재시작하지 않음
- 파드에서 failed 상태가 나는 이유 중 하나.
- T-파드가 failed 뜨는 상황이란에 실험을 진행했다.
- 이게 아니면 파드 자체가 failed 뜨는 일은 잘 없다.
이 정책은 파드 내부의 앱 컨테이너, 초기화 컨테이너에 대해 동작한다.
사이드카 컨테이너는 재시작 정책이 always인 초기화 컨테이너 내부에서 정의되기에 이를 무시한다.
재시작은 항상 같은 노드 내에서 이뤄지는 것이 보장된다.