Kubernetes Cost Optimization

A comprehensive guide to Kubernetes cost optimization covering resource optimization, spot instances, committed use discounts, rightsizing, and practical implementation strategies for reducing cloud costs.

Resource Optimization Spot Instances Committed Use Discounts Rightsizing
Why Cost Optimization Matters

Kubernetes cost optimization is essential for managing cloud expenses while maintaining performance and reliability. Without optimization, costs can spiral due to:

  • Over-provisioning: Allocating more resources than needed
  • Idle Resources: Running unused or underutilized resources
  • Inefficient Workloads: Poor resource requests and limits
  • Lack of Visibility: No insight into cost drivers
  • Poor Scaling: Not scaling down when demand drops
Cost Optimization Principles:
  • Right-size: Match resources to actual needs
  • Scale Dynamically: Scale up and down with demand
  • Use Spot Instances: Leverage discounted capacity
  • Commit to Use: Use reserved instances for steady workloads
  • Monitor Continuously: Track and optimize regularly
Cost Optimization Strategies

Resource Rightsizing

Optimize resource requests and limits
Adjust CPU and memory requests/limits based on actual usage. Use VPA recommendations and monitoring data to find the optimal values.
Typical Savings: 20-40%
All workloads

Spot Instances

Use discounted spare capacity
Run fault-tolerant workloads on spot instances for up to 70-90% savings. Handle interruptions gracefully with node termination handlers.
Typical Savings: 60-90%
Stateless, fault-tolerant workloads

Committed Use Discounts

Reserve capacity for savings
Commit to using specific resources for 1-3 years for significant discounts (20-70%). Best for steady, predictable workloads.
Typical Savings: 20-70%
Steady-state workloads

Cluster Autoscaling

Dynamic node scaling
Automatically scale nodes up and down based on demand. Reduces cost during low-traffic periods by minimizing node count.
Typical Savings: 10-30%
Variable workloads

Storage Optimization

Optimize storage usage
Use appropriate storage classes, implement lifecycle policies, clean up unused volumes, and use compression for logs.
Typical Savings: 10-30%
Storage-heavy workloads

Efficient Networking

Optimize data transfer
Minimize cross-zone traffic, use caching, and implement content delivery networks for reduced bandwidth costs.
Typical Savings: 5-20%
Network-intensive workloads
Resource Rightsizing

Rightsizing involves adjusting resource requests and limits based on actual usage. It's one of the most effective cost optimization strategies.

# Check current resource usage kubectl top pods --all-namespaces kubectl top nodes # Identify over-provisioned pods kubectl get pods -o json | jq '.items[] | { name: .metadata.name, namespace: .metadata.namespace, requests: .spec.containers[].resources.requests, limits: .spec.containers[].resources.limits }' # Use VPA for recommendations apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata: name: app-vpa spec: targetRef: apiVersion: apps/v1 kind: Deployment name: my-app updatePolicy: updateMode: "Off" # Only recommend, don't apply resourcePolicy: containerPolicies: - containerName: '*' minAllowed: cpu: 50m memory: 64Mi maxAllowed: cpu: 2000m memory: 2Gi # Get VPA recommendations kubectl get vpa app-vpa -o yaml | grep -A 20 recommendation # Manual rightsizing based on usage # Original requests requests: cpu: 500m memory: 512Mi # After analysis (based on actual usage) # Actual usage: CPU 150m, Memory 200Mi requests: cpu: 200m # Reduced from 500m memory: 256Mi # Reduced from 512Mi # Goldilocks tool for VPA recommendations helm repo add fairwinds-stable https://charts.fairwinds.com/stable helm repo update helm install goldilocks fairwinds-stable/goldilocks --namespace goldilocks --create-namespace # Goldilocks dashboard kubectl port-forward -n goldilocks svc/goldilocks-dashboard 8080:80
Rightsizing Best Practices:
  • Use VPA recommendations as a starting point
  • Monitor actual usage over time (weeks)
  • Set requests based on steady-state usage
  • Set limits based on peak usage
  • Gradually adjust values to avoid instability
  • Review and adjust regularly (monthly)
