Cases4 cases
1 to 4 of 4
- Symptoms
Nodes that already existed kept running, but every new node, spot or standard, on either v1.32 or v1.33, failed to initialise and could not join the cluster. Spot nodes that were preempted and recreated never came back, so services degraded progressively: background workers on spot instances, reporting services and order allocation stopped completely, and the APIs on existing nodes kept answering but could not scale for load spikes.
- Trigger
Google upgraded the GKE control plane from v1.32.x to v1.33.2 at the version deprecation deadline, although auto-upgrade was disabled on the node pools.
- Root cause
- Component
- Contributing factor
- Remediation
- Created a new GKE cluster at v1.33, the version of the forced upgrade
- Upgraded Istio to 1.27.1 for Kubernetes 1.33 compatibility
- Updated the cert-manager configuration for Kubernetes 1.33
- Migrated all production workloads to the new cluster and verified pod scheduling, DNS resolution, PVC mounting and external integrations
- Decommissioned the broken cluster
- Action items
- Configure all clusters to use the GKE stable release channel
- Implement a separate management cluster for Argo CD, monitoring and other control components (Q4 2025)
- Review spot instance usage for critical workloads and add on-demand fallback pools
- Document the SRE upgrade procedure: management cluster first, production after a monitoring period of several days
- Document a Kubernetes, Istio and cert-manager compatibility matrix
- Create an automated upgrade testing pipeline
- Reserve static IPs for quick migrations
- Pin versions of Istio, cert-manager, CSI and DNS addons
- Stay current with stable releases and regularly check GKE alerts and announcements to avoid deprecation deadlines
- Lessons
GKE upgrades the control plane at a version's deprecation deadline even when auto-upgrade is disabled, so staying inside the supported version window is how to avoid a forced upgrade. A control plane upgrade can leave existing nodes healthy while every new node fails, and spot nodes that cannot rejoin after preemption turn this into cascading failures. Relying heavily on spot instances for critical workers turned a node join failure into a progressive outage. Kubernetes upgrades have to be planned together with dependent components such as Istio and cert-manager, and without a standby cluster on the same provider there was no immediate failover; the only recovery left was building a new cluster.
- Symptoms
During peak hours, when Mercari's GKE clusters handle very high request rates, the platform team saw kube-dns reaching its limits. DNS query rates were high enough to overwhelm the kube-dns service.
- Trigger
Peak-hour traffic on the GKE clusters produced more DNS queries than the few kube-dns pods could answer.
- Root cause
- Component
- Contributing factor
- Detection
During peak hours the team saw frequent NXDOMAIN and truncated-response errors and recurring "failed to refresh DNS cache" errors on the clusters, which showed that kube-dns had reached its limits.
- Remediation
- deployed NodeLocal DNSCache on the Laboratory GKE cluster with a specific nodeAffinity to measure its effect
- rolled NodeLocal DNSCache out gradually to the Dev and Prod environments by labelling node pools so its pods could be deployed there
- Lessons
When every pod in a busy cluster resolves names through a few central kube-dns pods, DNS becomes a shared bottleneck, and a DNS failure quickly turns into higher latency, timeouts and cascading outages across microservices. A cache on each node takes most of that load off kube-dns and keeps resolution local to the node. Rolling the cache out first to an internal test cluster with nodeAffinity, and then node pool by node pool through labels, kept the blast radius of the change small.
IL-0027All CoreDNS pods landed on one node, the node ran out of memory, and DNS for the whole service went downBackpackr2025- Symptoms
Services on the production Amazon EKS cluster behind the idus marketplace threw intermittent errors whose cause was hard to pin down. Calls to external services such as RDS and Redis failed now and then, and whenever DNS traffic spiked, domain lookups answered slowly or failed outright.
- Trigger
All CoreDNS pods were scheduled onto the same node, and that node's memory usage spiked until it ran out of memory.
- Root cause
- Component
- Contributing factor
- Detection
The write-up does not say how the full outage was noticed. The earlier DNS trouble showed up as intermittent service errors, and investigating failed calls to RDS and Redis led to DNS resolution failures.
- Remediation
- deployed NodeLocal DNSCache as a DaemonSet in front of CoreDNS
- added a PodDisruptionBudget (maxUnavailable 1) and topologySpreadConstraints across zones for CoreDNS
- lowered ndots from 5 to 2 with dnsConfig in the Deployments
- Lessons
The CoreDNS setup that EKS creates by default (two pods) can be enough for a small or development cluster but becomes a bottleneck in a large production cluster, and DNS is a single point of failure that needs high availability and room to scale. Tuning the CoreDNS cache and buffer size only relieved the symptoms; the real load came from the extra queries that ndots:5 generates for external names. A CoreDNS pod without a memory limit can share a node's fate with everything else on it.
IL-0060Kubernetes 1.24 upgrade removed the master node label that Calico route reflectors selected on, dropping all pod routes and taking Reddit down for 314 minutesReddit2023- Symptoms
About two minutes after an engineer started the Kubernetes 1.23 to 1.24 upgrade of the cluster running Reddit's legacy stack, just after 19:00 UTC, the site stopped. The CDN edge request graph, which is kept separate from the cluster, showed traffic by status collapsing. Users saw the error page, a homepage with no posts, or plain errors.
- Trigger
An in-place upgrade of the legacy cluster from Kubernetes 1.23 to 1.24; in 1.24 the node-role.kubernetes.io/master label is removed even from running clusters.
- Root cause
- Component
- Contributing factor
- Detection
The site broke about two minutes into the upgrade; an incident was opened immediately and responders were on the call within three minutes, working from CDN edge graphs because the cluster's own metrics were gone.
- Remediation
- deleted the Open Policy Agent webhook configurations to stop API server timeouts
- terminated all worker nodes of the cluster
- restored the control plane from the pre-upgrade backup onto the first control plane node
- switched off the cluster autoscaler until the control plane was stable
- generated new TLS certificates so replacement control plane nodes could join etcd
- brought traffic back in steps from 1% to 100%
- restarted legacy services that had been stopped by hand
- Action items
- Codify cluster configuration so every choice has a record, and document in detail what cannot be codified
- Standardise components across clusters and replace bespoke configurations
- Build tooling to manage the lifecycle of whole clusters so they can be recreated or replicated
- Add pre-production clusters that can be tested with confidence
- Improve the backup restore process and make cluster upgrades safe
- Lessons
Configuration that exists only in a live cluster, edited by hand through a special tool, can be forgotten, as the route reflector setup was, and then break on an upgrade nobody connects it to. A Kubernetes upgrade cannot be reverted without a restore, so the restore procedure has to be kept current and practised. Consistent, codified clusters are what make upgrades testable; bespoke clusters keep producing outages.
These 4 cases involve Client-side DNS resolver and cache and Node pool. 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
Breaking change in an upgrade2 cases
- Component
- Contributing factor
IL-0101After Google forced a GKE control plane upgrade to 1.33.2 at a deprecation deadline, no new node could initialise, so autoscaling and spot node replacement stopped for 15 hoursWealthy2025IL-0060Kubernetes 1.24 upgrade removed the master node label that Calico route reflectors selected on, dropping all pod routes and taking Reddit down for 314 minutesReddit2023
Capacity exhaustion2 cases
- Component
- Contributing factor
- Organisation
IL-0080kube-dns on Mercari's GKE clusters could not keep up with peak-hour DNS query rates, and a Sev1 production outage followed when several services failed DNS resolutionMercari2025IL-0027All CoreDNS pods landed on one node, the node ran out of memory, and DNS for the whole service went downBackpackr2025