
Redefining Kubernetes Scaling with Smart EC2 Spot Allocation
This blog covers Karpenter's groundbreaking approach to Kubernetes scaling using smart EC2 Spot allocation. It delves into implementing price-capacity-optimized strategies, diversifying instance types, and setting up mixed Spot/On-Demand configurations. Learn how to overcome traditional autoscaling challenges, achieve rapid and efficient scaling, and significantly reduce costs while maintaining high availability in your Kubernetes clusters.
- Lack of Intelligent Decision-Making: Cluster auto-scaler, for instance, doesn't make nuanced scaling decisions. It simply provisions a new node of a predefined size when a pending pod's resource requirements exceed the available capacity on existing nodes.
- Resource Inefficiency: This approach often leads to sub-optimal resource allocation:
- Oversized Nodes: When nodes are too large, it results in underutilized infrastructure and unnecessary costs.
- Undersized Nodes: Conversely, if nodes are too small, it increases overhead and drives up expenses due to the need for more nodes.
- Inflexibility: The predetermined node sizes limit the ability to adapt to diverse and changing workload needs efficiently.
1
2
3
4
5
6
7
8
9
10
11
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: spot-provisioner
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot"]
providerRef:
name: default
1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: spot-price-capacity-optimized
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot"]
providerRef:
name: default
provider:
spotAllocationStrategy: price-capacity-optimized
- Balances cost savings with instance availability
- Reduces the likelihood of Spot interruptions
- Optimizes for both price and capacity stability
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: diverse-spot-provisioner
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot"]
- key: node.kubernetes.io/instance-type
operator: In
values: ["c5.large", "c5a.large", "m5.large", "m5a.large", "r5.large", "r5a.large"]
provider:
spotAllocationStrategy: price-capacity-optimized
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: mixed-provisioner
spec:
requirements:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot", "on-demand"]
provider:
spotAllocationStrategy: price-capacity-optimized
onDemandAllocationStrategy: lowest-price
weights:
- key: karpenter.sh/capacity-type
operator: In
values: ["spot"]
weight: 90
- key: karpenter.sh/capacity-type
operator: In
values: ["on-demand"]
weight: 10
- Prefers Spot instances (90% weight) but allows for On-Demand (10% weight)
- Uses price-capacity-optimized strategy for Spot
- Uses lowest-price strategy for On-Demand when needed
1
2
3
4
5
6
7
aws cloudwatch get-metric-statistics \
--namespace AWS/EC2Spot \
--metric-name SpotInstanceInterruption \
--statistics Sum \
--period 3600 \
--start-time 2023-01-01T00:00:00 \
--end-time 2023-01-31T23:59:59
Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.