Kubernetes OOMKilled Hatası (Exit Code 137) Nasıl Çözülür? Kapsamlı Rehber (2026)

01.01.2026 03:29 Haber

Kubernetes pod'larınız sürekli "OOMKilled" statusuyla mı crash oluyor? Exit code 137 görüyor ve ne yapacağınızı bilmiyor musunuz? Alesta Web olarak bu rehberde OOMKilled hatasının nedenlerini ve nasıl çözüleceğini (how to fix) kapsamlı şekilde ele alacağız. Memory management Kubernetes'te kritik bir konudur!

OOMKilled Nedir? (What is OOMKilled?)

OOMKilled (Out Of Memory Killed), Kubernetes'te bir container'ın belirlenen memory limit'ini aştığında Linux Kernel tarafından sonlandırılmasıdır. Exit code 137, container'ın SIGKILL (9) sinyali ile zorla kapatıldığını gösterir.

Alesta Web olarak DevOps projelerinde bu hatayı sıkça görüyoruz. Doğru memory yönetimi, uygulamanızın stable çalışması için kritiktir!

Tipik Hata Görünümü / Typical Error:

$ kubectl get pods
NAME                        READY   STATUS      RESTARTS   AGE
myapp-deployment-7d4f8c9    0/1     OOMKilled   5          10m

$ kubectl describe pod myapp-deployment-7d4f8c9
...
State:          Terminated
  Reason:       OOMKilled
  Exit Code:    137
Last State:     Terminated
  Reason:       OOMKilled
  Exit Code:    137

Events:
  Type     Reason     Message
  ----     ------     -------
  Warning  OOMKilled  Container killed due to OOM (Out of Memory)
? Exit Code 137 Nedir? / What is Exit Code 137?

Exit code 137 = 128 + 9 (SIGKILL). Bu, process'in zorla sonlandırıldığı anlamına gelir. OOM Killer, memory sınırını aşan process'i bu şekilde durdurur.

Hata Nedenleri (Common Causes of OOMKilled)

Alesta Web deneyimlerimize göre OOMKilled hatasının başlıca nedenleri:

1. Yetersiz Memory Limit

❌ Düşük Limit Örneği:

apiVersion: v1
kind: Pod
metadata:
  name: memory-demo
spec:
  containers:
  - name: memory-demo-ctr
    image: myapp:latest
    resources:
      limits:
        memory: "64Mi"  # ❌ Çok düşük!
      requests:
        memory: "32Mi"

2. Memory Leak (Bellek Sızıntısı)

Uygulama kodunda memory leak varsa, zamanla bellek kullanımı artar ve limit'e ulaşılır.

3. Yanlış Memory Request Ayarları

Request değeri çok düşükse, scheduler pod'u yetersiz kaynaklı node'a yerleştirebilir.

4. Node Overcommitment

Node üzerinde çok fazla pod schedule edildiğinde, toplam memory ihtiyacı node kapasitesini aşabilir.

5. Java Heap Size Uyumsuzluğu

Java uygulamalarında -Xmx değeri container limit'ini aşarsa OOMKilled kaçınılmazdır.

⚠️ Önemli Yanılgı / Important Misconception:

OOM Killer, node'da boş memory olsa bile çalışabilir! Çünkü cgroups bazında limit kontrolü yapar. Container limit'i aşıldığında, node'da GB'larca boş RAM olsa bile container kill edilir.

Teşhis Yöntemleri (Diagnosis Methods)

1. Pod Status ve Events Kontrolü

kubectl Komutları:

# Pod durumunu kontrol et
kubectl get pod myapp-xxx -o jsonpath='{.status.containerStatuses[0].state}'

# Pod detaylarını görüntüle
kubectl describe pod myapp-xxx

# Önceki container loglarını al
kubectl logs myapp-xxx --previous

# Tüm OOMKilled pod'ları listele
kubectl get pods --all-namespaces | grep OOMKilled

2. Memory Kullanımını İzle

Metrics Server ile İzleme:

# Pod memory kullanımı
kubectl top pod myapp-xxx

# Tüm pod'ların memory kullanımı
kubectl top pods --all-namespaces --sort-by=memory

# Node memory kullanımı
kubectl top nodes

# Container bazında detaylı bilgi
kubectl top pod myapp-xxx --containers

3. cgroups Memory Bilgisi

Container İçinden Kontrol:

# Container'a bağlan
kubectl exec -it myapp-xxx -- /bin/sh

# Memory limit (cgroups v2)
cat /sys/fs/cgroup/memory.max

# Mevcut kullanım
cat /sys/fs/cgroup/memory.current

# OOM kill sayısı
cat /sys/fs/cgroup/memory.events | grep oom_kill

4. Prometheus Sorguları

PromQL Örnekleri:

# Container memory kullanımı vs limit
container_memory_usage_bytes{pod="myapp-xxx"}
  / container_spec_memory_limit_bytes{pod="myapp-xxx"} * 100

# Son 1 saatte OOMKilled olan pod'lar
kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}

# Memory limit'e yaklaşan container'lar (%80+)
(container_memory_usage_bytes / container_spec_memory_limit_bytes) > 0.8

# Memory kullanım trendi (son 1 saat)
rate(container_memory_usage_bytes[1h])

Çözüm Yöntemleri (Solutions)

Çözüm 1: Memory Limit'i Artır

