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-0461Every rollout of Datadog's metrics query service on Kubernetes raised errors that the logs blamed on DNSDatadog2022- Symptoms
From September 2021, each rollout of an update to Datadog's metrics query service, which serves real-time and historical metric data to the web frontend and to monitor evaluation, came with a rise in errors. Clients retried failed queries, so few errors reached users, but the retries slowed dashboards and monitors. The service's logs showed DNS errors stopping it from connecting to the data stores it depends on.
- Trigger
Rollouts of the metrics query service, which delete the old pods. The client behaviour behind the failures came from an August 2021 rollout of the metrics query clients that applied round_robin as the new default gRPC load balancing policy.
- Root cause
- Component
- Contributing factor
- Detection
Errors rose during rollouts of the metrics query service, and the service's logs showed DNS errors when connecting to its data stores.
- Remediation
- Raised the memory of the node-local-dns pods from 64 MB to 256 MB, which stopped the OOM kills but not the DNS errors
- Tested larger instance types and confirmed that scaling up the service's infrastructure resolved the errors
- Removed the custom gRPC reconnect parameters from the clients to restore the defaults
- Action items
- Contribute a change to Cilium that adds an unreachable route for a deleted pod's IP so clients get an ICMP error
- Lessons
The errors looked like DNS but were not. ENA metrics and VPC Flow Logs gave the visibility into VPC connection tracking that host metrics did not, and Cilium, Kubernetes and AWS networking interact in ways that can make reverse path filtering drop packets it should allow. DNS propagation time depends on many settings. The causes were changes Datadog had made itself, to work around a dependency bug, to resolve earlier incidents and to override default reconnect parameters, which looked safe at the time and showed their effects much later, when the link was hard to see.
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.
These 3 cases involve CoreDNS and Client-side DNS resolver and cache. 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 cause2
Capacity exhaustion2 cases
- Contributing factor
- Organisation
Configuration change1 case
- Component
- Contributing factor
- Organisation