Cases5 cases
1 to 5 of 5
IL-0473Jenkins infrastructure went fully down after a pod IP range fix deleted every AKS node pool and could not recreate themJenkins project2023- Symptoms
On 7 July 2023 from 11:05 to 15:25 UTC many public Jenkins infrastructure services were completely down, including get.jenkins.io, plugins.jenkins.io, accounts.jenkins.io, javadoc.jenkins.io and incrementals.jenkins.io, while ci.jenkins.io, issues.jenkins.io, repo.jenkins-ci.org and www.jenkins.io were partly or completely disrupted.
- Trigger
After the upgrade to Kubernetes 1.25 changed the range of the pods' originating IP and LDAP access was blocked, a fix (Azure PR 431) deployed at 10:55 UTC to set a proper set of pod IP ranges removed all node pools of the cluster.
- Root cause
- Component
- Contributing factor
- Detection
After the upgrade, at 10:30 UTC, the team noticed that services inside the cluster, such as accounts.jenkins.io, could not reach the LDAP service.
- Remediation
- Created the cluster again from scratch with a fixed network setup
- Set a custom pod CIDR in a range separate from the virtual network
- Moved the services and their DNS records to new public IPs
- Pushed a pull request that recorded the manual rebuild, including the IP setup, in code
- Action items
- Protect the public IPs from deletion with a Management Lock
- Keep the public IPs in a separate resource group and point the Kubernetes-managed load balancers to it with the service.beta.kubernetes.io/azure-load-balancer-resource-group annotation
- Improve network diagrams and documentation so possible overlaps are visible when preparing operations
- Avoid changing the configuration of all AKS node pools at once
- Lessons
The team said that changing one node pool at a time would have shown the problem after the first pool and avoided a full outage, and that the public IPs should change as little as possible because users behind corporate firewalls with allow-lists depend on them. The team also noted that it could rebuild, in under 4 hours, the cluster that hosts almost all public services.
IL-0231Deleting EKS managed node groups also deleted Karpenter's instance profile, and every Stytch worker node shut downStytch2023- Symptoms
On 23 February 2023 Stytch's EKS worker nodes went Ready:Unknown one after another, Karpenter failed to launch replacement nodes, and with fewer and fewer pods scheduled the Live Stytch API went down for 14 minutes, returning 5XX on every call.
- Trigger
At 14:21 UTC Stytch landed a change to remove unused EKS managed node groups, because it had decided to run its data plane applications fully on nodes provisioned by Karpenter. Because Crossplane resources use an orphan deletion policy, engineers deleted the node groups in the AWS console, first in staging and then in production.
- Root cause
- Component
- Contributing factor
- Detection
Low-urgency alerts that Karpenter could not find the instance profile fired in staging at 16:06 UTC and in production at 17:48 UTC but were not treated as an incident. The incident process started at 20:26 UTC when node launch failures spiked the Karpenter error rate, and Kubernetes monitoring alerts in production followed at 20:44 UTC. The support team flagged the outage at 21:14 UTC.
- Remediation
- Reverted the node group deletion, which recreated the managed node groups
- Manually scaled up one of the Live API node groups with more and much larger nodes and removed its taints
- Removed node selectors from the applications one after another so their pods could be scheduled
- Action items
- Treat Karpenter errors as high-urgency alerts that page the on-call engineer
- Tune cluster alerting thresholds to send a high-urgency page earlier
- Add alerts for nodes that stay NotReady or Unknown for long periods
- Raise the thresholds of other deployment alerts, such as unschedulable pods and replicas not available
- Give Karpenter its own IAM instance profile, separate from the one used by the node groups
- Separate other AWS resources that were shared between uses, specifically IAM and security groups
- Rework the EKS and Karpenter configuration so system instance profiles are unique, static per cluster and generated by Karpenter
- Introduce a cloud visualization tool for engineers making infrastructure changes
- Add live system and product metrics to the status page
- Ask AWS to confirm the undocumented actions and side effects of deleting a node group
- Correct the shared use of IAM roles and security groups across the infrastructure
- Lessons
The IAM role for Karpenter's self-managed nodes should never have been the same as the one for the managed node groups; sharing it is what let the node group deletion break Karpenter, and the roles had been left combined for speed and simplicity when Karpenter was first set up. The hours-long delay between the configuration change and its effect made the incident hard to assess, and AWS confirmed that this delay is expected, so Stytch will allow for it in future IAM instance profile changes.
IL-0094Student pods filled the shared nodes of a JupyterHub cluster and starved the hub's core pods, freezing the hub2i2c2020- Symptoms
At 08:52 PM IST a report came in from WER that many students could not access the JupyterHub and that it was frozen; pages were stuck and nothing was usable. A rise in activity was visible by 09:02 PM, but the usual fixes, such as opening an incognito window and restarting servers, did not help.
- Trigger
WER students' pods used a good chunk of their memory limit (tests had shown they almost always use just under 1G of their 2G limit, against a 512M guarantee) on nodes shared with the hub's core pods.
- Root cause
- Component
- Contributing factor
- Detection
WER reported stuck pages and students unable to reach the hub in a GitHub issue (2i2c-org/docs#27).
- Remediation
- removed memory overcommit for the WER students
- raised resource guarantees for all core pods, which restarted them and moved some to a new node
- Action items
- Put user pods in a separate pool so they do not create pressure on the core pods (infrastructure#89)
- Set limits on the support infrastructure (Prometheus, Grafana, ingress) as well (infrastructure#90)
- Document and think about overcommit ratios for memory usage (infrastructure#91)
- Set up better Grafana dashboards to monitor resource usage (infrastructure#92)
- Document how people can get kubectl access to the cluster so others can look into issues too (infrastructure#87)
- Lessons
Core pods without resource guarantees get whatever is left on a node, so when user pods on the same nodes fill the CPU and memory, the hub that serves everyone freezes. The memory overcommit ratio has to come from measured use: WER students used just under 1G against a 512M guarantee, which a 4x overcommit could not hold.
- Symptoms
Overnight into 26 March 2019 (PDT), every Prow test job that needed a GCP project from Boskos, the Kubernetes test-infra service that hands out GCP projects to test jobs, failed. The required job pull-kubernetes-e2e-gce failed on every run, so no pull request could be merged in kubernetes/kubernetes for just over nine hours, and other projects saw similar failures.
- Trigger
At 23:04 PDT the node running the only Boskos pod was drained to be replaced with a 1.13 node during the upgrade of the Prow clusters from Kubernetes 1.11 to 1.13. The replacement pod started from the StatefulSet's current spec, which named a newer Boskos image containing the bug.
- Root cause
- Component
- Contributing factor
- Detection
Users reported the failure on GitHub at 02:50 and on Slack at 05:16 and 06:27, and an engineer saw the Slack reports on waking at 07:16. The Boskos monitoring dashboard showed the failure, but no alert caught it.
- Remediation
- Built and deployed a new Boskos image with the bug fixed
- Cleaned up the GCP projects that had been left open
- Action items
- Change the Boskos configuration so that deployments actually take effect (#11956)
- Automate Boskos deploys (#11957)
- Improve alerting on Boskos status (#11953)
- Lessons
The write-up lists what went poorly: a ten-hour upgrade was started shortly after 17:00 when on-call coverage ended at 18:00; deployments were not checked to confirm that something had actually rolled out; the Boskos StatefulSet was not set up to perform updates, so changing its spec left the old pod running; the December change appears never to have been tested; and Boskos was deployed by hand, unlike most of Prow, which left more room for error. Once people were available, the problem was fixed quickly.
IL-0054All ingress traffic lost while draining a GKE node pool because the load balancer only targeted new nodes without ingress-nginx podsDevOps Hof2019- Symptoms
While the old nodes of a GKE cluster were being drained to move workloads to a newly created node pool, none of the services in the cluster could be reached through ingress-nginx any more.
- Trigger
Cordoning and draining the old node pool removed those nodes from the GCP load balancer backend while the ingress-nginx pods were still running on them.
- Root cause
- Component
- Contributing factor
- Detection
The team noticed during the drain that no service in the cluster was reachable through ingress-nginx.
- Remediation
- deleted the nginx-ingress-controller pods still running on the old nodes so they were rescheduled on the new, ready nodes
- Lessons
With externalTrafficPolicy: Local, the load balancer can only reach nodes that run an ingress pod, and cordoned nodes leave the load balancer backend immediately; if the ingress pods stay behind on cordoned nodes, all ingress traffic stops. Before any change that might touch traffic, look twice into the documentation.
These 5 cases involve Node pool 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 cause4
Configuration change2 cases
- Contributing factor
- Organisation
Capacity exhaustion1 case
- Component
- Contributing factor
- Organisation
Faulty deployment1 case
- Contributing factor
- Organisation
Operator error1 case
- Contributing factor
- Organisation