✅ Doğru Ayarlar / Correct Settings:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  template:
    spec:
      containers:
      - name: myapp
        image: myapp:latest
        resources:
          requests:
            memory: "256Mi"   # Garanti edilen minimum
            cpu: "100m"
          limits:
            memory: "512Mi"   # Maksimum izin verilen
            cpu: "500m"
? Request vs Limit / Request vs Limit:
  • Request: Pod schedule edilirken garanti edilen minimum kaynak
  • Limit: Container'ın kullanabileceği maksimum kaynak
  • Best Practice: Request = %70-80 of Limit

Çözüm 2: Vertical Pod Autoscaler (VPA) Kullan

VPA Konfigürasyonu:

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: myapp-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  updatePolicy:
    updateMode: "Auto"  # Off, Initial, Recreate, Auto
  resourcePolicy:
    containerPolicies:
    - containerName: myapp
      minAllowed:
        memory: "128Mi"
      maxAllowed:
        memory: "2Gi"
      controlledResources: ["memory"]

Çözüm 3: Memory Profiling ile Leak Tespit

Profiling Araçları:

# Node.js için
node --inspect app.js
# Chrome DevTools'ta Memory profiling

# Python için
pip install memory-profiler
python -m memory_profiler app.py

# Go için
import _ "net/http/pprof"
go tool pprof http://localhost:6060/debug/pprof/heap

# Java için
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp/heapdump.hprof

Çözüm 4: Resource Quota ile Namespace Limitleri

ResourceQuota Örneği:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-quota
  namespace: production
spec:
  hard:
    requests.memory: "8Gi"
    limits.memory: "16Gi"
    pods: "20"

---
# LimitRange ile varsayılan değerler
apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
  namespace: production
spec:
  limits:
  - default:
      memory: "512Mi"
    defaultRequest:
      memory: "256Mi"
    type: Container

Çözüm 5: Pod Priority ve Eviction

Priority Class Kullanımı:

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "Critical workloads"

---
apiVersion: v1
kind: Pod
metadata:
  name: critical-app
spec:
  priorityClassName: high-priority
  containers:
  - name: app
    image: myapp:latest

Java Uygulamaları için Özel Ayarlar

Java uygulamaları OOMKilled hatalarına özellikle yatkındır. Alesta Web olarak Java container'ları için şu ayarları öneriyoruz:

JVM Memory Ayarları:

# Dockerfile
FROM openjdk:17-jdk-slim

# Container-aware JVM ayarları
ENV JAVA_OPTS="-XX:+UseContainerSupport \
               -XX:MaxRAMPercentage=75.0 \
               -XX:InitialRAMPercentage=50.0 \
               -XX:+HeapDumpOnOutOfMemoryError \
               -XX:HeapDumpPath=/tmp"

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

Kubernetes Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-app
spec:
  template:
    spec:
      containers:
      - name: java-app
        image: java-app:latest
        env:
        - name: JAVA_OPTS
          value: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
        resources:
          requests:
            memory: "512Mi"
          limits:
            memory: "1Gi"  # JVM MaxRAMPercentage=75 -> ~768Mi heap
⚠️ Java Uyarısı / Java Warning:

JVM, heap dışında da memory kullanır (Metaspace, Native Memory, Thread Stack). Bu yüzden MaxRAMPercentage'ı %75-80 civarında tutun, %100 yapmayın!

Monitoring ve Alerting

Alesta Web olarak production Kubernetes cluster'larında şu monitoring stratejisini uyguluyoruz:

Prometheus Alert Rules:

groups:
- name: memory-alerts
  rules:
  # Memory kullanımı %80'i aştığında uyar
  - alert: ContainerMemoryHigh
    expr: |
      (container_memory_usage_bytes / container_spec_memory_limit_bytes) > 0.8
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Container memory high ({{ $labels.pod }})"
      description: "Memory usage is {{ $value | humanizePercentage }}"

  # OOMKilled olduğunda uyar
  - alert: ContainerOOMKilled
    expr: |
      increase(kube_pod_container_status_restarts_total[1h]) > 3
      and kube_pod_container_status_last_terminated_reason{reason="OOMKilled"} == 1
    labels:
      severity: critical
    annotations:
      summary: "Container OOMKilled multiple times ({{ $labels.pod }})"
✅ Monitoring Best Practices:
  • Memory kullanımını sürekli izle (Prometheus + Grafana)
  • %80 eşiğinde uyarı al
  • OOMKilled event'lerini logla
  • Trend analizi yap (memory leak tespiti için)
  • Pod restart sayısını izle

? Kaynaklar ve Referanslar / Sources and References

Alesta Web olarak tüm çözümleri production cluster'larda test ettik.

✅ Sorun Çözüldü! (Problem Solved!)

Artık Kubernetes OOMKilled hatası (Exit Code 137) sizin için bir gizem değil! Alesta Web olarak anlattığımız yöntemlerle pod'larınızın stable çalışmasını sağlayabilirsiniz.

Hızlı Özet / Quick Summary:

  • ✅ OOMKilled kavramı anlaşıldı (OOMKilled concept understood)
  • ✅ Teşhis yöntemleri öğrenildi (Diagnosis methods learned)
  • ✅ Memory limit'ler optimize edildi (Memory limits optimized)
  • ✅ Java JVM ayarları yapıldı (Java JVM configured)
  • ✅ Monitoring kuruldu (Monitoring setup)

Faydalı Linkler / Useful Links:

© 2026 AlestaWeb - Tüm hakları saklıdır.

WM Tools
💫

WebMaster Tools

15 Profesyonel Araç