StatefulSet Migration - Quick Start
β±οΈ Time Required: 2-4 hours πΎ Data Loss: None (old data was ephemeral anyway) βΈοΈ Downtime: ~2-5 minutes during migration
π One-Command Migrationβ
# Run automated migration script
./scripts/migrate-to-statefulset.sh
That's it! The script handles everything:
- β Creates BackendConfig for session affinity
- β Deletes old Deployment
- β Creates StatefulSet with persistent storage
- β Updates Ingress
- β Tests persistence
π What Gets Createdβ
Kubernetes Resourcesβ
| Resource | Name | Purpose |
|---|---|---|
| StatefulSet | coditect-combined | 3 pods with stable names |
| PVCs | workspace-coditect-combined-{0,1,2} | 50GB persistent storage per pod |
| PVCs | theia-config-coditect-combined-{0,1,2} | 5GB config storage per pod |
| Service | theia-headless | Headless service for StatefulSet |
| Service | coditect-combined-service | Load balancer with session affinity |
| BackendConfig | coditect-backend-config | Session affinity + timeout config |
| Ingress | coditect-ingress | WebSocket + cookie-based affinity |
File Structure Createdβ
k8s/
βββ theia-statefulset.yaml β Main StatefulSet config
βββ backend-config-stateful.yaml β Session affinity config
βββ ingress-stateful.yaml β Updated Ingress
scripts/
βββ migrate-to-statefulset.sh β Automated migration
βββ test-persistence.sh β Test data persistence
βββ test-session-affinity.sh β Test sticky sessions
docs/11-analysis/
βββ STATEFULSET-migration-guide.md β Complete documentation
β Quick Validationβ
Test 1: Verify StatefulSet Runningβ
kubectl get statefulset coditect-combined -n coditect-app
Expected: 3/3 READY
Test 2: Verify PVCs Createdβ
kubectl get pvc -n coditect-app
Expected: 6 PVCs (3 workspace + 3 config), all Bound
Test 3: Test Persistenceβ
./scripts/test-persistence.sh
Expected: β All tests passed, file persists across pod restart
Test 4: Test in Browserβ
- Open: https://coditect.ai/theia
- Create file:
/workspace/test.txt - Logout
- Login again
- File should still exist β
π§ How It Worksβ
Before Migration (Data Loss Issue)β
User creates file.txt
β
Stored in pod's ephemeral filesystem
β
Pod restarts/deployment update
β
File DELETED β
After Migration (Persistent Storage)β
User creates file.txt
β
Stored in PVC (50GB GCE Persistent Disk)
β
Pod restarts/deployment update
β
File PERSISTS β
Session Affinity (Same Pod Every Time)β
User visits coditect.ai/theia
β
Ingress assigns pod + sets cookie
β
User creates files on pod-0
β
User logs out and back in
β
Cookie routes to pod-0 again
β
User sees same files β
π― Key Featuresβ
Persistent Storage:
- 50GB
/workspacevolume per pod - Files persist across pod restarts
- Files persist across deployments
- Automatic GCE PD provisioning
Session Affinity:
- Cookie-based routing (3-hour timeout)
- ClientIP affinity at Service level
- Users stick to same pod
- Prevents "files disappeared" confusion
High Availability:
- 3 replicas (pods)
- Each pod has own workspace
- Load balanced across pods
- Graceful shutdown (120s grace period)
Pod Identity:
- Stable names:
coditect-combined-0,coditect-combined-1,coditect-combined-2 - DNS:
coditect-combined-0.theia-headless.coditect-app.svc.cluster.local - Predictable, debuggable
π Troubleshootingβ
Issue: Pods stuck in Pendingβ
Cause: PVC provisioning delay
Check:
kubectl describe pod coditect-combined-0 -n coditect-app
Solution: Wait 2-5 minutes for GCE Persistent Disk provisioning
Issue: Session affinity not workingβ
Cause: Ingress annotations not applied
Check:
kubectl get ingress coditect-ingress -n coditect-app -o yaml | grep affinity
Solution: Re-apply Ingress
kubectl apply -f k8s/ingress-stateful.yaml
Issue: Files still disappearingβ
Cause: PVC not mounted correctly
Check:
kubectl exec -it coditect-combined-0 -n coditect-app -- df -h /workspace
Expected: Should show GCE PD mount, not overlay filesystem
Solution: Check StatefulSet volumeMounts configuration
π Monitoring Commandsβ
# Check StatefulSet status
kubectl get statefulset coditect-combined -n coditect-app
# Check pods
kubectl get pods -n coditect-app -l app=coditect-combined
# Check PVCs
kubectl get pvc -n coditect-app
# Check pod logs
kubectl logs coditect-combined-0 -n coditect-app
# Exec into pod
kubectl exec -it coditect-combined-0 -n coditect-app -- bash
# Check events
kubectl get events -n coditect-app --sort-by='.lastTimestamp' | tail -20
π Rollback (If Needed)β
# Delete StatefulSet
kubectl delete statefulset coditect-combined -n coditect-app
# Re-create old Deployment
kubectl apply -f k8s/k8s-combined-deployment.yaml
# Verify
kubectl get deployment coditect-combined-v5 -n coditect-app
Note: Old Deployment had no persistence either, so no data lost in rollback.
π Documentationβ
- Complete Guide:
docs/11-analysis/STATEFULSET-migration-guide.md - Current State Analysis:
docs/11-analysis/CURRENT-STATE-POD-PERSISTENCE-analysis.md - Socket.IO + Persistence Fixes:
docs/11-analysis/socket-io-theia-persistence-insights.md
β Success Checklistβ
- Run migration script:
./scripts/migrate-to-statefulset.sh - Verify 3/3 pods running
- Verify 6 PVCs bound (3 workspace + 3 config)
- Run persistence test:
./scripts/test-persistence.sh - Run session affinity test:
./scripts/test-session-affinity.sh - Manual browser test (create file β logout β login β file exists)
- Check no errors in pod logs
- Monitor for 24 hours to ensure stability
Ready to migrate?
./scripts/migrate-to-statefulset.sh
Questions? See docs/11-analysis/STATEFULSET-migration-guide.md for complete documentation.