Introduction
Containerization (Docker) and orchestration (Kubernetes) are foundational to modern cloud architectures. However, many organizations don’t understand the true costs of running containers at scale.
This guide breaks down container and Kubernetes economics, reveals hidden costs, and provides strategies to optimize container spending by 40-60% without sacrificing performance or reliability.
Container Economics Fundamentals
Cost Breakdown
Container costs come from multiple sources:
Total Container Cost = Compute + Storage + Networking + Tools + Management
1. Compute (60-70% of cost)
- EC2 instances running Docker
- Memory allocated to containers
- CPU allocated to containers
2. Storage (15-20% of cost)
- Container images (registry storage)
- Persistent volumes
- Snapshots
3. Networking (10-15% of cost)
- NAT gateway traffic
- Load balancer requests
- Data transfer between zones
4. Tools & Management (5-10% of cost)
- Container registry (ECR, Docker Hub)
- Monitoring and logging
- GitOps tools
The Container Cost Trap
Real-World Scenario
A company migrates monolith to microservices (15 containers):
Before:
- 4x EC2 m5.large instances
- Cost: $2,880/month
After (Kubernetes):
- 20x EC2 t3.medium instances (container overhead)
- Monitoring, logging, networking tools
- Cost: $8,400/month
Problem: 3x cost increase despite microservices benefits!
Docker and Container Image Costs
Container Image Storage Costs
Image sizes (uncompressed):
- Node.js base: 900 MB
- Python + dependencies: 1.2 GB
- Java application: 800 MB
- Multi-stage optimized: 200 MB
Registry Storage Costs
Scenario: Company with 50 microservices
Average image size: 800 MB (uncompressed)
Compressed size: 200 MB
Per service (5 versions in registry):
= 200 MB ร 5 = 1 GB/service
Total: 50 ร 1 GB = 50 GB
ECR Storage (AWS):
= 50 GB ร $0.10/month = $5/month
Docker Hub Private:
= 5 repositories ร $5/month = $25/month
Not a huge cost, but adds up with:
- Build artifacts storage
- Snapshots
- Multiple registries
Cost Reduction Strategy: Multi-Stage Builds
Bad: Single-stage image
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y python3 python3-pip
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py .
CMD ["python3", "app.py"]
# Size: 1.2 GB (includes all build tools)
Good: Multi-stage build
FROM python:3.9 as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
FROM python:3.9-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY app.py .
ENV PATH=/root/.local/bin:$PATH
CMD ["python3", "app.py"]
# Size: 200 MB (only runtime dependencies)
# 84% smaller = better registry performance
Kubernetes Cost Analysis
Kubernetes Cluster Architecture Cost
Minimal cluster (3 master nodes + workers):
AWS EKS pricing:
- Control plane: $0.10/hour = $73/month
Worker nodes (t3.medium):
- 3 master nodes: 3 ร $0.0965/hr ร 730 = $211/month
- 5 worker nodes: 5 ร $0.0965/hr ร 730 = $352/month
- Total node cost: $563/month
EBS storage:
- Default 20 GB per node: 8 nodes ร 20 GB = 160 GB
- Cost: 160 GB ร $0.10/month = $16/month
Total: $652/month for minimal Kubernetes cluster
Cost Per Container
652 / 50 containers = $13.04/container/month
Plus per-container costs:
- CPU requests: $0.05/vCPU/month (variable)
- Memory requests: $0.005/GB/month (variable)
Small container (0.1 vCPU, 256 MB):
= $13.04 + $5 (CPU) + $1.28 (memory)
= ~$19.32/container/month
Hidden Kubernetes Costs
Cost #1: Over-Provisioning
Problem: Requesting too much compute
Container configuration:
resources:
requests:
cpu: 1000m # 1 full CPU
memory: 512Mi # 512 MB
limits:
cpu: 2000m
memory: 1024Mi
Actual usage (observed):
average CPU: 50m (5% of request)
average memory: 128Mi (25% of request)
Waste factor: 20x (5% ร 25%)
Cost impact:
- 100 containers ร 20x waste = equivalent to 2,000 containers
- Actual cost: $10,000/month
- Optimized cost: $500/month
Solution: Right-Sizing
Steps to right-size:
1. Deploy with generous requests
2. Monitor actual usage (Prometheus)
3. Set requests = 110% of p99 usage
4. Set limits = 150% of p99 usage
5. Re-evaluate monthly
Cost #2: Node Waste
Problem: Nodes running below capacity
Kubernetes cluster:
- 10 worker nodes (t3.large)
- CPU capacity: 10 ร 2 vCPU = 20 vCPU total
- Actual usage: 8 vCPU (40% utilization)
- Wasted capacity: 12 vCPU (60%)
- Wasted cost: $2,000/month
With proper bin-packing:
- Could run same workload on 4 nodes
- Savings: $1,200/month
Solution: Bin-Packing & Pod Disruption Budgets
# Enable kube-scheduler pod spreading
podAffinity:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp
topologyKey: kubernetes.io/hostname
# Result: Better node utilization
# Fewer nodes needed
Cost #3: Excess Replicas
Problem: Over-replicating for high availability
Deployment configuration:
replicas: 10
Actual traffic:
average requests: 100 req/s
peak requests: 300 req/s
With 10 replicas:
capacity: 1,000 req/s (10x actual peak)
Optimized:
base replicas: 3
autoscale to max 5
cost: 40% lower
latency: same
availability: same (99.95%)
Solution: Autoscaling
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
Kubernetes Networking Costs
NAT Gateway Costs
Scenario: EKS cluster with pods accessing external APIs
NAT Gateway pricing (AWS):
- Fixed hourly cost: $0.045/hour = $33/month
- Data processing: $0.045/GB
If 100 GB of outbound traffic/month:
= $33 + (100 ร $0.045)
= $33 + $4.50
= $37.50/month
At scale (1 TB/month):
= $33 + (1,000 ร $0.045)
= $33 + $45
= $78/month
For 10 clusters:
= $780/month in NAT gateway costs alone
Cost Reduction: VPC Endpoints
Instead of NAT Gateway:
AWS PrivateLink endpoints:
- S3 endpoint: $7.20/month (free data)
- DynamoDB endpoint: $7.20/month (free data)
- API Gateway endpoint: $7.20/month
Savings: From $45/GB to $0/GB
Reduced from $78/month to $21.60/month for S3+DynamoDB
Additional benefit: Better security
Load Balancer Costs
AWS NLB (Network Load Balancer):
Fixed cost: $0.006/hour = $44/month
Data processing: $0.006/GB
With 1 TB/month traffic:
= $44 + (1,000 ร $0.006)
= $44 + $6
= $50/month
Multiple services, multiple NLBs:
= 10 NLBs ร $50 = $500/month
Solution:
- Use Ingress controller (reverse proxy)
- Single NLB + software-based routing
- Cost: $50/month instead of $500/month
- Savings: $450/month
Kubernetes Monitoring and Logging Costs
Container Logging
Scenario: 100 pod cluster, 10 log lines/second per pod
Log volume:
= 100 pods ร 10 lines/sec ร 86,400 sec/day
= 86.4 million log lines/day
= ~500 GB/day
CloudWatch Logs cost:
= 500 GB ร $0.50/GB
= $250/day = $7,500/month (!)
Solution:
- ELK stack (self-hosted): $1,000/month
- Datadog: $2,000/month
- New Relic: $1,500/month
- Savings: 73-87%
Metrics and Monitoring
Prometheus + Grafana (self-hosted):
- Cost: 1 t3.medium instance = $30/month
- Storage (30 days): 2 GB EBS = $0.20/month
- Total: $30.20/month
Datadog agent monitoring:
- Cost: $15/host/month ร 10 hosts = $150/month
- Minimum bill: $500/month
- Storage included
Savings with self-hosted: 94%
Container Orchestration Cost Comparison
Option 1: Self-Managed Kubernetes
Monthly costs:
- EC2 instances (10 nodes): $700
- EBS volumes: $50
- Data transfer: $50
- Monitoring/logging: $200
Total: $1,000/month
Overhead:
- Cluster maintenance: 40 hours/month
- Cluster upgrades: 20 hours/month
- Security patches: 10 hours/month
Total: 70 hours/month = $3,500 labor (at $50/hr)
True cost: $4,500/month
Option 2: AWS EKS (Managed)
Monthly costs:
- Control plane: $73
- EC2 instances (10 nodes): $700
- EBS volumes: $50
- Data transfer: $50
- Monitoring/logging: $200
Total: $1,073/month
Overhead:
- Configuration: 10 hours/month
- Debugging: 10 hours/month
Total: 20 hours/month = $1,000 labor
True cost: $2,073/month
Savings vs self-managed: $2,427/month (54%)
Option 3: Serverless (AWS Fargate)
Pricing:
- $0.04048/vCPU/hour
- $0.00445/GB/month
Task configuration:
- 0.5 vCPU
- 1 GB RAM
- 50 tasks running
Monthly cost:
= (0.5 ร $0.04048 ร 730) + (1 ร $0.00445 ร 50)
= $14.78 + $0.22
= $14.99/task/month
50 tasks: $750/month
Comparison:
- Self-managed K8s: $1,000/month
- EKS: $1,073/month
- Fargate: $750/month
Fargate best for variable workloads, EKS for steady-state
Real-World Optimization Case Study
Before: Over-Engineered Kubernetes
Architecture:
- 3 EKS clusters (dev, staging, prod)
- 20 nodes per cluster (60 total)
- 200 microservices deployed
Costs:
- EC2: 60 nodes ร $400/month = $24,000
- EKS control planes: 3 ร $73 = $219
- Load balancers: 20 ร $50 = $1,000
- Monitoring: $3,000
- Data transfer: $2,000
- Total: $30,219/month
After: Optimized Architecture
Changes:
- Consolidated clusters: 1 shared EKS cluster
- Right-sized nodes: 15 t3.xlarge (better efficiency than 60 t3.medium)
- Removed 40% unused services
- Implemented autoscaling
- Optimized logging to ELK stack
- Used spot instances for non-critical workloads
New Costs:
- EC2: 15 nodes ร $250/month = $3,750
- Spot instances: 5 nodes ร $100 = $500
- EKS control plane: $73
- Load balancers: 2 ร $50 = $100
- Monitoring (ELK): $300
- Data transfer: $500
- Total: $5,223/month
Savings: $25,000/month (83% reduction!)
Container Cost Optimization Checklist
- Use multi-stage Docker builds
- Implement resource requests/limits
- Monitor actual resource usage
- Enable horizontal pod autoscaling
- Right-size worker nodes
- Use spot instances for non-critical workloads
- Remove over-replicated services
- Optimize logging (ELK vs CloudWatch)
- Use VPC endpoints for AWS services
- Consolidate ingress controllers
- Clean up unused container images
- Implement cost monitoring alerts
Glossary
- Container: Lightweight, isolated application environment
- Pod: Smallest Kubernetes unit, contains one or more containers
- Node: Physical/virtual machine running Kubernetes
- Cluster: Collection of nodes managed by Kubernetes
- Registry: Repository storing container images
- Namespace: Virtual cluster within Kubernetes
- Resource Requests: Minimum compute guaranteed to pod
- Resource Limits: Maximum compute allowed to pod
- HPA: Horizontal Pod Autoscaler, scales replicas
Comments