Kubernetes/Trouble Shooting

🚀 Kubernetes에서 OOMKilled 발생 원인 및 해결 방법

ygtoken 2025. 2. 26. 10:44
728x90

 

 

Kubernetes를 운영하면서 OOMKilled(Out of Memory Killed) 오류를 접하는 것은 흔한 문제입니다. OOMKilled는 Pod이 메모리를 초과하여 사용했을 때 Kubernetes가 이를 강제로 종료하는 현상입니다. 이번 포스트에서는 OOMKilled의 원인과 이를 모니터링하고 해결하는 방법을 정리해보겠습니다.

 

 

🛑 OOMKilled 오류란?

 

OOMKilled는 Kubernetes에서 컨테이너가 설정된 메모리 제한(Limits)을 초과할 경우 발생하는 오류입니다. Pod이 할당된 메모리를 초과하면 Kubelet이 이를 감지하고 강제로 종료합니다.

 

🛑 OOMKilled 발생 시 나타나는 증상

kubectl get pod 명령어에서 STATUS가 OOMKilled로 표시됨

kubectl describe pod 출력에서 State: Terminated, Reason: OOMKilled

Airflow Worker/Webserver 등 특정 서비스가 지속적으로 재시작됨

kubectl logs에서 메모리 부족 관련 로그가 확인됨

🛠 OOMKilled 원인 분석 방법

 

OOMKilled가 발생하면 Pod의 리소스 사용량과 종료 이벤트를 분석해야 합니다.

 

1️⃣ 현재 Pod의 메모리 사용량 확인

 

Pod이 실행 중이라면 kubectl top pod을 사용하여 현재 리소스 사용량을 확인할 수 있습니다.

kubectl top pod -n airflow

출력 예시:

NAME                   CPU(cores)   MEMORY(bytes)
airflow-webserver-0    250m         800Mi
airflow-worker-0       500m         3500Mi

주의: kubectl top pod이 작동하지 않는다면 Metrics Server를 설치해야 합니다.

2️⃣ Pod의 OOMKilled 이벤트 확인

kubectl describe pod airflow-worker-0 -n airflow

출력 예시:

State:       Terminated
Reason:      OOMKilled
Exit Code:   137

Exit Code: 137메모리 부족으로 종료됨

Reason: OOMKilled → Kubernetes가 강제로 종료함.

3️⃣ 과거 메모리 사용량 모니터링 (Prometheus & Grafana)

 

Kubernetes에서는 Prometheus와 Grafana를 활용하여 Pod의 메모리 사용량 변화를 시각적으로 분석할 수 있습니다.

 

📌 Prometheus에서 메모리 사용량 조회

container_memory_working_set_bytes{pod="airflow-worker-0"}

이 값을 Grafana에서 시각화하면 OOMKilled 발생 전에 어느 시점에서 메모리 사용량이 증가했는지 추적할 수 있습니다.

🔥 OOMKilled 해결 방법

 

✅ 1. Pod의 리소스 제한 증가

 

현재 설정된 메모리 리소스 제한이 너무 낮다면 values.yaml에서 늘려야 합니다.

 

예제: Airflow Worker의 리소스 증가

workers:
  resources:
    requests:
      memory: "4096Mi"  # 기존 2048Mi → 4096Mi (4GiB)
      cpu: "1000m"      # 기존 500m → 1000m (1 CPU)
    limits:
      memory: "6144Mi"  # 기존 3072Mi → 6144Mi (6GiB)
      cpu: "2000m"      # 기존 1000m → 2000m (2 CPU)

수정 후 Helm 업데이트:

helm upgrade --install airflow apache-airflow/airflow -f values.yaml

✅ 2. Kubernetes LimitRange 확인

 

Kubernetes에서 기본적으로 Pod에 설정된 LimitRange가 OOMKilled를 유발할 수도 있습니다.

 

현재 LimitRange 확인

kubectl get limitrange -n airflow

LimitRange 값 확인

kubectl describe limitrange airflow-resource-limits -n airflow

메모리 제한이 너무 낮다면 다음 명령어로 삭제 후 재설정할 수 있습니다.

kubectl delete limitrange airflow-resource-limits -n airflow

✅ 3. Kubernetes Liveness/Readiness Probe 수정

 

Liveness & Readiness Probe가 너무 짧게 설정되어 있으면 Pod이 충분히 실행되기 전에 재시작될 수 있습니다.

webserver:
  livenessProbe:
    initialDelaySeconds: 60
    periodSeconds: 20
  readinessProbe:
    initialDelaySeconds: 60
    periodSeconds: 20

수정 후 Helm 업데이트:

helm upgrade --install airflow apache-airflow/airflow -f values.yaml

✅ 4. Autoscaling (HPA) 적용

 

OOMKilled이 지속된다면 **Horizontal Pod Autoscaler(HPA)**를 적용하여 트래픽 증가에 따라 Pod을 자동으로 확장할 수도 있습니다.

kubectl autoscale deployment airflow-worker --cpu-percent=80 --min=1 --max=5 -n airflow

이렇게 하면 CPU 사용률이 80%를 초과할 경우 Worker Pod 개수를 자동으로 증가시킵니다.

🎯 결론: OOMKilled 해결을 위한 체크리스트

해결 방법적용 방법

1. Pod 리소스 제한 증가 values.yaml에서 requests.memorylimits.memory 수정
2. Kubernetes LimitRange 수정 kubectl get limitrange 후 필요 시 삭제
3. Liveness & Readiness Probe 수정 initialDelaySeconds=60 설정 후 Helm 업데이트
4. Autoscaling(HPA) 적용 kubectl autoscale deployment 명령어 사용

🚀 마무리

 

Kubernetes에서 OOMKilled 문제를 해결하려면 메모리 사용량을 모니터링하고, 적절한 리소스를 할당하며, 자동 확장을 고려하는 것이 중요합니다.

특히 Prometheus & Grafana를 활용하여 실시간 모니터링을 구축하면 문제 발생 전에 리소스 부족을 예측할 수 있습니다.

 

이제 위 내용을 참고하여 Kubernetes 환경에서 안정적인 운영을 해보세요! 🚀🔥

728x90