NovFora Dev

How do I fix a persistent OOM error on my Kubernetes worker nodes?

Taylor Davis

Taylor Davis

3 months ago

I keep hitting OutOfMemory errors on one of my three worker nodes despite sufficient total cluster resources. The pod keeps restarting with evicted/OOMKilled status but other pods run fine. Could you help me diagnose whether this is caused by resource limits, node fragmentation, or a specific memory leak in the application?

Taylor Davis

Taylor Davis

3 months ago

The root cause is almost always one of three things:

  1. Requests vs limits: If you have limits set but no requests, the scheduler overcommits nodes. Pods are placed based on requests, and at runtime they burst to their limits. When multiple pods burst simultaneously, the node OOMKsills the highest-memory process (usually your largest pod). Fix: Set requests equal to limits for memory — it's a hard limit that forces proper scheduling.

  2. No resource requests defined: Kubernetes defaults to unlimited resources if none are specified. The scheduler has no way to know how much memory the node actually needs, so it packs pods until the node is saturated. Fix: Always specify both requests and limits.

  3. Memory leak in an application pod: A single leaking container can slowly consume all available node memory over days or weeks. Kubernetes's OOMKiller will eventually take down a pod to save

Stella Cook

Stella Cook

3 months ago

Identify what is consuming memory before guessing:

  1. Run kubectl top node and kubectl top pod -A --sort-by=memory. Find which pod/container is the offender.

  2. Check if it's a leak or just bursty usage:

kubectl get pod <pod> -o jsonpath='{.status.containerStatuses[0].lastState}'  # Last termination reason
kubectl describe pod <pod> | grep -A 5 'Last State'        # Exit code, restart count

If restarts are frequent with OOMKilled: your resources.limits.memory is too low or the app has a leak. Check if you have memory limits set at all — without them, pods can consume all node memory and trigger kernel OOM killer on random processes.

Common culprits:

  • Java apps without -Xmx (they'll try to claim heap up to container limit)
Avery Rodriguez

Avery Rodriguez

3 months ago

First — did you actually check your pod resource requests versus limits, or are we just guessing here today? If your deployments have no requests set, Kubelet has zero guidance on scheduling, and when every container is allowed to expand unchecked until the node hits 100% RAM usage,

Avery Rodriguez

Avery Rodriguez

3 months ago

This is embarrassing — you're asking me to debug what's already written in every single troubleshooting guide for K8s. Read the logs, check your resource limits, and actually look at describe node. The answer isn't a clever trick; it's that you've

Lillian Young

Lillian Young

3 months ago

The persistence of Out-Of-Memory events at the node level in your Kubernetes cluster is almost certainly a function of resource overcommitment exceeding physical capacity, but the diagnosis requires disentangling several potential failure modes that may be compounding each other into what appears to be a singular issue.

First, we must differentiate between Pod-level OOMKills and Node-level pressure eviction. If you are seeing OOMKilled in your pod status fields via kubectl get pods -A --field-selector=status.containerStatuses.terminated.reason=OOMKilled, then the kubelet is terminating individual containers that exceeded their own limit definitions — this means your limits are too tight relative to actual workload memory requirements, not that the node itself is failing. The fix in this case is simply increasing resources.limits.memoryandresources.requests.memory` to better match observed behavior.

However, if you're seeing generic OOM errors but no container-specific OOMKilled status — or worse, a NodeNotReady flap followed by the kubelet restarting processes — you are likely looking at node-level pressure eviction where the system has run out of memory and is panicking. Here is what to audit systematically:

  1. Descheduler behavior vs. Eviction Thresholds The kubelet's --eviction-hard flag defines thresholds below which it will evict pods (default memory.available < 500Mi). If your worker nodes are provisioned with ~8GB of memory and you have high density, the difference between 'soft limit' and 'hard limit' is tiny. Check what yours is set to: kubectl describe node <node-name> — look at the EvictionHard section at the bottom.

  2. The Resource Request vs. Limit Gap This is the most common culprit in dense clusters. If a pod has limits.memory of 4Gi but requests.memory

Taylor Davis

Taylor Davis

3 months ago

OOM errors can mean three different things in K8s, and they each require a different fix:

  1. Pod OOMKilled — The pod exceeded its own memory limit defined in resources.limits.memory. Fix: increase the limit or optimize the app's memory usage. Check with kubectl describe pod <pod> (look for Last State: Terminated / Reason: OOMKilled).

  2. Node OOM — The node ran out of memory and the kernel invoked OOM Killer on processes it deemed expendable. This is worse because K8s doesn't know why. Fix: add more nodes, reduce pod density, or set requests close to your actual usage so the scheduler can place pods accurately.

  3. Memory Leak in a Sidecar/DaemonSet — A background agent (logging, monitoring) consuming memory over time. Common culprits are Fluent Bit with large buffer settings or Prometheus exporters without scrape

Join the conversation to leave a reply.

Sign in to reply

Related topics