Skip to main content

🚀 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

  1. Service Level (Layer 4)

    sessionAffinity: ClientIP
    • Based on user's IP address
    • Fast but breaks if IP changes
  2. Ingress Level (Layer 7)

    nginx.ingress.kubernetes.io/affinity: "cookie"
    • Browser gets a cookie
    • Survives IP changes
    • Most reliable
  3. 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:

  1. Redis Pub/Sub

    # Pod 1 publishes message
    redis.publish('chat', message)

    # All pods subscribe
    redis.subscribe('chat')
  2. Message Queue

    • RabbitMQ
    • Google Pub/Sub
    • Apache Kafka
  3. 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

TermSimple Definition
PodContainer running your app
NodeComputer running pods
ServiceInternal address for pods
IngressExternal entrance
DeploymentManages pod lifecycle
ReplicaCopy of a pod
LabelTag for organizing resources
SelectorQuery to find labeled resources
NamespaceVirtual cluster within cluster
ConfigMapConfiguration storage
SecretSensitive data storage
VolumePersistent storage
ProbeHealth check
HPAAuto-scaler for pods
ClusterIPInternal-only service
LoadBalancerExternal service
Session AffinitySticky 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

  1. Pods are temporary - They can die anytime
  2. Services are stable - They provide consistent addressing
  3. WebSockets need stickiness - Always enable session affinity
  4. Labels must match - Deployment ↔ Service ↔ Ingress
  5. Health checks are critical - Kubernetes relies on them
  6. Each pod is isolated - Use Redis/queue for cross-pod messaging
  7. Monitor everything - You can't fix what you can't see
  8. Start small - 3 pods is fine for testing
  9. Clean up resources - Prevent surprise bills
  10. Read the logs - They tell you what's wrong

Need Help?

Pro Tip: Keep this cheat sheet handy. Kubernetes has a lot of moving parts, and it's normal to reference documentation frequently!