본문 바로가기

트러블슈팅 & 장애 대응

Kubernetes CrashLoopBackOff 해결 가이드 — 로그·이벤트·Probe·OOM 점검

반응형

CrashLoopBackOff는 Kubernetes가 컨테이너를 반복해서 시작하지만 계속 종료되어 재시작 사이의 대기시간을 늘리고 있다는 상태입니다. 이것은 원인명이 아니라 재시작 결과이므로 “CrashLoopBackOff 해결”보다 컨테이너가 왜 종료됐는지를 찾아야 합니다.

핵심 요약

  • kubectl logs --previous로 직전에 종료된 컨테이너 로그를 먼저 봅니다.
  • kubectl describe pod의 Last State, Exit Code, Reason, Events를 확인합니다.
  • Exit 0 반복은 Batch 프로그램을 Deployment로 실행한 설계 오류일 수 있습니다.
  • OOMKilled는 메모리 Limit뿐 아니라 Heap·Native·Cache·동시성 사용량을 함께 봅니다.
  • Liveness Probe가 너무 공격적이면 정상적으로 기동 중인 컨테이너를 반복 종료할 수 있습니다.

1. 첫 5분 진단 명령

kubectl get pod -n app
kubectl describe pod api-xxxxx -n app
kubectl logs api-xxxxx -n app --previous
kubectl logs api-xxxxx -n app -c sidecar --previous
kubectl get events -n app --sort-by=.lastTimestamp

Pod에 컨테이너가 여러 개면 -c로 대상 컨테이너를 지정합니다. 현재 로그만 보면 재시작 직후의 빈 로그가 보일 수 있으므로 --previous가 중요합니다.

2. 종료 코드와 Reason 읽기

신호가능한 원인확인

Exit Code 1 애플리케이션 예외·설정 오류 이전 로그 첫 Stack Trace
Exit Code 0 프로세스 정상 종료 후 재시작 정책 Deployment 대신 Job 여부
Exit Code 137 SIGKILL·OOM 가능성 Reason OOMKilled, Node 이벤트
Exit Code 143 SIGTERM 배포·Probe·Eviction 시점
ContainerCannotRun Command·권한·파일 오류 Image ENTRYPOINT와 SecurityContext

3. 설정·Secret·의존성 오류

  • 필수 환경변수와 Secret Key 이름이 실제 Manifest와 일치하는지 확인합니다.
  • ConfigMap Volume의 경로와 파일 권한을 확인합니다.
  • DB·Kafka·외부 API DNS와 NetworkPolicy를 점검합니다.
  • Migration을 모든 Replica가 동시에 실행해 Lock이 생기지 않았는지 봅니다.
  • Image Tag가 예상 Digest를 가리키는지 확인합니다.

4. Liveness Probe 악순환

startupProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
  periodSeconds: 5
  failureThreshold: 30

livenessProbe:
  httpGet:
    path: /actuator/health/liveness
    port: 8080
  periodSeconds: 10
  failureThreshold: 3

기동이 느린 서비스에는 Startup Probe를 사용해 Liveness 시작을 늦춥니다. DB 접속 실패처럼 일시적 외부 장애를 Liveness에 포함하면 Pod 전체가 반복 재시작될 수 있으므로 Readiness와 역할을 분리합니다.

5. OOMKilled 대응

메모리 Limit을 바로 올리기 전에 실제 사용 패턴을 봅니다. Java라면 Heap 이외에도 Metaspace, Direct Buffer, Thread Stack, Native Library가 메모리를 사용합니다.

  1. 종료 시점의 Working Set과 RSS를 확인합니다.
  2. Request·Limit과 JVM -Xmx 사이에 Native 여유를 둡니다.
  3. 동시 요청·Batch·Cache 크기가 메모리에 미치는 영향을 측정합니다.
  4. Heap Dump·GC Log 수집이 가능한 재현 환경을 만듭니다.
  5. Node Memory Pressure와 Eviction 이벤트도 함께 확인합니다.

6. Debug Container 활용

Image에 Shell이나 진단 도구가 없으면 kubectl debug의 Ephemeral Container를 사용해 DNS, Network, Mount를 확인할 수 있습니다. 운영 Cluster에서는 RBAC와 감사 로그 정책에 따라 사용합니다.

7. 재발 방지 체크리스트

  • 종료 Reason·Exit Code·Restart Count 알림을 구성합니다.
  • 배포 전 동일한 Config와 Resource Limit으로 Smoke Test합니다.
  • Probe Endpoint와 Threshold를 부하 상황에서 검증합니다.
  • 시작 로그에 버전·Profile·필수 설정 검증 결과를 남깁니다.
  • Rollback 기준과 직전 정상 Image Digest를 Runbook에 기록합니다.

공식 자료

정리: CrashLoopBackOff에서는 재시작 버튼보다 직전 종료 증거를 먼저 확보해야 합니다. Previous Log, Last State, Events를 기준으로 설정·Probe·OOM·프로세스 종료를 분리하면 대부분의 원인을 빠르게 좁힐 수 있습니다.

반응형