Spot Instances for Cost Savings

Spot instances offer significant cost savings (60-90%) but can be interrupted. They're ideal for stateless, fault-tolerant workloads.

# AWS Spot Node Group (eksctl) apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-cluster region: us-east-1 nodeGroups: - name: spot-workers instanceType: t3.medium desiredCapacity: 3 spot: true # Enable spot instances spotPrice: "0.02" labels: node-type: spot taints: - key: spot value: "true" effect: NoSchedule # Pod toleration for spot nodes apiVersion: v1 kind: Pod metadata: name: spot-workload spec: tolerations: - key: spot operator: Equal value: "true" effect: NoSchedule nodeSelector: node-type: spot containers: - name: app image: myapp:latest # AWS Node Termination Handler helm repo add aws https://aws.github.io/eks-charts helm repo update helm install aws-node-termination-handler aws/aws-node-termination-handler \ --namespace kube-system \ --set enableSpotInterruptionDraining=true \ --set enableScheduledEventDraining=true # GCP Preemptible VM # Node pool with preemptible instances gcloud container node-pools create spot-pool \ --cluster=my-cluster \ --zone=us-central1-a \ --preemptible \ --num-nodes=3 \ --machine-type=n1-standard-2 # Azure Spot VM az aks nodepool add \ --resource-group my-rg \ --cluster-name my-cluster \ --name spotpool \ --node-count 3 \ --enable-spot \ --spot-eviction-policy Delete
Spot Instance Considerations:
  • Use only for stateless, fault-tolerant workloads
  • Implement node termination handling
  • Set appropriate pod disruption budgets
  • Monitor spot interruption rates
  • Have fallback capacity (on-demand) for critical workloads
  • Test spot handling in staging
Committed Use Discounts

Committed use discounts (reserved instances) provide significant savings (20-70%) for predictable workloads by committing to use specific resources for 1-3 years.

# AWS Reserved Instances # Purchase standard or convertible RIs # Standard RIs: Up to 72% savings, fixed instance type # Convertible RIs: Up to 54% savings, flexible instance type # AWS Compute Savings Plan # Up to 66% savings, flexible across instance types and regions # AWS EC2 Savings Plan # Up to 72% savings, specific to EC2 # GCP Committed Use Discounts # Up to 70% savings, 1-3 year commitment gcloud compute commitments create \ --region=us-central1 \ --resources=vcpu=4,memory=16GB \ --commitment-type=1-year # Azure Reserved VM Instances # Up to 72% savings, 1-3 year commitment az reservation purchase \ --reserved-resource-type VirtualMachines \ --instance-flexibility Enabled \ --quantity 3 \ --term P1Y # Kubernetes cluster with reservations # Ensure reserved capacity matches your steady-state usage # Monitor and adjust reservations based on usage
Committed Use Strategy:
  • Analyze historical usage to identify steady workloads
  • Purchase reservations for baseline capacity (e.g., 50-70% of usage)
  • Use spot/on-demand for variable capacity
  • Monitor utilization of reservations (aim for 80%+ utilization)
  • Use savings plans for flexibility
  • Review and adjust reservations regularly
