🚀 Resource Optimization in Kubernetes
Making Your Containers Just Right (Like Goldilocks!)
The Goldilocks Story of Containers
Imagine you’re packing lunch boxes for a school trip.
- Too big a box? You waste space and carry extra weight.
- Too small a box? Your sandwich gets squished!
- Just right? Perfect fit, easy to carry, nothing wasted.
Kubernetes resource optimization is exactly like this. We want each container to have just enough resources—not too much, not too little.
🎯 What You’ll Learn
- Resource Best Practices → Rules for smart resource use
- Right-sizing Containers → Finding the perfect fit
- Cost Optimization → Spending less, getting more
- Cost Management Tools → Helpers that track your spending
📚 Part 1: Resource Best Practices
The Golden Rules of Resource Management
Think of resources like electricity at home. You don’t leave all lights on—you use what you need.
Rule 1: Always Set Requests AND Limits
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
What does this mean?
| Setting | What It Does | Real-Life Example |
|---|---|---|
requests |
“I need at least this much” | Booking a table for 4 |
limits |
“I will never use more than this” | Maximum occupancy sign |
Rule 2: Use Resource Quotas
Resource Quotas are like a family budget. Everyone gets a fair share.
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-budget
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
Example: Your team gets 4 CPUs and 8GB RAM guaranteed. No one team can hog all resources!
Rule 3: Use LimitRanges for Defaults
LimitRanges are like automatic seatbelts—they protect you even if you forget.
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
spec:
limits:
- default:
cpu: "500m"
memory: "512Mi"
defaultRequest:
cpu: "100m"
memory: "128Mi"
type: Container
Why? If someone forgets to set limits, these kick in automatically!
graph TD A["Pod Created"] --> B{Has Resource Limits?} B -->|Yes| C[Use Pod's Limits] B -->|No| D["Apply LimitRange Defaults"] C --> E["Schedule Pod"] D --> E E --> F{Within ResourceQuota?} F -->|Yes| G["✅ Pod Runs"] F -->|No| H["❌ Pod Rejected"]
🎯 Part 2: Right-sizing Containers
The Art of “Just Right”
Right-sizing means giving containers exactly what they need—no more, no less.
The Problem: Guessing Games
Most people guess their container needs:
- Over-provisioning: Asking for 4GB RAM when you only use 500MB
- Under-provisioning: Asking for 128MB when you need 1GB
Both are bad! 🙁
The Solution: Observe, Then Adjust
Step 1: Start with reasonable defaults
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "200m"
Step 2: Watch actual usage
kubectl top pods
Example Output:
NAME CPU(cores) MEMORY(bytes)
my-app-abc 45m 180Mi
my-app-def 52m 195Mi
Step 3: Adjust based on reality
If your app uses ~50m CPU and ~200Mi memory:
resources:
requests:
cpu: "75m" # ~1.5x actual usage
memory: "300Mi" # ~1.5x actual usage
limits:
cpu: "150m" # ~3x actual usage
memory: "400Mi" # ~2x actual usage
💡 The Magic Formula
| Metric | Request Should Be | Limit Should Be |
|---|---|---|
| CPU | 1.2x - 1.5x average | 2x - 3x average |
| Memory | 1.2x - 1.5x average | 1.5x - 2x average |
Why different multipliers?
- CPU: Containers can wait for CPU (they slow down)
- Memory: Containers get killed if they exceed memory limits! (OOMKilled)
graph TD A["Deploy with Estimates"] --> B["Monitor for 1-2 Weeks"] B --> C["Collect Usage Data"] C --> D{Usage < 50% of Request?} D -->|Yes| E["Reduce Resources"] D -->|No| F{Hitting Limits Often?} F -->|Yes| G["Increase Resources"] F -->|No| H["✅ Resources Optimal"] E --> B G --> B
💰 Part 3: Cost Optimization
Spending Less, Getting More
Cloud bills can grow fast! Here’s how to keep them in check.
Strategy 1: Use Spot/Preemptible Nodes
What are they? Cheaper cloud machines that can be taken away with short notice.
Perfect for:
- Batch jobs
- Development environments
- Stateless workloads
Example Node Pool:
apiVersion: v1
kind: Node
metadata:
labels:
cloud.google.com/gke-spot: "true"
Savings: Up to 70-90% cheaper than regular nodes!
Strategy 2: Autoscaling (Scale Smart)
Horizontal Pod Autoscaler (HPA): Add more pods when busy
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Cluster Autoscaler: Add/remove nodes based on demand
| Time of Day | Traffic | Nodes | Cost |
|---|---|---|---|
| 2 AM | Low | 2 | $ |
| 10 AM | Medium | 5 | $$ |
| 8 PM | Peak | 10 | $$$ |
Result: You only pay for what you use!
Strategy 3: Clean Up Waste
Find idle resources:
# Pods using almost no CPU
kubectl top pods --all-namespaces | \
awk '$3 ~ /[0-9]+m/ && $3+0 < 10'
Common waste sources:
- 🗑️ Old test deployments
- 🗑️ Unused PersistentVolumes
- 🗑️ Forgotten debug pods
- 🗑️ Over-sized development environments
🛠️ Part 4: Cost Management Tools
Your Financial Assistants
These tools help you see where money goes and how to save it.
Tool 1: Kubernetes Metrics Server
Built-in and free!
# Install Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# Check pod resources
kubectl top pods
kubectl top nodes
Tool 2: Kubecost
The most popular Kubernetes cost tool.
What it shows:
- Cost per namespace
- Cost per deployment
- Cost per label/team
- Savings recommendations
# Install Kubecost
helm install kubecost cost-analyzer \
--repo https://kubecost.github.io/cost-analyzer/ \
--namespace kubecost \
--create-namespace
Example Dashboard View:
| Namespace | Monthly Cost | Efficiency |
|---|---|---|
| production | $2,500 | 78% |
| staging | $800 | 45% |
| dev | $400 | 32% |
Tool 3: Cloud Provider Tools
| Provider | Tool | Key Feature |
|---|---|---|
| AWS | Cost Explorer | EKS cost breakdown |
| GCP | Cost Management | GKE recommendations |
| Azure | Cost Analysis | AKS cost allocation |
Tool 4: Goldilocks (Right-sizing Helper)
Automatically recommends resource settings!
# Install Goldilocks
helm install goldilocks fairwinds-stable/goldilocks \
--namespace goldilocks \
--create-namespace
# Enable for a namespace
kubectl label ns my-namespace goldilocks.fairwinds.com/enabled=true
What you get: A dashboard showing recommended requests/limits based on actual usage.
graph TD A["Install Metrics Server"] --> B["Install Kubecost"] B --> C["Enable Goldilocks"] C --> D["Review Recommendations"] D --> E["Implement Changes"] E --> F["Monitor Savings"] F --> G{Savings Goal Met?} G -->|No| D G -->|Yes| H["🎉 Celebrate!"]
🎓 Summary: Your Optimization Checklist
✅ Resource Best Practices
- [ ] Always set requests AND limits
- [ ] Use ResourceQuotas for team budgets
- [ ] Use LimitRanges for safe defaults
✅ Right-sizing
- [ ] Monitor actual usage (kubectl top)
- [ ] Set requests at 1.2-1.5x average usage
- [ ] Set limits at 1.5-3x average usage
- [ ] Review and adjust regularly
✅ Cost Optimization
- [ ] Use Spot/Preemptible nodes where possible
- [ ] Enable Horizontal Pod Autoscaler
- [ ] Enable Cluster Autoscaler
- [ ] Clean up unused resources weekly
✅ Cost Management Tools
- [ ] Install Metrics Server (free, essential)
- [ ] Consider Kubecost for visibility
- [ ] Use Goldilocks for right-sizing help
- [ ] Review cloud provider cost reports monthly
🚀 You Did It!
You now understand how to:
- Set smart resource limits → No more guessing!
- Right-size containers → Perfect fit every time
- Optimize costs → Keep your cloud bill happy
- Use tools → Let helpers do the hard work
Remember: Resource optimization is not a one-time task. It’s like gardening—check regularly, prune waste, and watch your savings grow! 🌱
“The goal is not to spend less, but to spend smart. Every dollar saved on over-provisioning is a dollar you can invest in building better products.”
