Incident Library

IL-0503 Binder Project · 2017-11-30kubernetesgcp

mybinder.org launches failed after a GKE node ran out of memory and its nginx-ingress proxy pod crash-looped

At 16:22 PST on 30 November 2017 a node in the mybinder.org cluster on GKE ran out of memory and the service started to degrade. The write-up gives a build container as the probable cause: builds had no memory limits, and one likely used all the memory on the node. That node ran the proxy pod, which holds an nginx container and a chp container; the memory exhaustion broke the proxy, its pods went into a crash loop, and launches of new servers failed with an error about creating a temporary user.

Operators noticed the problem at 16:59 because one of them happened to look at Grafana. Restarting the jupyterhub pod did not help and, because of the JupyterHub configuration, deleted all running user pods. After the OOMKilling event was found on the proxy's node, an operator suggested at 17:18 cordoning that node and then deleting the proxy pod, and the node was cordoned. At 17:20 the proxy pod was working again, although by then it had already been running for about 10 minutes, and the node was uncordoned, and at 17:21 service was restored and user pods started running again.

Severity
–
Scope
mybinder.org: new server launches failed; restarting the jupyterhub pod also removed all running user pods
Users affected
–
Region
us-central1-a
Time to detect
37m
Time to resolve
59m

Symptoms

On 30 November 2017 at 16:59 PST, mybinder.org operators noticed that Grafana looked wrong and that launching a new server failed with an error that a temporary user could not be created. Pods that were already running kept running, but no new ones were being created.

The launch page showed "Found built image, launching...", "Launching server..." and then "Failed to create temporary user for gcr.io/binder-prod/r2d-<repository>:6be6d6329de99168d0a0b68f9d52228ecc61ac50". The proxy pods were in CrashloopBackoff after about 13 restarts. `kubectl describe` on them showed "Back-off restarting failed container" and "Readiness probe failed: Get http://10.12.5.36:10254/healthz: dial tcp 10.12.5.36:10254: getsockopt: connection refused" for the nginx-ingress-controller:0.9.0-beta.15 image, and the jupyterhub pod logged many DELETE requests timing out, with tracebacks.

A Google Cloud storage incident (17006) was suspected first, but all nodes showed "Ready" in the cloud console. Restarting the jupyterhub pod at 17:12 removed all user pods and the error remained. At 17:14 `kubectl describe` on the node running the proxy showed an OOMKilling event: "Memory cgroup out of memory: Kill process 8339 (python) score 1576 or sacrific".

Symptom Service outageContainer crash loopProbe failuresOOMKilled

Root cause

Trigger
A build container, which ran without a memory limit, most likely used up all the memory on the node that ran the proxy pod.

Detection

An operator happened to look at Grafana at 16:59 PST, saw that it looked wrong, and confirmed the error by launching a new server.

Remediation

Action items

Lessons

–

Sources

References

Related cases

Check your cluster for this

kubegap audits a Kubernetes cluster for conditions like the ones in this case, Ingress controller, Container memory limit, JupyterHub among them, read-only, from Claude Code or Codex. Its checks cite public reports like this one.

For AI tools and scripts

The API needs no key. The MCP server offers search_incidents, get_incident, list_incidents, get_topic and vocab; both are explained on API and MCP.