Skip to main content
โšก Calmops

Container Cost Analysis: Docker, Kubernetes Economics

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:

  1. Consolidated clusters: 1 shared EKS cluster
  2. Right-sized nodes: 15 t3.xlarge (better efficiency than 60 t3.medium)
  3. Removed 40% unused services
  4. Implemented autoscaling
  5. Optimized logging to ELK stack
  6. 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

Resources


Comments