Graph
Cases3 cases
1 to 3 of 3
IL-0153DOKS worker nodes went NotReady at 06:00 UTC on three days because a systemd timer in the Debian image ran apt upgrade and killed it mid kernel upgrade, breaking node networkingDigitalOcean2023- Symptoms
Customers of DigitalOcean Managed Kubernetes (DOKS) saw worker nodes go NotReady between 06:00 and 07:00 UTC and stay unavailable, taking down the services on them, until the nodes were replaced or rebooted; some nodes needed several replacements or reboots. The first sporadic reports on October 8 said replacing the node fixed it. The same thing happened again around 06:00 UTC on October 9, more widely and across many regions, and again on October 10. Only clusters on versions 1.27.6-do.0 and 1.28.2-do.0 were affected.
- Trigger
A systemd timer in the DigitalOcean Debian image started apt upgrade daily at 06:00 UTC, with a random delay of up to 60 minutes.
- Root cause
- Component
- Contributing factor
- Detection
Sporadic customer reports of failed worker nodes arrived at 07:43 UTC on October 8; internal incident response started at 07:10 UTC on October 9 after broader impact across regions.
- Remediation
- Advised customers to replace or reboot affected worker nodes
- Arranged SSH and console access to worker nodes while they were healthy, and live-debugged an affected node on October 10
- Released a DaemonSet to all affected clusters that disables the apt upgrade systemd timer on every worker node
- Released new node images without the auto-update process
- Action items
- Disable the timer during node provisioning, then remove the DaemonSet from all clusters
- Add a check to the internal conformance test suite for new cluster versions that the auto-upgrade process and other unwanted timers stay disabled
- Support logging into worker nodes even when normal access paths are broken
- Lessons
An operating system auto-update timer left enabled in a node image can change the kernel and systemd underneath Kubernetes, and a timeout that kills the upgrade half-way can leave a node without networking. Failures that start at the same time every day point to a scheduled job on the nodes, and systemd timers belong on that list next to cron jobs. When the failure takes out a node's network, an investigation that depends on logging into the node stalls; access paths that work while the node is broken shorten diagnosis.
IL-0008An unresponsive OPA validating webhook crash-looped the API server during a GKE master upgrade, and node auto-repair then recreated every nodeJetstack2019- Symptoms
Jetstack was upgrading the master of a development cluster that many teams use to test their apps during the working day, a regional Google Kubernetes Engine (GKE) cluster in europe-west1. The upgrade ran through Jetstack's GKE Terraform pipeline and did not finish before the 20-minute Terraform timeout, while the GKE console still showed the cluster as upgrading.
- Trigger
A planned master upgrade of the shared development cluster. The same upgrade had been done on another pre-production environment earlier that day, and no API downtime was expected.
- Root cause
- Component
- Contributing factor
- Detection
The first sign was the master upgrade missing the 20-minute Terraform timeout; re-running the pipeline returned the kube-apiserver unhealthy error. The cause was identified with the help of Google Support.
- Remediation
- Deleted the OPA ValidatingAdmissionWebhook resource during a window of API server access
- Action items
- Limit the OPA webhook to the namespaces where the policy applies and development teams have access
- Enable the webhook only for Ingress and Service resources, the only resources the policy validates
- Add a liveness probe so OPA is restarted when it stops responding, and update the OPA documentation
- Follow the open upstream Kubernetes issue about this behaviour
- Lessons
With alerting on API server response times, the team might have seen CREATE and UPDATE requests slow down across the board as soon as the OPA-backed webhook was first deployed. Every workload needs probes: OPA looked so simple to deploy that the team skipped the Helm chart, which adds a livenessProbe for the admission controller containers among other adjustments to the tutorial configuration. Others had hit the same problem, and an upstream issue to improve it was still open.
IL-0035Worker nodes went NotReady after a new ElastAlert rule without memory limits used up node memoryNU.nl2019- Symptoms
The NU.nl development team got reports that several services on one of its Kubernetes clusters behaved erratically: occasional error pages, slow responses and timeouts. The affected services were mostly internal tools and dashboards.
- Trigger
A new ElastAlert rule, deployed shortly before from the command line, that fired if the Cloudfront-* Elasticsearch indexes stopped receiving documents; those indexes take a few million requests per hour, and the rule made ElastAlert's memory grow without bound.
- Root cause
- Component
- Contributing factor
- Detection
Users reported error pages, slow responses and timeouts from several services; no alert fired.
- Remediation
- terminated the NotReady nodes one by one so the auto-scaling group replaced them (the new nodes also went NotReady, but Prometheus and Grafana landed on a stable node)
- found the ElastAlert pods' memory growth on the Grafana pod memory dashboard
- fixed the ElastAlert problem that caused the memory growth
- Action items
- Define alerts on resource usage such as CPU, memory and disk space
- Keep researching an alerting strategy that combines Elasticsearch, Prometheus Alertmanager and New Relic
- Consider exporting metrics out of the cluster and running Grafana outside it, on EC2 or a separate Kubernetes cluster
- Either visualise the important metrics in the ELK stack or make Prometheus and Grafana more available, and improve the metrics strategy
- Set resource limits for ElastAlert through the Helm values
- Configure namespaces with default memory requests and limits
- Isolate customer-facing workloads from build, logging and monitoring workloads (a dedicated node group, or later a separate tools cluster)
- Deploy everything through automation such as Jenkins pipelines, and consider a GitOps approach
- Deploy through a pipeline that includes a smoke test step
- Make Kubernetes and cloud infrastructure work part of the team's sprints, picked up by all team members while pairing with more experienced members, and hold workshops that go deep into specific topics
- Lessons
Fixing the root cause covers only a small part of what an incident can teach; the chain of smaller failures around it is where most of the learning is. A pod without a memory limit can take whole nodes down, so limits need defaults at the namespace level. Monitoring that runs inside the cluster it watches goes blind with it. Changes installed by hand from the command line leave the rest of the team without a record of what changed.
These 3 cases involve kubelet and Admission webhook. 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
Configuration change3 cases
- Component
- Contributing factor
- Organisation
IL-0153DOKS worker nodes went NotReady at 06:00 UTC on three days because a systemd timer in the Debian image ran apt upgrade and killed it mid kernel upgrade, breaking node networkingDigitalOcean2023IL-0008An unresponsive OPA validating webhook crash-looped the API server during a GKE master upgrade, and node auto-repair then recreated every nodeJetstack2019IL-0035Worker nodes went NotReady after a new ElastAlert rule without memory limits used up node memoryNU.nl2019