Cost Monitoring and Visibility
# Install Kubecost for cost visibility helm repo add kubecost https://kubecost.github.io/cost-analyzer helm repo update helm install kubecost kubecost/cost-analyzer \ --namespace kubecost \ --create-namespace \ --set prometheus.enabled=true \ --set grafana.enabled=true # Access Kubecost UI kubectl port-forward -n kubecost svc/kubecost-cost-analyzer 9090:9090 # Check cost by namespace kubectl get pods -n kubecost # Access: http://localhost:9090 # Kubecost API for cost data # Total monthly cost curl http://localhost:9090/api/v1/allocation/aggregated?aggregate=namespace # Cost by pod curl http://localhost:9090/api/v1/allocation/aggregated?aggregate=pod # Cloud provider cost monitoring # AWS Cost Explorer aws ce get-cost-and-usage --time-period Start=2025-01-01,End=2025-01-31 # GCP Cost Management gcloud beta billing accounts describe # Azure Cost Management az consumption usage list --start-date 2025-01-01 --end-date 2025-01-31 # OpenCost (open-source alternative) helm repo add opencost https://opencost.github.io/opencost-helm-chart helm repo update helm install opencost opencost/opencost --namespace opencost --create-namespace
Cost Monitoring Best Practices:
  • Implement cost visibility tools (Kubecost, OpenCost)
  • Monitor cost trends and anomalies
  • Set cost budgets and alerts
  • Track cost by namespace, team, and application
  • Regularly review cost reports
  • Share cost visibility with teams
Implementation Roadmap
1. Gain Visibility
Implement Kubecost or OpenCost. Understand where costs are coming from. Identify top cost drivers and trends.
2. Rightsize Resources
Use VPA recommendations and monitoring data. Adjust requests and limits. Aim for 60-80% utilization.
3. Implement Autoscaling
Configure HPA for pods and Cluster Autoscaler for nodes. Scale based on demand to avoid over-provisioning.
4. Adopt Spot Instances
Identify stateless workloads. Implement spot node groups with termination handling. Start with non-critical workloads.
5. Purchase Reservations
Analyze historical usage. Purchase reserved instances for steady workloads. Use savings plans for flexibility.
6. Optimize Storage
Review storage usage. Use appropriate storage classes. Implement lifecycle policies. Clean up unused volumes.
7. Monitor and Repeat
Continuous monitoring and optimization. Review costs monthly. Adjust strategies based on changing usage.
Cost Optimization Comparison
Strategy Savings Risk Effort Best For
Rightsizing 20-40% Low Medium All workloads
Spot Instances 60-90% High High Stateless, fault-tolerant
Committed Use 20-70% Low Low Steady workloads
Cluster Autoscaling 10-30% Low Medium Variable workloads
Storage Optimization 10-30% Low Medium Storage-heavy workloads
Network Optimization 5-20% Low Medium Network-intensive
Frequently Asked Questions
What is the most effective cost optimization strategy?
Rightsizing is the most effective starting point. It requires no infrastructure changes and provides significant savings. Combine with spot instances and committed use discounts for maximum savings.
What are the risks of using spot instances?
Spot instances can be interrupted with a 2-minute notice. Use them only for stateless, fault-tolerant workloads. Implement node termination handling and ensure pods can be rescheduled.
How do I know if I'm over-provisioned?
Check CPU and memory utilization. If usage is consistently below 60% of requests, you're over-provisioned. Use tools like Kubecost, Goldilocks, or VPA to identify over-provisioned pods.
What is the difference between spot and reserved instances?
Spot instances are spare capacity with high discounts but can be interrupted. Reserved instances are commitments with fixed discounts (20-70%). Use spot for flexible workloads, reserved for steady workloads.
How often should I review cost optimization?
Review monthly for trends and quarterly for major optimizations. Monitor cost dashboards continuously. Adjust rightsizing and reservations based on changing usage patterns.
What tools can help with Kubernetes cost optimization?
Kubecost (comprehensive), OpenCost (open-source), Goldilocks (VPA recommendations), CloudHealth, and cloud provider native tools (AWS Cost Explorer, GCP Cost Management).
How do I handle storage costs?
Use appropriate storage classes, implement lifecycle policies for automatic cleanup, use compression for logs, and monitor PVC usage. Consider using cheaper storage for backups and archival.
What is the recommended reserved instance coverage?
Aim for 50-70% of your steady-state workload covered by reservations. This provides significant savings while maintaining flexibility for variable workloads.
Previous: Node Maintenance Next: Troubleshooting Pods

Cost optimization is an ongoing process. Start with visibility, implement rightsizing, then gradually adopt spot instances and committed use discounts. Monitor continuously and adjust strategies based on changing usage patterns.