Incident Library
Applied filters ComponentPersistent volumes and stateful setsDomainKubernetesClear 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

Cases16 cases

13 to 16 of 16

  1. Symptoms

    Shortly after 9am UTC on 17 July 2018, the disk space of the GitLab cluster behind gitlab.freedesktop.org was critical, and some API requests were failing because of the shortage. The administrator first learned of the failure when people mentioned it on IRC.

    Trigger

    Many recently created forks of Mesa, each about 2.1GB, filled the disk space of the GitLab cluster.

    Root cause
    Component
    Contributing factor
    Detection

    People mentioned the failure on IRC. Monitoring and alerting on disk usage and API error rate had not been set up yet.

    Remediation
    • Dropped all inbound traffic to GitLab at the firewall except from the administrator's IP
    • Took a manual backup by streaming tar over SSH to an encrypted partition on a local machine
    • Snapshotted all GCE disks behind the PersistentVolumes
    • Copied the data from the old disk snapshots to new enlarged volumes through a temporary GCE VM
    • Re-did the copy into new empty volumes with the correct directory structure and checked repositories, users and workflows
    • Restored public access to GitLab
    Action items
    • Set up monitoring, logging and alerts
    • Find ways to communicate outages much better; this one was announced only on IRC, and the lists were not told when it dragged on
    • Use the Cloud console clients instead of the slow Cloud Console web UI
    • Add more GitLab administrators, ideally someone familiar with Kubernetes deployments
    • Move from the single Omnibus container to GitLab's cloud native deployment with one container per service
    • Move storage to resizeable volumes or to Google Cloud Storage
    Lessons

    The backup step alone used up the outage window; backups had grown along with the disk problem, and a test run before announcing the window could have measured it. The changes had been tested on a scratch cluster, but not exactly as run, and tests of steps such as disk snapshots could have been more realistic. A single GitLab administrator who was new to Kubernetes was a single point of failure. Keeping at least three copies of the data from the first destructive step meant no data was lost.

  2. Symptoms

    On 13 March 2018 at 07:28 CET the mybinder.org team noticed that JupyterHub had not been spawning new users and that the launch success rate on the Grafana dashboard had been at zero for several hours. Many pods were in the states "Unknown" and "NodeLost", on at least the nodes `10.128.0.7` and `10.128.0.5`.

    Root cause
    Component
    Contributing factor
    Detection

    The team noticed only after several hours, when the launch success rate on the Grafana dashboard had been at zero for a long time. No Stackdriver alert email arrived in time, because those emails were marked as spam and reached the team hours later.

    Remediation
    • Cordoned the bad nodes
    • Deleted the hub pod in Unknown state and the hub pod stuck in ContainerCreating
    • Reset node gke-prod-a-ssd-pool-32-134a959a-n2sk from the GCP web interface to force the PVC to be released
    • Force-deleted every pod in Unknown or NodeLost state with kubectl delete --grace-period=0 --force
    Action items
    • Investigate why the outage started, through Stackdriver logs and Google Cloud incidents
    • Set up an alerting service that does not depend on Stackdriver
    • Document how to check whether a PVC has not been released
    • Document how to restart a node by hand when commands are not working
    • Document how to delete pods that are in Unknown state
    Lessons

    The error went unnoticed for a long time because Stackdriver alert emails were marked as spam and arrived hours late. Once the problem was found, each step was logged and the steps were made more forceful as needed, so the hub was down only briefly after detection.

  3. Symptoms

    A user reported that pods were starting up and then vanishing. When the cluster operators looked, kubectl get pods and kubectl get nodes returned two different sets of data that alternated back and forth, as if there were two opinions of the cluster's state.

    Trigger

    etcd write latency rose far above the healthy single-digit milliseconds; the speakers say trouble starts once the database sync time crosses double digits or several hundred milliseconds.

    Root cause
    Component
    Contributing factor
    Detection

    A user reported pods starting up and vanishing.

    Remediation
    • restored service on a replacement cluster
    • freed persistent volumes from the old cluster one by one so they could bind in the new cluster
    • updated DNS records that pointed at the old cluster's load balancer names
    Action items
    • Make the Kubernetes API server request quorum reads from etcd
    Lessons

    etcd is extremely sensitive to write latency; once the database sync time crosses double digits of milliseconds, stale reads or badly degraded performance follow. Without quorum reads, a consistent store can still hand out stale data. Documentation for a fast-moving system changes, so read it again regularly. Moving workloads to a new cluster is hard when they hold persistent volumes or when DNS records point at generated load balancer names.

  4. Symptoms

    At about 1 AM on 9 February 2017, UC Berkeley's DataHub was reported down: users trying to log in got a proxy error. The hub pod was running, but its log was full of sqlite errors.

    Trigger

    While debugging, an operator ran `.save jupyterhub.sqlite` in sqlite3 inside the hub pod without having attached the database, which replaced the JupyterHub database file with an empty one.

    Root cause
    Component
    Contributing factor
    Detection

    DataHub was reported down at about 1 AM, when users got a proxy error at login. At 1:12 AM a user reported that he could log in but all his notebooks were gone.

    Remediation
    • Scaled the hub to 0 replicas
    • Rebuilt the JupyterHub sqlite database by matching Kubernetes PVC names back to user ids
    • Set cookie_id to null instead of a dummy value and attached the rebuilt database to the hub
    • Changed the cookie secret in the hub pod and restarted it to log all users out
    • Deleted all user pods to log everyone out
    • Ran a script that filled in cookie_id for all users, restarted the hub and deleted all user pods again
    • Dropped the new users with a '.' in their name and renamed the older users from '-' to '.'
    Action items
    • Report upstream that JupyterHub uses only part of the cookie secret and discards the rest
    • Report upstream that the cookie_id column of the users table should have UNIQUE and NOT NULL constraints
    • Ask KubeSpawner to support username hashes in PVC and pod names so the names stay the same when the database is deleted
    • Ask OAuthenticator to support using the id from the Google authenticator as the user id, giving stable user ids
    • Switch to Google Cloud SQL, a hosted and managed MySQL database
    • Take regular and tested backups of the database
    • Start an operational FAQ of things to do and not to do
    • Set up better monitoring and paging
    • Document escalation procedures explicitly
