π Mission Debrief: Lost Connection - Labels & Selectors¶
What Happened¶
Your Service had a selector for app: frontend, but your Pod had the label app: backend. Since the labels didn't match, the Service couldn't find the Pod and had no endpoints. Without endpoints, traffic sent to the Service had nowhere to go.
How Kubernetes Behaved¶
Services don't directly manage Pods. Instead, they use label selectors to dynamically discover which Pods should receive traffic.
The process:
1. Service created with selector: app: frontend, tier: api
2. Service controller watches all Pods
3. Finds Pods matching ALL selector labels
4. Creates Endpoints object with matching Pod IPs
5. Routes traffic to those endpoints
Your Service was looking for app=frontend, but your Pod was labeled app=backend, so step 3 failedβno matches found.
The Correct Mental Model¶
Labels are key-value pairs attached to Kubernetes objects:
Selectors are queries that filter objects by labels:
How Services Use Selectors:
Service selector: {app: backend, tier: api}
β
Looks for pods with matching labels
β
Pod 1: {app: backend, tier: api} β
Match!
Pod 2: {app: frontend, tier: api} β app doesn't match
Pod 3: {app: backend, tier: db} β tier doesn't match
Pod 4: {app: backend, tier: api, env: prod} β
Match! (extra labels OK)
β
Creates Endpoints with IPs of Pod 1 and Pod 4
Important: All labels in the selector must match, but pods can have extra labels.
Real-World Incident Example¶
Company: Fintech startup processing $10M daily Impact: 3-hour payment processing outage Cost: $125K in SLA violations + 400 customer support tickets
What happened:
During a routine deployment, a DevOps engineer updated the payment service deployment and accidentally changed the pod label from app: payment-processor to app: payment-service.
The Service still had selector app: payment-processor. Result: instant disconnect. All payment pods became unreachable. The load balancer kept the Service alive, but with 0 endpoints.
Why it took 3 hours:
- Service remained "up" (no alerts fired)
- Health checks targeted the Service, which existed (but had no backends)
- Logs showed "connection refused" but team thought it was network issues
- Finally discovered via: kubectl get endpoints payment-service showed empty
- Checked: kubectl get pods --selector=app=payment-processor showed 0 pods
The fix: Changed the Service selector to match the new label. Endpoints appeared instantly.
Lesson learned: 1. Never change pod labels without updating corresponding services 2. Monitor endpoint counts (alert if endpoints = 0) 3. Use Horizontal Pod Autoscaler labels for consistency 4. Consider using consistent naming conventions
Commands You Mastered¶
# Check service and its selector
kubectl get service <name> -n <namespace>
kubectl describe service <name> -n <namespace>
kubectl get service <name> -n <namespace> -o yaml | grep -A 5 selector
# Check endpoints (the IPs service routes to)
kubectl get endpoints <name> -n <namespace>
kubectl describe endpoints <name> -n <namespace>
# View pod labels
kubectl get pods --show-labels -n <namespace>
kubectl get pod <name> -n <namespace> --show-labels
# Find pods matching a selector
kubectl get pods --selector=app=backend -n <namespace>
kubectl get pods -l app=backend,tier=api -n <namespace>
# Add/modify labels on running pods
kubectl label pod <name> app=frontend -n <namespace>
kubectl label pod <name> app=backend --overwrite -n <namespace>
# Delete resources
kubectl delete -f <file>.yaml
Label Best Practices¶
-
Use recommended labels (from Kubernetes docs):
-
Keep selectors simple: 1-3 labels max
- Don't change labels on running pods if services depend on them
- Use consistent values:
backendnotBackendorback-end - Document your labels: Maintain a label glossary for your org
Understanding Endpoints¶
Endpoints are the bridge between Services and Pods:
kubectl get endpoints <service-name>
NAME ENDPOINTS
backend-service 10.244.0.5:5678,10.244.0.6:5678
β These are Pod IPs matching the selector
If ENDPOINTS is empty = service has no backends = traffic fails.
Common reasons for empty endpoints: - β Label mismatch (what you just fixed!) - β No pods exist - β Pods exist but not Ready - β Port mismatch in Service - β Pods in different namespace
What's Next?¶
Labels are used everywhere in Kubernetes: - Services selecting Pods (you just learned this!) - Deployments managing ReplicaSets - NetworkPolicies filtering traffic - Node selectors for scheduling - Volume claims selecting storage
Next challenge: You'll debug a container port mismatch!