Cases2 cases
1 to 2 of 2
IL-0029Slow user-facing services from CPU throttling on containers that used far less CPU than their limitBuffer2020- Symptoms
Services on Buffer's kops-managed cluster on AWS (about 60 nodes and 1500 containers) answered more slowly than they should have. The container throttling metric showed that many containers were being throttled whatever their CPU usage was, including containers that never came close to their CPU limit.
- Trigger
CPU limits on user-facing services, enforced through CFS quota by a Linux kernel with a bug that throttled containers even when they were well under their limit.
- Root cause
- Component
- Contributing factor
- Detection
While reviewing the container throttling metric, the team noticed many containers being throttled even though their CPU usage stayed far below their limits.
- Remediation
- removed CPU limits from all services directly or indirectly on the users' critical path
- moved those services to dedicated tainted nodes and gave them matching tolerations
- set each service's CPU request to its peak usage over a few months plus a margin of more than 20%, and set memory requests the same way
- Action items
- Move nodes to a kernel that contains the CFS throttling fix (4.19 or later), which for Buffer means a kops version whose host image is Ubuntu 20.04
- After the kernel upgrade, check whether throttling is fully gone and update the post
- Lessons
A CPU limit can slow a service down even when the service uses a small part of it, because of how the kernel enforces CFS quota on older kernels; the throttling metric shows it, the CPU usage graph does not. Upgrading the kernel is the safer fix. Removing limits works for latency, but only together with honest CPU and memory requests, isolation of the unbounded services, and monitoring of node usage, since unbounded containers can starve the kubelet.
IL-0011HAProxy ingress piled requests onto the same pods because a Go template visited the backend map in sorted pod IP orderSkyscanner2019- Symptoms
On a Sunday, a team using one of Skyscanner's Kubernetes clusters manually paged the out-of-hours Kubernetes support because their service showed elevated latency, worst at the p90 and maximum levels.
- Trigger
Upgrading the HAProxy ingress controller to v0.6 and going back from Service virtual IPs to individual pod IPs as backends, on the understanding that the sort-backends flag introduced in v0.5, false by default, meant backends were randomly shuffled.
- Root cause
- Component
- Contributing factor
- Detection
A cluster user manually paged the out-of-hours Kubernetes support about elevated latency; Prometheus queries then showed the uneven request distribution across pods.
- Remediation
- switched the affected service from pod IPs back to the Service virtual IP through a config change in the internal deployment tool Slingshot
- patched the controller to keep each backend's servers in an insertion-ordered slice and changed the template to iterate over that slice
- tested the patch in sandbox clusters and rolled it out to the production clusters
- Action items
- Run the internal controller patch in production and return to pod IPs as the default backends
- Raise the problem upstream with a GitHub issue and pull request
- Test changes to cluster components against the specific behaviour and conditions that matter
- Lessons
The team already knew that sorted backends cause hot-podding and still did not test the new flag well enough to see that it did not work; changes to cluster components need tests aimed at the exact behaviour that matters, under conditions like production. A keyword can behave differently in different parts of a language: range over a map is unordered in Go code but sorted in text/template. A small cluster component can do outsized harm to every user of the cluster and, in the end, to customers.
These 2 cases involve Configuration templating 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 defect2 cases
- Component
- Contributing factor
- Organisation