Kubernetes Resource Management
Why Resource Management Matters
Resource requests and limits enable Kubernetes to make intelligent scheduling decisions and prevent resource starvation. Without proper resource management, high-demand pods can consume cluster resources, starving others.
Impact of poor resource management:
- One pod consuming all CPU crashes other pods
- Memory leaks cause cluster instability
- Unschedulable pods due to insufficient resources
- Unpredictable application performance
Requests vs Limits
graph TD
A["Container Resources"] -->B["Requests
Minimum Guaranteed"]
A -->C["Limits
Maximum Allowed"]
B -->B1["Scheduler reserves these"]
B -->B2["Pod guaranteed this much"]
C -->C1["Hard cap enforced"]
C -->C2["Excess usage killed"]
style B fill:#90EE90
style C fill:#FFB6C6
Requests
Minimum resources guaranteed to container. Kubernetes scheduler uses requests to place pods on nodes with sufficient available resources.
Why requests matter: Scheduler needs to know minimum resource requirements to avoid overcommitting nodes.
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: myapp:latest
resources:
requests:
memory: "256Mi" # Minimum 256 MB memory
cpu: "250m" # Minimum 250 millicores (0.25 CPU)
Limits
Maximum resources container can consume. Kubernetes enforces limits—exceeding them terminates the container.
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi" # Hard cap: 512 MB
cpu: "500m" # Hard cap: 500 millicores
Why limits matter: Prevent one container from consuming all cluster resources, protecting other workloads.
Resource Units
CPU
Measured in cores. Fractional values use millicores (m).
1 = 1 CPU core
250m = 0.25 CPU cores = 1/4 core
500m = 0.5 CPU cores = 1/2 core
1000m = 1 CPU core
Memory
Measured in bytes with standard units:
1 Mi = 1 Mebibyte = ~1 million bytes
1 Gi = 1 Gibibyte = ~1 billion bytes
512Mi, 1Gi, 2Gi, 4Gi, etc.
Note: Use Mi (mebibytes, binary) not M (megabytes, decimal) in Kubernetes.
Quality of Service (QoS) Classes
Kubernetes assigns QoS classes based on requests/limits, determining pod eviction order during resource shortage.
Guaranteed
Both requests and limits set to same values.
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "500m"
Priority: Highest. Never evicted unless exceeding limits. Use case: Critical applications requiring stability.
Burstable
Requests set lower than limits (or only requests set).
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
Priority: Medium. Evicted if node under pressure. Use case: Most applications—guaranteed minimum with ability to burst.
BestEffort
No requests or limits set.
# No resources section
Priority: Lowest. First to evict during shortage. Use case: Non-critical batch jobs, development.
Namespace Resource Quotas
Limit total resources per namespace, preventing one team from consuming entire cluster.
apiVersion: v1
kind: Namespace
metadata:
name: team-a
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "10" # Max 10 cores requested
requests.memory: "20Gi" # Max 20 GB requested
limits.cpu: "20" # Max 20 cores limited
limits.memory: "40Gi" # Max 40 GB limited
pods: "100" # Max 100 pods
Why quotas matter: Prevent resource starvation in shared clusters. Teams get guaranteed capacity.
Pod Disruption Budgets
Define minimum availability during voluntary disruptions (node drains, cluster upgrades).
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
spec:
minAvailable: 2 # Always keep minimum 2 api pods
selector:
matchLabels:
app: api
Prevents simultaneous eviction of required pods, maintaining availability during maintenance.
Vertical Pod Autoscaler (VPA)
Automatically adjusts container requests/limits based on observed usage.
Why VPA: Manual resource tuning is difficult. VPA learns from real usage patterns.
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: api-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: api
updatePolicy:
updateMode: "Auto" # Automatically update
VPA monitors pod usage and recommends (or applies) resource adjustments.
Horizontal Pod Autoscaler (HPA)
Automatically scales pod replicas based on metrics (CPU, memory, custom metrics).
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # Scale up if CPU >70%
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80 # Scale up if memory >80%
Why HPA: Automatically handle traffic spikes without manual intervention.
Real-World Example: Production Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: myregistry.azurecr.io/api:v1.0
ports:
- containerPort: 5000
resources:
requests:
memory: "512Mi" # Guaranteed minimum
cpu: "250m"
limits:
memory: "1Gi" # Hard cap
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 5000
initialDelaySeconds: 10
periodSeconds: 10
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: api
Result:
- Each pod guaranteed 512 MB and 0.25 CPU
- No pod exceeds 1 GB memory or 0.5 CPU
- HPA automatically scales between 3-20 replicas based on CPU
- Minimum 2 pods always available during cluster maintenance
Common Pitfalls
- No requests set - Scheduler can't place pods; nodes become overcommitted
- Limits too low - Legitimate traffic spikes kill pods
- Limits too high - Defeats the purpose; wasted resources
- Forgetting memory requests - Memory leaks cause cluster instability
- No HPA - Manual scaling leaves gaps during traffic spikes
Key Takeaways
- Requests guarantee minimum resources; limits enforce maximum (hard cap)
- QoS classes determine eviction priority: Guaranteed, Burstable, BestEffort
- Namespace quotas prevent resource starvation in multi-tenant clusters
- HPA automatically scales replicas based on CPU, memory, or custom metrics
- VPA automatically adjusts container requests/limits based on observed usage
- PodDisruptionBudgets maintain minimum availability during cluster maintenance
- Proper resource management is essential for reliable, scalable production deployments
Next Steps: Set appropriate requests and limits for deployments, implement HPA for traffic-sensitive services, establish namespace quotas for multi-team clusters.