Cases3 cases
1 to 3 of 3
IL-0002CI builder pods could not get AWS IAM credentials because kubelet fell minutes behind its API rate limitZalando2019- Symptoms
Builds on Zalando's in-house Continuous Delivery Platform (CDP), which runs CI/CD on Kubernetes, timed out and failed for almost an hour on 11 June 2019. The Kubernetes builder pods could not get AWS IAM credentials.
- Trigger
An unlucky rescaling of the CDP Kubernetes cluster left only one node available for builder pods. Builder pods were created and deleted on that node so quickly that kubelet fell behind.
- Root cause
- Component
- Contributing factor
- Remediation
- Scaled the CDP cluster up by hand so builder pods spread over more than one node
- Action items
- Raise the kubelet QPS limit from the default 5 to 50 in the global cluster configuration
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-0031Kubernetes API server OOM-killed, leaving the Skipper ingress without routes; the talk points to a misconfigured CronJob manifestZalando2018- Symptoms
Customers were affected, and Zalando's IAM service answered requests with HTTP 404. The talk shows this on slides titled "Customer impact" and "IAM returning 404", followed by a slide on the number of pods in the cluster.
- Trigger
A CronJob (apiVersion batch/v2alpha1, schedule "*/15 9-19 * * Mon-Fri") whose concurrencyPolicy: Forbid and job history limits sat inside the pod template spec instead of the CronJob spec. The talk shows it right after the slides on the number of pods and the API server being OOM-killed, and the lessons add a quota on the number of pods.
- Root cause
- Component
- Contributing factor
- Remediation
- fixed the CronJob manifest: moved concurrencyPolicy: Forbid and the job history limits to the CronJob spec, added activeDeadlineSeconds: 120 and changed the schedule to "7 8-18 * * Mon-Fri"
- Action items
- Make the ingress stay healthy during API server problems
- Make the ingress keep the last known set of routes
- Use a ResourceQuota on the number of pods (the example sets pods: "1500")
- Lessons
An AWS ALB routes traffic to all hosts when all hosts report unhealthy, so the ingress should stay healthy during API server problems. An ingress controller that reads routes from the API server should keep its last known set of routes. Use a quota for the number of pods.
These 3 cases involve Kubernetes API server and CI system. 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-0002CI builder pods could not get AWS IAM credentials because kubelet fell minutes behind its API rate limitZalando2019IL-0001Cluster-wide DNS outage after CoreDNS pods were OOM-killed again and again under a burst of DNS queriesZalando2019IL-0031Kubernetes API server OOM-killed, leaving the Skipper ingress without routes; the talk points to a misconfigured CronJob manifestZalando2018