-
Kubernetes OOMKill 예방과 메모리 관리 실전 가이드Kubenetes 2025. 9. 4. 15:07반응형

쿠버네티스의 메모리 요청과 제한 이해하기
쿠버네티스에서 각 포드는 메모리 사용량을 요청(request)과 제한(limit)으로 지정할 수 있습니다. ‘요청’은 포드가 최소한으로 필요한 메모리, ‘제한’은 최대 사용할 수 있는 메모리입니다. 적절히 설정하지 않으면 일부 컨테이너가 과도하게 메모리를 잡아먹어 노드가 다운될 수 있으니 꼭 주의해야 합니다.
resources: requests: memory: 512Mi limits: memory: 1Gi실시간 모니터링으로 조기 대응하기
포드의 메모리 상태를 항상 체크해야 문제 발생 전에 막을 수 있습니다. Prometheus로 container_memory_usage_bytes 지표를 수집하고, Grafana로 경보(75%, 90% 등)를 설정하면 메모리 한계에 다다르기 전에 직접 조치할 수 있어 OOMKill(Out Of Memory Kill)을 방지할 수 있습니다.
메모리 프로파일링으로 컨테이너 사이즈 최적화
실서비스와 부하 상황에서 메모리 소모가 어떻게 변하는지 모니터링 툴(heapster, cAdvisor 등)이나 언어별 프로파일러를 사용하세요. 예상치 못한 캐시나 내부 데이터 누적으로 갑자기 메모리가 커지는 원인을 찾아내면, 불필요한 설정값(예시: 캐시 크기 등)을 줄여 확실하게 리소스를 아낄 수 있습니다.
적절한 Liveness/Readiness Probe 설정하기
포드 장애 감시를 위한 프로브(헬스체크) 설정이 너무 공격적이면, 일시적 메모리 증가나 GC(가비지 컬렉션) 지연만으로도 불필요한 재시작이 반복될 수 있습니다. failureThreshold, initialDelaySeconds 등을 늘려서 여유를 주면 작은 흔들림에도 포드가 죽는 상황을 예방할 수 있습니다.
livenessProbe: exec: command: [stat, /app/ready] initialDelaySeconds: 30 periodSeconds: 10 failureThreshold: 5Init 컨테이너에는 별도 메모리 한도 적용하기
데이터 준비 등 초기 작업(init container)이 일반 컨테이너보다 더 많은 메모리 사용이 필요하다면, 별도의 resources 블록을 추가해 각각 다른 한도를 설정하세요. 이렇게 하면 초기 작업만 넉넉하게 돌리고, 본 서비스는 안전하게 제한할 수 있습니다.
initContainers: - name: preprocess image: my/preprocessor resources: requests: memory: 1Gi limits: memory: 2Gi자동으로 리소스 할당을 조정하는 VPA 활용법
Vertical Pod Autoscaler(VPA)는 실제 사용량을 분석해, 포드의 요청 메모리를 자동으로 재설정합니다. 운영 환경에서 메모리 부족이 반복될 때 VPA를 적용하면, OOMKill을 크게 줄이고 더 안정적으로 서비스를 운영할 수 있습니다.
apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata: name: myapp-vpa spec: targetRef: apiVersion: apps/v1 kind: Deployment name: myapp updatePolicy: updateMode: Auto자바 애플리케이션의 메모리 설정 팁
Java 컨테이너는 JVM 힙 크기가 자동으로 한도를 넘길 수 있으니, JAVA_TOOL_OPTIONS 환경 변수에서 최대 힙 비율을 고정하면 좋습니다. 이렇게 남은 메모리를 GC나 스레드 등 네이티브 작업에 남겨둬서 갑작스러운 트래픽에도 OOMKill을 예방할 수 있습니다.
env: - name: JAVA_TOOL_OPTIONS value: -XX:MaxRAMPercentage=75.0무거운 작업은 분리해서 실행하기
일시적으로 메모리 사용량이 급증하는 배치 작업이나 대용량 테스트는, 서비스 포드에서 분리해 별도의 전용 Job으로 돌리세요. 이렇게 하면 본래 웹서비스 포드가 느닷없이 죽는 사태를 막고 전체 시스템 안정성을 높일 수 있습니다.
apiVersion: batch/v1 kind: Job spec: template: spec: containers: - name: heavy-task image: my/processor resources: limits: memory: 4Gi restartPolicy: NeverMemcached 등 사이드카로 메모리 넘침 완화하기
가끔 일시적으로 메모리가 초과될 때, Memcached나 Redis 사이드카를 이용해 데이터 일부를 외부로 넘기는 방법도 있습니다. 이런 RAM 스왑 구조는 메모리 폭주 시 짧은 시간(수십~수백 ms)을 벌어서, 자동 확장이나 OOMKill을 막는 데 쓸 수 있습니다.
OOMKill 감지와 자동 복구 시스템 만들기
OOMKill이 발생하면 직접 감지하고 자동 대응하는 스크립트를 구축하세요. 포드 이벤트를 수집해 웹훅으로 노드 풀 증설, 코드 롤백, SRE팀 알림까지 빠르게 처리하면 복구 시간이 대폭 단축되어 장애 영향을 최소화할 수 있습니다.
kubectl get events --field-selector reason=OOMKilled -o json | jq .빠른 자동화는 수동 대응보다 훨씬 효율적입니다!
반응형'Kubenetes' 카테고리의 다른 글
쿠버네티스 관측 가능성(Observability) 핵심 가이드 (0) 2025.09.04