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:


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:


Common Pitfalls


Key Takeaways

Next Steps: Set appropriate requests and limits for deployments, implement HPA for traffic-sensitive services, establish namespace quotas for multi-team clusters.