Cases3 cases
1 to 3 of 3
IL-0044Prometheus OOMKilled in a loop while replaying its write-ahead log after a kube-prometheus-stack upgradeSaifeddine Rajhi2024- Symptoms
After an upgrade of the kube-prometheus-stack Helm chart, several pods stayed not ready. Among them was prometheus-prometheus-operator-prometheus-0, showing 3/4 Running and a recent termination.
- Trigger
During the kube-prometheus-stack Helm chart upgrade, Prometheus had to replay its write-ahead log on startup, and the replay needed more memory than its limit allowed.
- Root cause
- Component
- Contributing factor
- Detection
The team noticed pods not ready after the Helm chart upgrade and found the OOMKilled termination with kubectl describe pod.
- Remediation
- ran promtool tsdb analyze inside the Prometheus pod to find high-cardinality metrics such as haproxy_server_http_responses_total
- Action items
- Verify that the memory overhead during WAL replay stays within acceptable limits, for example 10 to 15%, and do not run Prometheus close to its memory limit
- Optimise storage, scraping and remote write configuration and upgrade to newer Prometheus releases
- Recover automatically from OOM crash loops, for example by deleting the WAL on OOM events
- Enforce scrape limits so Prometheus stops scraping targets when memory use passes a threshold
- Lessons
Size Prometheus for its restart, not only for steady state: WAL replay can need far more memory than normal running, and a Prometheus that already runs near its limit can be OOM-killed during the replay. Much of Prometheus memory use comes from cardinality, which promtool tsdb analyze can measure even when Prometheus itself is down.
IL-0001Cluster-wide DNS outage after CoreDNS pods were OOM-killed again and again under a burst of DNS queriesZalando2019- Symptoms
Customers of the Zalando Fashion Store got a high rate of errors on all web product pages and outfit pages for more than an hour. The errors came from the main data aggregation layer service, which runs in one of Zalando's Kubernetes clusters.
- Trigger
Calls from the aggregation layer to a single, not very important downstream service started timing out. The aggregation layer returned 404s for them, clients retried, and the resulting spike in requests became a spike in DNS queries to CoreDNS.
- Root cause
- Component
- Contributing factor
- Detection
The on-call engineer for the aggregation layer phoned the on-call Kubernetes engineer. Automatic paging did not happen because the cluster's monitoring and alerting ran inside the cluster and failed along with DNS. The Kubernetes engineer then saw that the CoreDNS pods were being OOM-killed.
- Remediation
- Raised the CoreDNS memory requests and limits by hand from 100Mi to 2000Mi
- Action items
- Introduce a more resilient DNS setup: CoreDNS fronted by dnsmasq on every node
- Improve high-level alerting from outside the clusters, so that a cluster problem is known before or at the same time as applications are affected
- Improve incident response processes and tooling so that any on-call engineer can escalate directly to other teams when automatic paging fails, for example through a chat bot
- Lessons
The Kubernetes DNS setup was far from resilient enough: a single application could take down DNS for everything in the cluster. The blast radius of one application sending more DNS queries should be limited to one node at most, ideally to single pods. Known Kubernetes DNS problems, such as Linux kernel races in conntrack handling and the ndots 5 problem, were familiar to the team and partly mitigated, but their combined effect on the DNS infrastructure was worse than the team had understood. Monitoring that runs inside the cluster was not robust enough: when the cluster's DNS broke, it could not page anyone, and recovery took longer than it should have.
IL-0468New JupyterHub student pods stuck Pending on MaxVolumeCount after a memory limit cut with node size unchangedUC Berkeley2017- Symptoms
On 20 March 2017, from some time early in the day until about 13:00, some new student servers on UC Berkeley's JupyterHub stayed in Pending forever and the students got 500 errors that kept them from logging in.
- Trigger
On 18 March at 16:30 the RAM per student was reduced from 2G to 1G to save resources while the nodes kept the same size of 26G RAM, and as a result the nodes hit the Google Cloud the limit on the number of disks per node.
- Root cause
- Component
- Contributing factor
- Detection
New student servers reported a 500 error that kept students from logging in. At 12:44 this was judged widespread, and at 12:53 `kubectl describe pod` showed the pods Pending on MaxVolumeCount.
- Remediation
- Copied the Google Container Engine instance template and changed it to spawn smaller n1-highmem-2 nodes
- Switched the managed instance group to the new template
- Grew the instance group by 30 new nodes
- Ran populate.bash so student pods would start on time on the new nodes
- Stopped the simple autoscaler
- Stopped and started affected user pods from the control panel
- Restarted the hub and proxy pods
- Action items
- Follow the status of kubernetes/kubernetes issue 24317
- Find and fix the cause of the 'too many redirects' error in JupyterHub
- Delete the older, larger nodes that are no longer in use
- Alert when any pods stay Pending for a non-negligible time
These 3 cases involve Container memory limit and Cloud block storage. kubegap audits a Kubernetes cluster for gaps like these, read-only, from Claude Code or Codex; its checks cite public reports like the ones in this library.
By root cause1
Capacity exhaustion3 cases
- Component
- Contributing factor
- Organisation
IL-0044Prometheus OOMKilled in a loop while replaying its write-ahead log after a kube-prometheus-stack upgradeSaifeddine Rajhi2024IL-0001Cluster-wide DNS outage after CoreDNS pods were OOM-killed again and again under a burst of DNS queriesZalando2019IL-0468New JupyterHub student pods stuck Pending on MaxVolumeCount after a memory limit cut with node size unchangedUC Berkeley2017