Incident Library
Applied filters FactorLimited debug accessDomainKubernetesClear allEvery case under the filters, with no sentence; newest first.
Suggested filters Search, and the values found in your words appear here.

Graph

  • Root cause
  • Component
  • Symptom
  • Contributing factor
  • Case

Cases14 cases

9 to 13 of 14

  1. Symptoms

    From April 11, 2022 at 13:17 UTC customers and Gitpod staff reported that Gitpod workspaces were intermittently becoming unresponsive. CPU usage of nodes and pods looked normal, with nothing maxed out, and at 13:58 UTC the team found that the workspaces were IO bound rather than CPU bound.

    Trigger

    The ws39 generation of workspace clusters, released to all regional clusters on April 8th at 20:08 UTC and to the XL clusters on April 9th at 17:45 UTC, split the 1TB disk into smaller RAID0 disks, changed CPU limiting and workspace networking, and moved to faster machine types.

    Root cause
    Component
    Contributing factor
    Detection

    Customers and Gitpod staff reported on April 11th at 13:17 UTC that workspaces were intermittently unresponsive, and the team opened an incident in Slack through its incident.io integration. On April 17th the team noticed increased CPU load on the workspace nodes and opened an internal incident.

    Remediation
    • Shifted workspace starts back to the ws38 clusters on April 11th
    • Built ws39a clusters with c2d machines and local SSDs and moved traffic to them
    • Requested a limit increase from Let's Encrypt
    • Routed EU XL traffic to the regional EU cluster and built ws-eu39bxl to replace the crashed ws-eu39xl
    • Cleaned up workspaces stuck in a stopping state so users could start them again
    • Released ws40 with 1TB boot disks to get more IO bandwidth
    • Removed the workspaces that consumed excessive CPU time for crypto-mining
    • Blocked the fraudulent users behind the crypto-mining from using Gitpod
    • Rolled back the ws-daemon change that broke CPU limiting and shipped the fix in the ws34 clusters
    • Blocked ACME HTTP requests to workspace ports so Let's Encrypt rate limits would not be hit again
    • Rolled out IO limiting with the ws41xl and ws41 clusters and moved traffic to them step by step
    Action items
    • Invest in test automation so that test results stop releases like this one
    • Vary the interval between traffic shifts to new clusters, with more time for larger releases
    • Add a risk assessment stage, to be automated, that governs changeset size and rollout speed of workspace cluster rollouts
    • Reduce the impact teams have on each other
    • Add review criteria that find backwards incompatible changes before pull requests are merged, and split such pull requests
    • Recommend rollback as the primary means of mitigation in the incident procedures, and look at automating it
    • Make the status page show the workspace service as down when it is, and update the playbooks
    • Keep incident communication in a single Slack channel and Google Meet
    • Put 10% of the engineering staff on the on-call rotation from May 9th and use that time on observability, alerting and stability
    Lessons

    Gitpod concluded that it should have committed to rolling back on April 11th instead of building and shipping fixes, which kept customers on degraded workspaces longer than necessary. A large release so soon after the previous one needed a risk assessment and slower traffic shifts, and backwards incompatible changes that block a rollback need to be found before pull requests are merged. Failure-free operations require experience with failure.

  2. Symptoms

    At 08:05 UTC on 2021-06-21 the API service's Apdex (the share of requests that finish within a target time) and Rails request queuing began trending the wrong way. At 09:01 the team found the API deployment unhealthy: it needed more pods for the day's growing traffic, but no new nodes could be added to give it pod capacity. Users saw slow responses; the review found no sign that error rates rose.

    Trigger

    Google Cloud ran out of SSD persistent disk stock in us-east1, the region GitLab.com runs in, while the API service needed more nodes for rising user traffic.

    Root cause
    Component
    Contributing factor
    Detection

    There was no alert on resource availability. Apdex and Rails queuing began trending the wrong way at 08:05 UTC and an engineer declared the incident in Slack at 08:43; finding the cause took a lot of log digging: cluster autoscaler errors about node pools in backoff, then ZONE_RESOURCE_POOL_EXHAUSTED at the instance-group level, and finally Google Cloud support naming SSD as the exhausted resource.

    Remediation
    • added a node pool that uses pd-standard disks
    • scaled the new node pool by hand across all three zones to relieve the API
    • brought more pd-standard node pools online for the other blocked workloads
    • stopped production deployments and opened a Google Cloud support case about the cluster autoscaler not working with the new node pools
    • changed node pools and nodeSelectors so the remaining workloads ran on pd-standard nodes
    • removed the SSD-backed node pools after a day without problems
    Action items
    • Move Kubernetes services to pd-standard disks (delivery#1837)
    • Capture resource exhaustion errors as a metric
    Lessons

    A cloud region can run out of one specific resource, here SSD persistent disks, and the only error may be a generic ZONE_RESOURCE_POOL_EXHAUSTED that does not name it. GitLab could neither monitor nor reserve resource availability, so detection took 22 hours and the cause came from Google Cloud support. The workloads ran fine on pd-standard disks. A second problem found on the way, a cluster autoscaler that does not fall back to another matching node pool when one cannot scale, slowed the move to the new node pools.

  3. Symptoms

    Dex, the OIDC proxy that handled Kubernetes authentication, stored its data in the Kubernetes API (storage type kubernetes, inCluster: true) and had built up a huge number of AuthRequest objects. Listing all AuthRequests timed out, and without the list they could not be deleted.

    Trigger

    The dex namespace was deleted so that Kubernetes would clean up the accumulated AuthRequest objects itself.

    Root cause
    Component
    Contributing factor
    Detection

    The speaker says he had got hints of the problem earlier. While the masters were down, plenty of alerts arrived in Slack, but monitoring could not be reached because authentication and port-forwarding no longer worked.

    Remediation
    • removed the kubernetes finalizer from the dex namespace by calling the API directly (kill-kube-ns)
    • deployed Dex to a new namespace with sane defaults
    Lessons

    Dex with Kubernetes as its storage keeps every AuthRequest as an API object, and with a long TTL they pile up until the API cannot list them. Deleting a namespace that holds that many objects makes Kubernetes list them in a loop and can overload the masters. Monitoring that is reached through cluster authentication is lost when authentication is what broke.

  4. Symptoms

    On 25 February 2019 the Kubernetes API server of the managed Azure cluster running the data100 hub became unreachable. kubectl failed for every operation and requests to create new resources failed, so when the hub pod stopped, no new one was created and users saw a proxy error message.

    Root cause
    Component
    Contributing factor
    Detection

    Infrastructure staff were notified in Slack at 11:34 and found that kubectl failed for all operations while the hub proxy was up.

    Remediation
    • Created a new cluster and requested a new NFS server in its resource group
    • Detached the data volumes from the old NFS server and moved them to the new cluster's resource group
    • Imported the ZFS pool into the new NFS server
    • Created the staging hub with helm and updated DNS
    • Created the prod hub with helm and updated DNS
    Action items
    • Monitor the API server endpoint remotely and alert when it is down
  5. Symptoms

    On 20 February 2019 at 08:03 CET, `kubectl logs -f <pod>` stopped working for every pod in the mybinder.org cluster on GKE. Because pod logs could not be read, build logs were no longer forwarded to users, although the builds themselves ran normally.

    Root cause
    Component
    Contributing factor
    Remediation
    • Cordoned node gke-prod-a-users-b921bb88-rd5d so it would be removed from the pool once empty
    • Drained the node and removed it from the pool, after which kubectl logs worked again
    Action items
    • Test that kubectl logs works and notify when it does not
    • Add the command for retrieving API server logs to the SRE guide
    • Describe in the SRE guide how to identify suspicious node networking status
    Lessons

    The root cause was very difficult to identify, partly because it appears to sit in the Kubernetes master or the GKE service itself. Capturing `kubectl describe node` for the suspicious node would have allowed a comparison with healthy nodes, and a node that reports no ExternalIP or InternalIP in its status was likely a direct symptom of the problem and can be used as a diagnostic in the future.

Check your cluster for this

These 14 cases involve Kubernetes API server and etcd. 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 cause7

Capacity exhaustion2 cases

  1. IL-0085 A 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 hours
  2. IL-0076 Kubernetes masters went down after Dex filled etcd with AuthRequest objects and deleting its namespace started an endless list-and-timeout loop

Configuration change3 cases

  1. IL-0005 A new telemetry service overloaded the Kubernetes API servers of large clusters and broke DNS-based service discovery for all OpenAI services
    OpenAI2024
  2. IL-0118 A global change to Kubernetes namespace labels made the networking layer recompute metadata and overwhelmed the control planes of three of OpenAI's largest GPU clusters
    OpenAI2024
  3. IL-0153 DOKS 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 networking

Software defect2 cases

  1. IL-0077 EKS cluster went read-only for over seven hours after Kyverno ephemeralreports filled the etcd database past its size limit
  2. IL-0174 After an upgrade to Fluent Bit 2.0, logging sidecars that used the Kafka output plugin kept restarting with SIGSEGV because the plugin read a corrupted record as a map without checking its type

Breaking change in an upgrade1 case

Contributing factor
Organisation
  1. IL-0501 Every node of the UToronto Kubernetes cluster on Azure went NotReady and the JupyterHub became unreachable
    2i2c2022

Certificate or credential expiry1 case

Organisation
  1. IL-0113 The managed GKE control plane of Webhook Relay's main cluster failed because its API server certificates had never been rotated, and a manual credential rotation reported success without taking effect

Faulty deployment2 cases

  1. IL-0591 Gitpod workspaces in all regions became IO bound and unresponsive for days after the ws39 workspace cluster release
    Gitpod2022
  2. IL-0466 Prow scheduled test job pods onto its service cluster, leaving hundreds Pending and starving Prow's own services

Cloud provider outage3 cases

  1. IL-0205 The GKE cluster autoscaler could not add nodes to GitLab.com's production cluster because Google Cloud ran out of SSD persistent disks in us-east1
    GitLab2021
  2. IL-0469 The managed Azure Kubernetes API server for the data100 hub stopped answering, so the stopped hub pod was not recreated
  3. IL-0505 kubectl logs failed on GKE with "No SSH tunnels currently open" and mybinder.org build logs stopped reaching users