Check your cluster for this

These 16 cases involve Persistent volumes and stateful sets and Database. 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 cause9

Configuration change2 cases

  1. IL-0063 VPN outage after recreating a Redis StatefulSet restarted the whole Redis cluster without readiness checks
  2. IL-0009 A duplicated generated name made Argo CD replace the InfluxDB Cloud production Application and delete the whole production environment

Breaking change in an upgrade1 case

Organisation
  1. IL-0101 After Google forced a GKE control plane upgrade to 1.33.2 at a deprecation deadline, no new node could initialise, so autoscaling and spot node replacement stopped for 15 hours

Operator error3 cases

  1. IL-0095 An engineer deleted the prod namespace of the LEAP JupyterHub while believing the kubeconfig pointed at a new cluster, and the hub was down for about an hour
    2i2c2025
  2. IL-0197 Moving a three-node Elasticsearch StatefulSet to new persistent volumes split the cluster in two, because the Helm chart hardcoded cluster.initial_master_nodes to elasticsearch-0
    Palark2021
  3. IL-0506 UC Berkeley DataHub logins failed and students got empty home directories after the JupyterHub database was overwritten

Capacity exhaustion4 cases

  1. IL-0067 Redis filled its persistent volume, corrupted its append-only file and crash-looped on every restart
  2. 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
  3. IL-0500 UToronto JupyterHub logins and server starts returned 500 errors when the hub's sqlite database disk filled up
    2i2c2022
  4. IL-0518 gitlab.freedesktop.org on GKE ran short of volume space and a planned 30-minute storage upgrade became a 4-hour outage

Dependency failure1 case

Organisation
  1. IL-0489 Rejoining a failed node of Magic Pages' three-node MySQL cluster broke its metadata and took customer websites down

Certificate or credential expiry1 case

Contributing factor
Organisation
  1. IL-0521 AKS pods could not mount volumes and new nodes got no CNI network interface after the cluster service principal expired

Software defect2 cases

Organisation
  1. IL-0196 Adding a second Redis replica and lowering memory limits in one RedisFailover change restarted the only Redis pod that held data, and Sentinel promoted the empty new replica, erasing the data
    Palark2020
  2. IL-0072 High etcd write latency made the API servers return stale data, and the production cluster flipped between two views of its state

Cloud provider outage1 case

Organisation
  1. IL-0193 A GCP persistent disk degradation took down a Cassandra StatefulSet whose OrderedReady policy blocked recovery, and Metrictank could not reconnect to the recreated pods, causing a 23-hour Graphite query outage

unknown1 case

Contributing factor
Organisation
  1. IL-0402 mybinder.org launches dropped to zero for hours because a JupyterHub pod on a lost GKE node kept its hub database PVC