
데브옵스
Kubernetes 환경 OOMKilled 원인 분석
두줄요약
Kubernetes에서 발생하는 OOMKilled의 원인과 JVM 메모리 구성을 함께 분석했습니다. Heap뿐 아니라 Non-Heap, Off-Heap까지 고려해 JVM 옵션을 조정하는 방법을 정리했습니다.
문제 상황
- Kubernetes 환경에서 Pod가 OOMKilled로 재시작되는 현상
- 단순 OOM과 달리 에러 로그 없이 종료되어 원인 파악이 어려운 점
원인 분석
- Container Limit 초과 시 Kubernetes가 JVM보다 먼저 프로세스를 강제 종료
- Heap, Non-Heap, Off-Heap, 기타 메모리와 JVM 오버헤드가 Limit 안에서 함께 소모되는 구조
- Heap Max를 크게 잡은 상태에서 Metaspace, Direct Buffer, Thread Stack까지 합산되며 여유가 급격히 줄어든 상황
해결 방법
- Heap Max를 Container Limit보다 보수적으로 낮추고 MaxRAMPercentage를 조정
- MaxMetaspaceSize와 MaxDirectMemorySize로 비Heap 영역 상한 설정
- G1GC로 변경해 Container 친화적인 GC 구성
적용해볼 점
- Heap만 보지 말고 Container 전체 메모리 기준으로 산정
- 서비스 특성에 따라 Non-Heap과 Off-Heap 사용량을 함께 모니터링
- Burstable QoS와 재시작 반복 가능성까지 고려해 메모리 여유 확보
