Cases3 cases
1 to 3 of 3
IL-0085A control plane node of Magic Pages' Kubernetes cluster on Hetzner Cloud ran out of memory, the cluster's own calls then used up the Hetzner API rate limit, and all customer websites were down for about 7.5 hoursMagic Pages2025- Symptoms
At around 09:33 UTC one of the three control plane nodes of the Kubernetes cluster that hosts Magic Pages went offline. Looking at the node showed that it had run out of memory.
- Trigger
One of the three control plane nodes ran out of memory and went offline at about 09:33 UTC; the attempts to replace it with hetzner-k3s failed while the cluster's own components were exhausting the Hetzner API rate limit.
- Root cause
- Component
- Contributing factor
- Detection
The founder found the control plane node offline at about 09:33 UTC. Monitoring alerts about unreachable customer websites started around the time the replacement attempts failed, and about half an hour of investigation identified the exhausted Hetzner API rate limit.
- Remediation
- powered off all servers of the Kubernetes cluster to stop the API requests so the Hetzner rate limit could recover
- waited until ratelimit-remaining had built up a buffer before starting recovery
- restarted the control plane servers
- started the essential Longhorn components by hand so Longhorn could heal and make storage volumes available
- restarted the remaining websites by hand
- Action items
- Monitor the Hetzner API call rate coming from the Kubernetes cluster nodes themselves to get early warning of high usage
- Get a higher Hetzner API rate limit; Hetzner support was contacted
- Investigate how to reduce the cluster's reliance on a single API, including alternatives to hetzner-k3s
- Document and test a procedure for recovering Longhorn after a full cluster shutdown
- Lessons
The running cluster, not only the deployment tooling, consumed the cloud provider's API quota, and in a failure it consumed it fast enough that the quota never recovered. The default limit of 3600 requests per hour was not enough for failure and recovery scenarios, and API usage from inside the cluster was not monitored. A tool that hides the provider's API errors slows diagnosis. After a full, non-graceful shutdown, Longhorn needed manual intervention to come back, which lengthened the outage.
IL-0110A Grafana Agent pod's high memory use and crash-looping Hangfire pods drove a Kubernetes node into system OOM and NotReady, twice in one dayDFDS2024- Symptoms
At 10:01 UTC on 2024-03-13 a Kubernetes node entered NotReady state, with CPU requests at 78% and memory requests at 82%. An alert fired in Slack at 10:03 and was picked up at 10:05. An attempt to SSH into the node at 10:13 failed because it was unresponsive; it started responding again at 10:19.
- Trigger
Pods of a dev container that used Hangfire to trigger jobs failed with OOM and crash-looped on a node where a Grafana Agent pod was already using a lot of memory.
- Root cause
- Component
- Contributing factor
- Detection
A Slack alert fired two minutes after the node went NotReady and was picked up two minutes later; the second node's NotReady at 15:03 also raised a Slack alert.
- Remediation
- marked the EC2 instance unhealthy so a new node started
- cordoned and force-drained the NotReady node and terminated its EC2 instance
- removed the new LimitRange from the Grafana Agent namespace and restarted the Grafana Agent pod
- scaled the dev container to 0 replicas, after which EC2 network traffic returned to normal
- after the second NotReady, scaled the dev container to 0 replicas again and added a new node
- emailed the team that owns the dev container, which confirmed it was working on a fix
- Action items
- Move grafana-agent to the monitoring node group
- Add alerts for when bandwidth across the cluster reaches a certain threshold
- Investigate whether memory limits can be set on the grafana-agent Helm chart
- Investigate grafana-agent memory usage
- Ask Grafana support whether grafana-agent should use a PVC
- Consider pushing node logs to Loki with limited retention
- Create a wiki page with common metrics and log queries to check when investigating issues with Kubernetes nodes
- Lessons
Dev workloads mixed with production let one crash-looping dev container take down nodes that production also used, and a monitoring agent outside its dedicated node group added to the memory pressure. Scaling the suspect container back up before its owners had fixed it brought the failure back on the replacement node. The team also noted that action items from earlier post-mortems need follow-up, and that knowledge of useful CloudWatch metrics had not been shared, which made the diagnosis harder.
IL-0040Parallel Helm installs saturated small gp2 root volumes on a kops cluster and left all three workers NotReady with the kubelet or Docker downSaltside2017- Symptoms
While running the CI process on a local machine to test an application Helm chart, the SRE lead watched the pods with watch kubectl get pods. All pods reached Running, and then some went back to Pending. Two hours later the problem had grown and some pods showed the phase Unknown.
- Trigger
A CI run installed the application's Helm charts for all four markets (Efritin.com, Tonaton.com, Ikman.lk and Bikroy.com) on the nonproduction cluster at the same time.
- Root cause
- Component
- Contributing factor
- Detection
The SRE lead saw pods go from Running back to Pending while watching kubectl get pods during the CI run; no monitoring raised an alert, even when all three workers were not ready.
- Remediation
- terminated the three worker nodes and let the auto scaling group replace them
- Action items
- Fix the Datadog integration for the nonproduction AWS account and repeat the installs with telemetry
- Increase the worker root EBS volumes from 20GB to 120GB
- Keep common base images pulled on every node with a DaemonSet until kops supports user hooks
- Configure different allocation limits for the different layers in Kubernetes
- Discuss a highly available Tiller with the Helm team
- Find a way to throttle the number of newly created pods
- Lessons
An ordinary deploy of the application could collapse the cluster, because the default 20GB gp2 root volumes could not keep up with parallel image pulls and container starts. Without node metrics and pod phase metrics, three NotReady workers raised no alert. A single Tiller replica can block the deploy that would fix an outage.
These 3 cases involve Cloud controller manager and Container runtime. 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-0085A control plane node of Magic Pages' Kubernetes cluster on Hetzner Cloud ran out of memory, the cluster's own calls then used up the Hetzner API rate limit, and all customer websites were down for about 7.5 hoursMagic Pages2025IL-0110A Grafana Agent pod's high memory use and crash-looping Hangfire pods drove a Kubernetes node into system OOM and NotReady, twice in one dayDFDS2024IL-0040Parallel Helm installs saturated small gp2 root volumes on a kops cluster and left all three workers NotReady with the kubelet or Docker downSaltside2017