Cases3 cases
1 to 3 of 3
IL-0012CPU limits and an unpatched kernel CFS quota bug throttled multi-threaded services into stalls, failed health checks and timeoutsOmio2020- Symptoms
For about six months, applications on Omio's Google Kubernetes Engine clusters stalled at random: they got stuck, stopped answering health check requests or lost network connections, and nothing the team looked at explained why.
- Trigger
Multi-threaded workloads running with CPU limits on nodes whose kernel did not yet have the fix for a known CFS quota bug that causes unnecessary throttling.
- Root cause
- Component
- Contributing factor
- Detection
Months of random stalls and failed health checks led the team to read the cgroup cpu.stat throttling counters inside the pods, which showed far more throttling than the limits should allow.
- Remediation
- removed CPU limits until the kernel with the CFS bug fix was deployed across all clusters
- Action items
- Deploy the kernel with the CFS quota bug fix across all clusters
- Monitor utilisation, saturation and error metrics, API latency and error rates to confirm the change behaves as expected
- Lessons
A CPU limit is a time quota per 100 ms period, not a share of cores, so a multi-threaded container can be stopped for most of each period long before it uses the cores it was given, and a kernel bug can make that worse. Throttling is invisible in standard Kubernetes metrics and has to be read from the cgroup counters. Removing limits trades away protection against a container that takes a whole node, which is only acceptable when runtimes are tuned.
IL-0074All AirMap platform services down as worker nodes went NotReady and pods crash-looped on network and DNS failuresAirMap2018- Symptoms
At about 15:00 UTC on 19 July 2018, monitoring alerted on rising 5xx responses from several APIs, most notably pilot and tiles. Logins failed first, because the pilot service fetches the user's profile, and from there all services became unresponsive. Every affected API ran on the production Kubernetes cluster.
- Root cause
- Component
- Contributing factor
- Detection
Monitoring alerted on an increase in 5xx responses from several APIs, most notably pilot and tiles.
- Remediation
- restarted the kubelets on the stuck worker nodes, which did not last
- restarted all worker nodes in a staggered order starting at about 18:00 UTC, which took about 1.5 hours
- Action items
- Restart nodes on a rolling schedule to keep nodes and kubelets healthy until the fixes land upstream and reach the cloud provider, Microsoft Azure
- Lessons
When nodes keep falling back to NotReady after kubelet restarts and pods fail on network and DNS errors, a known upstream bug may be the cause; matching the symptoms to the upstream issue tracker, with help from the community, found the cause and the fix candidates.
IL-0003linkerd lost Kubernetes service discovery after an etcd reconfiguration, and restarting every linkerd instance turned failed payments into a full platform outageMonzo2017- Symptoms
At 14:10 an engineer deployed a change to a service that Monzo's current account needs to process payments, and every request to that service started to fail. Current account customers saw payment failures; the prepaid card was not affected at first because it does not use that service. The change was rolled back at 14:12, but the errors continued.
- Trigger
At 14:10 an engineer deployed a change to a service needed to process current account payments. Two weeks earlier the etcd cluster had been upgraded and grown from three to nine nodes, and one day earlier another team had scaled a new service down to zero replicas while leaving its Kubernetes service in place.
- Root cause
- Component
- Contributing factor
- Detection
Payment failures began right after the 14:10 deploy. The team rolled back at 14:12 and declared an outage internally at 14:16. At 15:13, when no service could serve requests, practically all automated alerts fired.
- Remediation
- Rolled back the payments service change (the errors continued)
- Activated internal backup processes so most customers could still use their card
- Restarted all linkerd instances (this made the outage worse)
- Restarted the three Kubernetes API server processes so replacement linkerd instances could start
- Began deploying a newer linkerd version with the fix for empty services
- Deleted the Kubernetes service that had no endpoints, which let linkerd load service discovery again
- Action items
- Fix the bug in Kubernetes that can trigger timeouts after a cluster reconfiguration
- Roll out a new version of linkerd that fixes the parsing error
- Create better health checks, dashboards and alerts for the affected components so they give clearer signals about what is wrong and prevent human error
- Improve procedures to communicate outages internally and externally as clearly and quickly as possible
- Lessons
A large failure in a distributed system can be very hard to understand, and well-meant human action can compound it, as restarting every linkerd instance did here by exposing a second incompatibility. Because Monzo deploys often and its network changes constantly, the deployment and request-routing systems have to be trustworthy. Monzo committed to publishing a similar post-mortem for any incident of this severity.
These 3 cases involve kubelet and Container CPU limit. 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
Software defect3 cases
- Contributing factor
IL-0012CPU limits and an unpatched kernel CFS quota bug throttled multi-threaded services into stalls, failed health checks and timeoutsOmio2020IL-0074All AirMap platform services down as worker nodes went NotReady and pods crash-looped on network and DNS failuresAirMap2018IL-0003linkerd lost Kubernetes service discovery after an etcd reconfiguration, and restarting every linkerd instance turned failed payments into a full platform outageMonzo2017