Cases2 cases
1 to 2 of 2
- Symptoms
At 09:36 on 18 March 2025, during the upgrade of the live cluster to EKS 1.30, users reported that their pods were being terminated and were not restarting automatically, in both production and non-production environments. Automated infrastructure alerts fired as well, and production services had outages.
- Trigger
Upgrading the live EKS cluster from 1.29 to 1.30, during which the descheduler attempted to reschedule all pods on the cordoned nodes simultaneously.
- Root cause
- Component
- Contributing factor
- Detection
Users reported at 09:36 that pods were being terminated and not restarting, and automated infrastructure alerts fired.
- Remediation
- Removed the cordon annotation so pods could be rescheduled
- Deleted stuck 1.30 nodes to force their recreation
- Added a new node group of 20 nodes running 1.30 by hand
- Cordoned and drained all old 1.29 nodes onto the new 1.30 nodes
- Action items
- Raise an AWS Production System Down support case (Case ID: 174229643100496)
- Get guidance from AWS support on querying control-plane logs to find the root cause of similar issues
- Document a runbook for emergency scaling of a new node group in case of unexpected capacity shortages
- Alert on an imbalance between the autoscaling group and the Kubernetes nodes
- Review the descheduler configuration to understand why it throws pods off cordoned nodes, and fix it where possible
- Alert on spikes in the pending pod count
- Lessons
The write-up lists review actions rather than lessons. They show the team had no documented way to add an emergency node group, no alert on a mismatch between the autoscaling group and the nodes Kubernetes sees, no alert on a spike in pending pods, and no clear understanding of how the descheduler treats cordoned nodes.
IL-0014A GKE upgrade to a withdrawn version stalled on slow drains and a stuck node pool, then broke an ingress and confused the HPAloveholidays2019- Symptoms
On the evening of a long-overdue upgrade of a loveholidays production GKE cluster from 1.10.X to 1.12.5-gke.10, planned to take 2 to 2.5 hours, the master upgrade and the first two 7-node NodePools went smoothly. After that the NodePool upgrades slowed to a crawl. Each node is cordoned, drained and upgraded in turn. Even a 14-node cluster at about 5 minutes per node took over an hour, and with about 100 more nodes to go, some of them taking over 15 minutes to drain, the sequential drains were too slow to finish at a reasonable hour.
- Trigger
A manual upgrade of the GKE masters and NodePools from 1.10.X to 1.12.5-gke.10, two versions at once, on 19 March 2019; GKE's release notes of 14 March had already said that version was no longer available for new clusters or master upgrades because masters showed elevated error rates, but it could still be selected.
- Root cause
- Component
- Contributing factor
- Detection
The slow drains, zombie nodes and stuck NodePool were seen by the engineer running the upgrade; the broken Ingress was noticed after the upgrade and explained by Google support; the HPA problem was noticed the next day.
- Remediation
- drained the remaining NodePool nodes ahead of the upgrade with kubectl drain --ignore-daemonsets --delete-local-data
- deleted the zombie instances from the managed instance group with gcloud compute instance-groups managed delete-instances
- cancelled the stuck UPGRADE_NODES operation with gcloud beta container operations cancel
- used kubectl port-forward in place of the broken internal Ingresses
- scaled down the older of two active ReplicaSets, or triggered a dummy deployment, to bring the HPA back
- Action items
- Alert when a HorizontalPodAutoscaler is at 70% and at 100% of its capacity
- Alert when a deployment has had two active ReplicaSets for 30 minutes and for 60 minutes
- Re-evaluate termination grace periods that were set to arbitrary large values
- Read the GKE release notes before every cluster upgrade
- Use auto-upgrade in non-production environments, and manual cluster upgrades with automatic node upgrades in production
- Keep environments as identical as possible, including resource names
- Lessons
Read the release notes before upgrading: the target version had been withdrawn five days earlier. Drain time depends on pod configuration, so emptyDir volumes, long grace periods and missing disruption budgets turn a NodePool upgrade into hours. Pre-production only catches problems like the ingress bug if it matches production down to resource names. Auto-upgrades in non-production surface problems early, and a mix of manual cluster upgrades and automatic node upgrades in production keeps clusters current without much effort.
These 2 cases involve Cluster autoscaler 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
Faulty deployment1 case
- Contributing factor
- Organisation
Cloud provider outage1 case
- Contributing factor
- Organisation