Cases2 cases
1 to 2 of 2
IL-0063VPN outage after recreating a Redis StatefulSet restarted the whole Redis cluster without readiness checksAdGuard VPN2025- Symptoms
The day began with an alert that several instances of the Redis cluster were running out of disk space. That part was fixed quickly. The outage came an hour later: right after the Redis StatefulSet was deleted and recreated at 8:10 UTC, Kubernetes restarted every Redis pod within about five minutes, and problems started to appear.
- Trigger
To make Git match the volumes that had been resized by hand, the Redis StatefulSet was deleted with orphan (non-cascading) deletion and recreated with the new storage template; Kubernetes reconciled the new spec by restarting the entire Redis cluster.
- Root cause
- Component
- Contributing factor
- Detection
An alert about Redis instances running out of disk space started the work; the outage itself showed up as backend errors about Redis connections right after the StatefulSet was recreated.
- Remediation
- made the Redis masters forget obsolete node identities, reset the affected replicas and rejoined them, then waited for replication to catch up
- identified the component that was actually running out of memory, scaled the backend service and raised memory limits for that component
- temporarily relaxed probes so backend instances took traffic immediately instead of flapping between ready and not ready
- reverted the temporary workarounds at 10:00 UTC
- Action items
- Add startup probes so a Redis pod is not marked ready until its dataset is loaded
- Build an own control plane for Redis that handles restarted pods stuck to an old master address
- Reduce dependence on the single Redis cluster: move some important data to other stores, such as a separate Redis cluster per server, and use Kafka for some backend components
- Lessons
The disk resize was not the problem; the cleanup afterwards was. An immutable field pushes operators toward deleting and recreating the controller, and that can set off a full reconcile. Startup and readiness probes are what slow a rolling restart down to a safe pace; without them a distributed store restarts in the most fragile way. Recovery plans must expect a cluster to heal slowly, and dependent services need to degrade gracefully while it does.
- Symptoms
Nodes that already existed kept running, but every new node, spot or standard, on either v1.32 or v1.33, failed to initialise and could not join the cluster. Spot nodes that were preempted and recreated never came back, so services degraded progressively: background workers on spot instances, reporting services and order allocation stopped completely, and the APIs on existing nodes kept answering but could not scale for load spikes.
- Trigger
Google upgraded the GKE control plane from v1.32.x to v1.33.2 at the version deprecation deadline, although auto-upgrade was disabled on the node pools.
- Root cause
- Component
- Contributing factor
- Remediation
- Created a new GKE cluster at v1.33, the version of the forced upgrade
- Upgraded Istio to 1.27.1 for Kubernetes 1.33 compatibility
- Updated the cert-manager configuration for Kubernetes 1.33
- Migrated all production workloads to the new cluster and verified pod scheduling, DNS resolution, PVC mounting and external integrations
- Decommissioned the broken cluster
- Action items
- Configure all clusters to use the GKE stable release channel
- Implement a separate management cluster for Argo CD, monitoring and other control components (Q4 2025)
- Review spot instance usage for critical workloads and add on-demand fallback pools
- Document the SRE upgrade procedure: management cluster first, production after a monitoring period of several days
- Document a Kubernetes, Istio and cert-manager compatibility matrix
- Create an automated upgrade testing pipeline
- Reserve static IPs for quick migrations
- Pin versions of Istio, cert-manager, CSI and DNS addons
- Stay current with stable releases and regularly check GKE alerts and announcements to avoid deprecation deadlines
- Lessons
GKE upgrades the control plane at a version's deprecation deadline even when auto-upgrade is disabled, so staying inside the supported version window is how to avoid a forced upgrade. A control plane upgrade can leave existing nodes healthy while every new node fails, and spot nodes that cannot rejoin after preemption turn this into cascading failures. Relying heavily on spot instances for critical workers turned a node join failure into a progressive outage. Kubernetes upgrades have to be planned together with dependent components such as Istio and cert-manager, and without a standby cluster on the same provider there was no immediate failover; the only recovery left was building a new cluster.
These 2 cases involve Persistent volumes and stateful sets and In-memory cache. 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
Configuration change1 case
- Contributing factor
- Organisation
Breaking change in an upgrade1 case
- Component
- Contributing factor
- Organisation