Goal
Query and understand available pre-paid AWS capacity (Compute SPs, EC2 Instance SPs, and RIs) from Lumina metrics to inform NodeOverlay creation decisions.
Background
Architecture Decision: Karve will create NodeOverlays for ALL instance families/types with available capacity, regardless of current NodePool configuration (Option 2 approach). This is simpler and more resilient than watching NodePools.
NodeOverlays are non-invasive - if no NodePool uses a particular instance family, the overlay is simply ignored by Karpenter.
Deliverables
1. Capacity Type Discovery
2. Utilization Tracking
3. Overlay Decision Logic
4. Logging & Observability
Implementation Details
Prometheus Queries
Compute Savings Plans (global):
savings_plan_utilization_percent{type="compute"}
sum(savings_plan_remaining_capacity{type="compute"})
EC2 Instance Savings Plans (per-family):
savings_plan_utilization_percent{type="ec2_instance"}
savings_plan_remaining_capacity{type="ec2_instance"}
# Labels include: instance_family, region
Reserved Instances (per-instance-type):
ec2_reserved_instance
# Labels include: instance_type, availability_zone, region
Overlay Decision Algorithm
// For each capacity source:
utilization := QueryUtilization(capacityType)
remaining := QueryRemaining(capacityType)
threshold := config.UtilizationThreshold // default: 95
shouldExist := (utilization < threshold) && (remaining > 0)
decisions = append(decisions, OverlayDecision{
Name: GenerateOverlayName(capacityType),
Weight: GetWeight(capacityType), // RI=30, EC2-SP=20, Compute-SP=10
Price: "0.00", // 100% discount
ShouldExist: shouldExist,
})
Configuration Support
Add to config.yaml:
overlayManagement:
utilizationThreshold: 95 # Delete overlays at this utilization %
weights:
reservedInstance: 30
ec2InstanceSavingsPlan: 20
computeSavingsPlan: 10
Example Log Output
{
"timestamp": "2025-10-27T12:05:00Z",
"message": "Capacity analysis complete",
"compute_sp": {
"utilization_percent": 87.5,
"remaining_capacity_dollars_per_hour": 12.50,
"overlay_decision": "create",
"overlay_name": "cost-aware-compute-sp-global"
},
"ec2_instance_sp_m5": {
"utilization_percent": 96.2,
"remaining_capacity_dollars_per_hour": -0.80,
"overlay_decision": "delete",
"overlay_name": "cost-aware-ec2-sp-m5"
},
"reserved_instances": {
"c5.xlarge": {
"count": 5,
"overlay_decision": "create",
"overlay_name": "cost-aware-ri-c5-xlarge"
}
}
}
Success Criteria
Testing Requirements
Unit Tests
- Overlay decision logic with various utilization percentages
- Threshold configuration (90%, 95%, 100%)
- Handling missing metrics (SP without utilization data)
- Weight assignment for different capacity types
Integration Tests
- Query mock Prometheus with sample Lumina metrics
- Parse responses into overlay decisions
- Verify correct overlay names/specs generated
- Test with multiple SPs, RIs simultaneously
Non-Goals (Deferred)
- ❌ Watching Karpenter NodePool CRs (not needed for Option 2)
- ❌ Parsing NodePool requirements (not needed for Option 2)
- ❌ Actually creating NodeOverlay CRs (that's Phase 4-5)
- ❌ Tracking per-instance cost allocation (Lumina handles this)
References
Goal
Query and understand available pre-paid AWS capacity (Compute SPs, EC2 Instance SPs, and RIs) from Lumina metrics to inform NodeOverlay creation decisions.
Background
Architecture Decision: Karve will create NodeOverlays for ALL instance families/types with available capacity, regardless of current NodePool configuration (Option 2 approach). This is simpler and more resilient than watching NodePools.
NodeOverlays are non-invasive - if no NodePool uses a particular instance family, the overlay is simply ignored by Karpenter.
Deliverables
1. Capacity Type Discovery
2. Utilization Tracking
savings_plan_utilization_percentfor each SPsavings_plan_remaining_capacityfor validationec2_reserved_instancefor RI availability3. Overlay Decision Logic
4. Logging & Observability
Implementation Details
Prometheus Queries
Compute Savings Plans (global):
EC2 Instance Savings Plans (per-family):
Reserved Instances (per-instance-type):
Overlay Decision Algorithm
Configuration Support
Add to
config.yaml:Example Log Output
{ "timestamp": "2025-10-27T12:05:00Z", "message": "Capacity analysis complete", "compute_sp": { "utilization_percent": 87.5, "remaining_capacity_dollars_per_hour": 12.50, "overlay_decision": "create", "overlay_name": "cost-aware-compute-sp-global" }, "ec2_instance_sp_m5": { "utilization_percent": 96.2, "remaining_capacity_dollars_per_hour": -0.80, "overlay_decision": "delete", "overlay_name": "cost-aware-ec2-sp-m5" }, "reserved_instances": { "c5.xlarge": { "count": 5, "overlay_decision": "create", "overlay_name": "cost-aware-ri-c5-xlarge" } } }Success Criteria
Testing Requirements
Unit Tests
Integration Tests
Non-Goals (Deferred)
References