🚀 Kubernetes + WebSockets: Quick Reference Cheat Sheet
📚 Core Concepts (The Building Blocks)
Pod
- What: Smallest deployable unit in Kubernetes
- Analogy: A single container running your app
- Reality: Usually wraps a Docker container
- Important: Each pod has its own memory/state
- Lifespan: Temporary - can be killed and recreated anytime
Service
- What: Internal load balancer
- Analogy: A phone switchboard
- Reality: Routes traffic to healthy pods
- Important: Has a stable internal address
- Key Feature: Can enable session affinity
Ingress
- What: External load balancer / front door
- Analogy: Hotel receptionist
- Reality: Routes external traffic to services
- Important: Handles HTTPS/SSL
- Key Feature: Cookie-based sticky sessions
Deployment
- What: Manages pod lifecycle
- Analogy: A supervisor
- Reality: Ensures N pods are always running
- Important: Handles rolling updates
- Key Feature: Auto-restarts failed pods
Node
- What: Physical or virtual machine
- Analogy: A computer
- Reality: The hardware running your pods
- Important: Multiple pods per node
- In GKE: Google-managed virtual machines
🔌 WebSocket Problem & Solution
The Problem
❌ Without Session Affinity:
User → Ingress → Pod 1 (WebSocket opens)
User → Ingress → Pod 2 (doesn't know about user!) 💔
Result: Connection breaks
The Solution
✅ With Session Affinity:
User → Ingress → Pod 1 (WebSocket opens)
↓ (saves cookie)
User → Ingress → Pod 1 (cookie routes here) ✅
Result: Same pod every time!
Three Layers of Stickiness
-
Service Level (Layer 4)
sessionAffinity: ClientIP- Based on user's IP address
- Fast but breaks if IP changes
-
Ingress Level (Layer 7)
nginx.ingress.kubernetes.io/affinity: "cookie"- Browser gets a cookie
- Survives IP changes
- Most reliable
-
Application Level
- Your app can track connections
- Store in Redis
- Requires custom code
⚙️ Essential kubectl Commands
Viewing Resources
# See everything
kubectl get all
# Watch pods in real-time
kubectl get pods -w
# Check pod status with details
kubectl describe pod <pod-name>
# View application logs
kubectl logs <pod-name>
kubectl logs -f <pod-name> # Follow logs
# Check which pods are running
kubectl get pods -o wide
# See services and their IPs
kubectl get services
Deploying & Updating
# Deploy from YAML
kubectl apply -f kubernetes-config.yaml
# Update image version
kubectl set image deployment/chat-app \
chat-container=gcr.io/project/app:v2
# Scale manually
kubectl scale deployment chat-app --replicas=5
# Check rollout status
kubectl rollout status deployment/chat-app
# Rollback if needed
kubectl rollout undo deployment/chat-app
Debugging
# Get shell inside pod
kubectl exec -it <pod-name> -- /bin/bash
# Port forward to local machine
kubectl port-forward service/chat-service 8080:80
# Check events (shows errors)
kubectl get events --sort-by='.lastTimestamp'
# Check resource usage
kubectl top pods
kubectl top nodes
# Describe any resource
kubectl describe ingress chat-ingress
kubectl describe service chat-service
Managing Pods
# Delete a pod (auto-recreated by deployment)
kubectl delete pod <pod-name>
# Delete deployment (kills all pods)
kubectl delete deployment chat-app
# Restart all pods (recreates them)
kubectl rollout restart deployment chat-app
📋 Common Kubernetes Patterns
Pattern 1: Deployment with 3 Replicas
apiVersion: apps/v1
kind: Deployment
metadata:
name: chat-app
spec:
replicas: 3 # Run 3 pods
selector:
matchLabels:
app: chat
template:
metadata:
labels:
app: chat # THIS LABEL IS CRITICAL
spec:
containers:
- name: chat-container
image: your-image:v1
ports:
- containerPort: 8000
Pattern 2: Service with Session Affinity
apiVersion: v1
kind: Service
metadata:
name: chat-service
spec:
type: ClusterIP
sessionAffinity: ClientIP # STICKY SESSIONS
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800 # 3 hours
selector:
app: chat # Matches deployment label
ports:
- port: 80
targetPort: 8000
Pattern 3: Ingress with WebSocket Support
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: chat-ingress
annotations:
# CRITICAL FOR WEBSOCKETS
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
spec:
rules:
- host: chat.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: chat-service
port:
number: 80
🔍 Troubleshooting Guide
Problem: Pods Won't Start
Check Status
kubectl get pods
kubectl describe pod <pod-name>
Common Causes:
- ❌ Image not found → Check image name
- ❌ ImagePullBackOff → Check registry access
- ❌ CrashLoopBackOff → Check app logs
- ❌ Insufficient resources → Check node capacity
Problem: Can't Connect to App
Check Ingress
kubectl get ingress
kubectl describe ingress chat-ingress
Common Causes:
- ❌ No external IP → Wait or check ingress controller
- ❌ Wrong domain → Check DNS settings
- ❌ Firewall → Check GCP firewall rules
- ❌ Service not found → Check service name
Problem: WebSocket Closes Immediately
Check Timeouts
kubectl describe ingress chat-ingress | grep timeout
Solutions:
# Add these annotations
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
nginx.ingress.kubernetes.io/websocket-services: "chat-service"
Problem: Messages Only Reach Some Users
This is EXPECTED without cross-pod messaging!
Each pod only knows about its own users. Solutions:
-
Redis Pub/Sub
# Pod 1 publishes message
redis.publish('chat', message)
# All pods subscribe
redis.subscribe('chat') -
Message Queue
- RabbitMQ
- Google Pub/Sub
- Apache Kafka
-
Database Polling
- Store messages in database
- All pods query for new messages
- Slower but simpler
💰 Cost Optimization Tips
Development
# Use smaller machines
--machine-type e2-small
# Use preemptible nodes (70% cheaper)
--preemptible
# Scale down when not in use
kubectl scale deployment chat-app --replicas=1
Production
# Use autoscaling
--enable-autoscaling \
--min-nodes 3 \
--max-nodes 10
# Use committed use discounts
# (Reserve capacity for 1-3 years)
# Use regional clusters for HA
--region us-central1
Don't Forget to Clean Up!
# Delete cluster when done testing
gcloud container clusters delete chat-cluster
📊 Monitoring Essentials
Health Checks
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 10
Resource Limits
resources:
requests:
memory: "128Mi" # Minimum needed
cpu: "100m"
limits:
memory: "256Mi" # Maximum allowed
cpu: "500m"
Autoscaling
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: chat-hpa
spec:
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
🎯 Best Practices Checklist
Security
- Use HTTPS (not HTTP)
- Limit container privileges
- Scan images for vulnerabilities
- Use network policies
- Rotate secrets regularly
Reliability
- Set resource limits
- Configure health checks
- Use multiple replicas
- Set pod disruption budgets
- Handle graceful shutdown
Performance
- Enable horizontal autoscaling
- Use appropriate machine types
- Cache where possible
- Monitor resource usage
- Optimize Docker images
Operations
- Use version tags (not :latest)
- Keep logs centralized
- Set up monitoring/alerts
- Document your setup
- Test disaster recovery
🔗 Label Matching (CRITICAL!)
Labels connect everything. They must match exactly:
# Deployment creates pods with label
template:
metadata:
labels:
app: chat # ← This label
# Service finds pods by label
selector:
app: chat # ← Must match!
# HPA targets deployment
scaleTargetRef:
name: chat-app # ← Deployment name
If labels don't match:
- Service won't route to pods
- No traffic reaches your app
- Everything looks healthy but nothing works!
Check labels:
kubectl get pods --show-labels
kubectl get service chat-service -o yaml
📖 Glossary
| Term | Simple Definition |
|---|---|
| Pod | Container running your app |
| Node | Computer running pods |
| Service | Internal address for pods |
| Ingress | External entrance |
| Deployment | Manages pod lifecycle |
| Replica | Copy of a pod |
| Label | Tag for organizing resources |
| Selector | Query to find labeled resources |
| Namespace | Virtual cluster within cluster |
| ConfigMap | Configuration storage |
| Secret | Sensitive data storage |
| Volume | Persistent storage |
| Probe | Health check |
| HPA | Auto-scaler for pods |
| ClusterIP | Internal-only service |
| LoadBalancer | External service |
| Session Affinity | Sticky connections |
🚀 Quick Start Workflow
# 1. Create cluster
gcloud container clusters create my-cluster \
--zone us-central1-a --num-nodes 3
# 2. Build & push image
docker build -t gcr.io/PROJECT/app:v1 .
docker push gcr.io/PROJECT/app:v1
# 3. Deploy
kubectl apply -f kubernetes-config.yaml
# 4. Check status
kubectl get pods
kubectl get service
kubectl get ingress
# 5. View logs
kubectl logs -f <pod-name>
# 6. Test
curl http://EXTERNAL_IP
# 7. Update
docker build -t gcr.io/PROJECT/app:v2 .
docker push gcr.io/PROJECT/app:v2
kubectl set image deployment/app container=gcr.io/PROJECT/app:v2
# 8. Clean up
gcloud container clusters delete my-cluster
💡 Remember
- Pods are temporary - They can die anytime
- Services are stable - They provide consistent addressing
- WebSockets need stickiness - Always enable session affinity
- Labels must match - Deployment ↔ Service ↔ Ingress
- Health checks are critical - Kubernetes relies on them
- Each pod is isolated - Use Redis/queue for cross-pod messaging
- Monitor everything - You can't fix what you can't see
- Start small - 3 pods is fine for testing
- Clean up resources - Prevent surprise bills
- Read the logs - They tell you what's wrong
Need Help?
- Kubernetes Docs: https://kubernetes.io/docs/
- GKE Docs: https://cloud.google.com/kubernetes-engine/docs
- WebSocket Guide: https://kubernetes.io/docs/concepts/services-networking/ingress/#websockets
Pro Tip: Keep this cheat sheet handy. Kubernetes has a lot of moving parts, and it's normal to reference documentation frequently!