Search... ⌘K
Write Log In Sign Up

Join DevSolved

Share war stories & investigate outages.

Sign Up for Free Log In to Account
ESC
CRITICAL Resolved

Kubernetes OOMKilled: The Memory Limit Death Spiral

Avatar Devsolved Nov 20, 2023 — 14:30 UTC MTTR: 12 hours 1 min read 110000 views
Executive Summary

A misconfigured Java heap size inside a Docker container caused our payment processing pods to get aggressively killed by the Kubernetes kubelet, resulting in a 15% transaction failure rate.

Financial Impact: 15% of inbound Stripe webhooks were dropped and had to be manually replayed.

The Symptom

Symptom

Our Datadog dashboards started alerting heavily for `PodRestartRate`. The payment microservice was constantly restarting. `kubectl describe pod` revealed the Reason as `OOMKilled` with an exit code of 137. However, our APM (Application Performance Monitoring) inside the JVM showed memory usage was perfectly stable.

Root Cause Analysis

Root Cause

We allocated 2GB of RAM to the Kubernetes pod limits (`limits: memory: "2Gi"`). However, the Java application was started without explicit `-Xmx` heap size flags. By default, older Java 8 runtimes look at the *host node's* total physical RAM (which was 64GB on our AWS instances) and dynamically set the heap size to 1/4th of that (16GB). The JVM thought it had 16GB of RAM to use, but the Linux cgroup enforced by Kubernetes brutally killed the process the millisecond it crossed the 2GB limit.

Code yaml
resources:
  requests:
    memory: "1Gi"
  limits:
    memory: "2Gi"

# The fatal flaw:
# command: ["java", "-jar", "app.jar"]

Resolution

Resolution

We upgraded the container base image to a modern Java 17 runtime that respects Linux cgroups (`-XX:+UseContainerSupport`), and explicitly configured the JVM to use a percentage of the container's memory using `-XX:MaxRAMPercentage=75.0`.

Preventive Action Items

critical Explicitly set MaxRAMPercentage on all JVM workloads @DevOps
high Create PromQL alerts for container memory usage > 90% of limit @SRE Team
|

Discussions 0

Most recent