Cases4 cases
1 to 4 of 4
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-0460Vault served an expired TLS certificate and almost every GoCardless service pod crash-looped, a 22-minute full outageGoCardless2020- Symptoms
On Sunday 25 October 2020 the GoCardless API, dashboard, payment pages and partner integrations were all unavailable for 22 minutes, from 07:32 to 07:54 GMT. Automated monitoring paged the on-call engineer at 07:32, a minute after every request to the API had started failing because no healthy backend was left.
- Trigger
At 07:22 the TLS certificate Vault was still serving expired. cert-manager had already renewed it, but Vault does not load a new certificate without a restart or a SIGHUP.
- Root cause
- Component
- Contributing factor
- Detection
Automated monitoring detected the failing requests and paged the on-call engineer at 07:32. Certificate expiry monitoring existed for the Layer-7 load balancers but did not cover the TCP load balancer that Vault uses.
- Remediation
- Forced cert-manager to recreate the Vault certificate
- Restarted the Vault cluster by hand so it loaded the new certificate
- Deleted some pods of critical workloads to skip their 5-minute exponential backoff
- Action items
- Check the certificate of the TCP load balancer in front of Vault with the Blackbox exporter, as for the Layer-7 load balancers
- Deploy the Reloader controller to roll Vault when its certificate data changes
- Change theatre-envconsul so envconsul no longer manages the child process and only injects secrets at container startup
- Lessons
A system that almost every service depends on, such as the secrets store, can take everything down at once, and failure scenarios like Vault becoming unreachable had not been tested enough. Assuming the certificate had expired, when it had been renewed but not reloaded, added a slow and unnecessary recreation step to the recovery.
- Symptoms
At 10:43 on 14 August 2020 two of the six ingress controller pods in the cluster were in a crash loop. Restarting those pods did not fix them.
- Root cause
- Component
- Contributing factor
- Detection
Two of the six ingress controller pods were seen crash-looping at 10:43; the incident was declared at 11:01.
- Remediation
- restarted the leader ingress controller pod so the other replicas could connect and get the latest nginx configuration
IL-0503mybinder.org launches failed after a GKE node ran out of memory and its nginx-ingress proxy pod crash-loopedBinder Project2017- Symptoms
On 30 November 2017 at 16:59 PST, mybinder.org operators noticed that Grafana looked wrong and that launching a new server failed with an error that a temporary user could not be created. Pods that were already running kept running, but no new ones were being created.
- Trigger
A build container, which ran without a memory limit, most likely used up all the memory on the node that ran the proxy pod.
- Root cause
- Component
- Contributing factor
- Detection
An operator happened to look at Grafana at 16:59 PST, saw that it looked wrong, and confirmed the error by launching a new server.
- Remediation
- Cordoned the node that had run out of memory
- Uncordoned the node once the proxy was working
- Action items
- Limit the memory available to build pods
- Change the JupyterHub configuration so user pods are not cleaned up when the jupyterhub pod restarts
- Nominate one person to drive the response, possibly in a shared terminal, so only one person changes the cluster
- Alert when something is wrong with the cluster, for example by counting 4xx responses on the jupyterhub pod
These 4 cases involve Ingress controller and Container memory limit. 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
Capacity exhaustion3 cases
- Contributing factor
- Organisation
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 dayDFDS2024IL-0093Ingress controller pods crash-looped one after another because the leader pod had exhausted its shared memoryIL-0503mybinder.org launches failed after a GKE node ran out of memory and its nginx-ingress proxy pod crash-loopedBinder Project2017
Certificate or credential expiry1 case
- Component
- Contributing factor
- Organisation