Kubernetes에서 발생한 OOMKilled

김유경·2025년 6월 1일

들어가며

카카오 클라우드의 Compute Instance에 구성한 Kubernetes 클러스터에 Spring Boot 기반 user-service를 배포했지만, ALB 대상 그룹이 계속해서 Unhealthy로 표시되며 요청이 502 Bad Gateway 로 실패하는 문제가 발생했습니다.

문제 상황

1. Pod 상태 확인

kubectl get pods -n dev-user-service -o wide
NAME                            READY   STATUS    RESTARTS          AGE
user-service-5667ffdbd4-dj52d   1/1     Running   146 (2m59s ago)   22h
user-service-5667ffdbd4-m9vkc   0/1     CrashLoopBackOff   166 (49s ago)     22h

‼️ 비정상적으로 높은 재시작 횟수

2. Pod 상세 정보 확인

kubectl describe pod user-service-5667ffdbd4-dj52d -n dev-user-service

‼️ 핵심 문제 발견

Last State:     Terminated
  Reason:       OOMKilled    # 🚨 메모리 부족으로 강제 종료
  Exit Code:    137          
Restart Count:  146          

Limits:
  cpu:     200m
  memory:  256Mi              

OOMKilled란?

OOMKilled(Out Of Memory Killed)는 컨테이너가 설정된 메모리 제한을 초과했을 때 쿠버네티스가 해당 컨테이너를 강제로 종료시키는 현상입니다.

Spring Boot 애플리케이션은 JVM 기반이며, 메모리 사용 구조는 다음과 같습니다.

  • Heap Memory: 객체 저장 공간
  • Non-Heap Memory: 클래스 메타데이터, 코드 캐시
  • Direct Memory: Netty 등에서 사용하는 off-heap 메모리
  • JVM Overhead: GC, 메타 정보 등 시스템 운영에 필요한 메모리

💡 권장 메모리: 최소 512Mi, 일반적으로 1Gi 이상


해결 과정

기존 Deployment 설정

resources:
  requests:
    cpu: "100m"
    memory: "128Mi"
  limits:
    cpu: "200m"
    memory: "256Mi"

수정된 Deployment 설정

resources:
  requests:
    cpu: "200m"
    memory: "256Mi"
  limits:
    cpu: "400m"
    memory: "512Mi"
kubectl logs -f deployment/user-service -n dev-user-service

적용 후 확인

kubectl logs -f deployment/user-service -n dev-user-service

  • 컨테이너 정상 기동 확인
  • ALB 대상 그룹 상태도 Healthy로 전환
  • Kong Gateway에서도 502 오류 해결

마무리

로컬 개발 환경에서는 최소한의 리소스만 할당한 채로 deployment.yaml을 작성했기 때문에, 운영 환경에서도 동일한 설정을 적용하면서 문제가 발생했습니다.

이번 문제는 지나치게 낮은 리소스 제한으로 인해 발생한 OOMKilled 현상이었고, 이를 통해 Kubernetes에서 JVM 기반 Spring Boot 애플리케이션을 운영할 때는 메모리 사용 특성을 반드시 고려해야 한다는 점을 깨달았습니다.

특히, JVM은 할당된 메모리 제한 내에서 Heap 크기를 자동 조절하기 때문에, 메모리 한계를 너무 작게 설정하면 애플리케이션이 정상적으로 기동되지 않을 수 있습니다.

0개의 댓글